下面是使用C++在ROS1环境下实现以上功能的代码和注释:
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>
#include <turtlesim/Pose.h>
#include <cmath>
// 全局变量
bool first_turtle_reached = false; // 判断小海龟1是否到达终点
// 小海龟1回调函数,当小海龟1运动结束时设置标志位为true
void turtle1Callback(const turtlesim::PoseConstPtr& pose)
{
if (!first_turtle_reached && std::fabs(pose->x - 5.54) <= 0.01 && std::fabs(pose->y - 5.54) <= 0.01)
{
first_turtle_reached = true;
ROS_INFO("Turtle 1 reached the destination.");
}
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "turtle_controller");
ros::NodeHandle nh;
// 创建两只小海龟
ros::ServiceClient spawn_client = nh.serviceClient<turtlesim::Spawn>("/spawn");
turtlesim::Spawn spawn_srv;
spawn_srv.request.x = 2.0;
spawn_srv.request.y = 2.0;
spawn_srv.request.theta = M_PI/4; // 设置初始角度为45度
spawn_srv.request.name = "turtle2";
// 调用服务生成小海龟2
if (spawn_client.call(spawn_srv))
{
ROS_INFO("Turtle 2 spawned successfully.");
}
else
{
ROS_ERROR("Failed to spawn turtle 2.");
return 1;
}
// 创建发布器和订阅器
ros::Publisher turtle1_pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
ros::Publisher turtle2_pub = nh.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);
ros::Subscriber turtle1_sub = nh.subscribe("/turtle1/pose", 10, turtle1Callback);
// 设置速度消息
geometry_msgs::Twist vel_msg;
// 小海龟1画椭圆
while (ros::ok())
{
if (!first_turtle_reached)
{
vel_msg.linear.x = 0.2; // 线速度为0.2m/s,使小海龟前进
vel_msg.angular.z = 0.4; // 角速度为0.4rad/s,使小海龟转弯
turtle1_pub.publish(vel_msg);
}
else
{
vel_msg.linear.x = 0.0; // 当小海龟1到达终点后停止运动
vel_msg.angular.z = 0.0;
turtle1_pub.publish(vel_msg);
break;
}
ros::spinOnce();
ros::Duration(0.01).sleep();
}
// 等待2秒后启动小海龟2的运动
ros::Duration(2.0).sleep();
// 小海龟2跟随小海龟1并进行旋转操作
while (ros::ok())
{
// 获取小海龟当前位置信息
turtlesim::PoseConstPtr turtle1_pose = ros::topic::waitForMessage<turtlesim::Pose>("/turtle1/pose", nh);
turtlesim::PoseConstPtr turtle2_pose = ros::topic::waitForMessage<turtlesim::Pose>("/turtle2/pose", nh);
// 计算小海龟1和小海龟2之间的距离
float distance = std::sqrt(std::pow(turtle1_pose->x - turtle2_pose->x, 2) + std::pow(turtle1_pose->y - turtle2_pose->y, 2));
if (distance < 0.1)
{
vel_msg.linear.x = 0.0; // 距离小于0.1m时停止线性运动
vel_msg.angular.z = 1.0; // 开始旋转操作,角速度为1rad/s
turtle2_pub.publish(vel_msg);
}
else
{
// 小海龟2跟随小海龟1进行线性运动
vel_msg.linear.x = 0.3;
vel_msg.angular.z = 0.0;
turtle2_pub.publish(vel_msg);
}
ros::spinOnce();
ros::Duration(0.01).sleep();
}
return 0;
}
这段代码中,使用了ROS的消息传输机制和服务调用机制来实现对两只小海龟的控制。首先通过服务调用生成第二只小海龟,然后分别创建发布器和订阅器来发布速度指令和订阅小海龟1的位置信息。在主循环中,控制小海龟1画椭圆直到达到目标点后停止运动。然后经过2秒延时后,小海龟2开始跟随小海龟1运动,并根据与小海龟1之间的距离进行旋转操作或线性运动。
请注意,在使用该代码之前,确保已经正确安装了ROS和相应的依赖包,并且在启动ROS环境之后运行该程序。
内容由零声教学AI助手提供,问题来源于学员提问




