紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
ros代码每次运行效果不一致,不报错,但是没有按照要求去执行
-
#include "ros/ros.h" #include<geometry_msgs/Twist.h> int main(int argc, char *argv[]) { ros::init(argc, argv, "vel_ctrl"); ros::NodeHandle n; ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10); ROS_INFO("draw_circle start..."); static double rotationDuration = 1.75; static ros::Time startTime; static double during=3.5; startTime=ros::Time::now(); ros::Rate loop_rate(10); // Control the loop frequency to 10Hz while((ros::Time::now()-startTime).toSec()<=during) { geometry_msgs::Twist vel1_cmd; vel1_cmd.linear.x=0; vel1_cmd.angular.z=-0.5; vel_pub.publish(vel1_cmd); loop_rate.sleep(); // Sleep for the rest of the cycle to maintain the loop frequency } for(int i=1;i<=2;i++) { startTime = ros::Time::now(); if(i==2) rotationDuration = 1.8; else rotationDuration = 1.75; while((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = 1.5/i; vel_cmd.linear.y = 0.0; vel_cmd.linear.z = 0.0; vel_cmd.angular.x = 0; vel_cmd.angular.y = 0; vel_cmd.angular.z = 1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); // Sleep for the rest of the cycle to maintain the loop frequency } } for(int i=1;i<=2;i++) { startTime = ros::Time::now(); if(i==2) rotationDuration = 1.8; else rotationDuration = 1.75; while((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = 0.75*i; vel_cmd.linear.y = 0.0; vel_cmd.linear.z = 0.0; vel_cmd.angular.x = 0; vel_cmd.angular.y = 0; vel_cmd.angular.z = -1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); // Sleep for the rest of the cycle to maintain the loop frequency } } ros::Duration(5.0).sleep(); startTime=ros::Time::now(); rotationDuration=1.75; while((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = 1.5; vel_cmd.linear.y = 0.0; vel_cmd.linear.z = 0.0; vel_cmd.angular.x = 0; vel_cmd.angular.y = 0; vel_cmd.angular.z = -1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); // Sleep for the rest of the cycle to maintain the loop frequency } return 0; }
正常是画一个太极图,多次运行代码可能可以画多个正常的,也可能像图中这样乱画,而且感觉有时候运行代码突然特别卡。ubuntu20.04,ros:noetic -
你的ROS代码中存在一些问题和潜在的改进点,这些问题可能导致行为不一致和性能问题。以下是一些关键的问题和建议:
1. 错误的HTML实体编码
在你的代码中,你使用了HTML实体编码(如
<
代替<
)来编写C++代码,这在C++编译器中是不被识别的。你需要将这些替换为标准的C++语法。2. 线程和同步问题
虽然ROS通常使用单线程模型,但你的代码在逻辑上可能存在同步问题,特别是如果你在不同的节点或不同部分中共享或修改全局变量(如
startTime
和rotationDuration
)。在你的例子中,这些变量被静态声明,并且每次循环都重新赋值,这可能导致一些意外的行为,特别是如果ROS节点被重新启动或异常终止。3. 性能问题
如果ROS网络或节点之间存在高延迟或负载,
ros::Rate
的sleep()
调用可能会导致节点无法及时响应。此外,如果你的计算机资源不足(如CPU或内存),也可能导致性能问题。4. 逻辑问题
你的代码中有多个循环,每个循环都设置不同的速度和旋转时间。如果这些参数设置不当,或者与其他ROS节点(如turtle simulator)的交互存在延迟,可能会导致不稳定的行为。
5. 改进后的代码
下面是一个修改后的代码示例,修正了HTML实体编码问题,并做了一些小的逻辑调整:
#include "ros/ros.h" #include "geometry_msgs/Twist.h" int main(int argc, char *argv[]) { ros::init(argc, argv, "vel_ctrl"); ros::NodeHandle n; ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10); ROS_INFO("draw_circle start..."); static double rotationDuration = 1.75; ros::Time startTime; static double during = 3.5; ros::Rate loop_rate(10); // 初始旋转 startTime = ros::Time::now(); while ((ros::Time::now() - startTime).toSec() <= during) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = 0; vel_cmd.angular.z = -0.5; vel_pub.publish(vel_cmd); loop_rate.sleep(); } // 两次不同的直线和旋转 for (int i = 1; i <= 2; i++) { startTime = ros::Time::now(); rotationDuration = (i == 2) ? 1.8 : 1.75; while ((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = (i == 1) ? 1.5 : 0.75; vel_cmd.angular.z = 1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); } startTime = ros::Time::now(); rotationDuration = 1.75; while ((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = (i == 1) ? 1.5 : 0.75; vel_cmd.angular.z = -1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); } } ros::Duration(5.0).sleep(); // 最后的旋转 startTime = ros::Time::now(); rotationDuration = 1.75; while ((ros::Time::now() - startTime).toSec() <= rotationDuration) { geometry_msgs::Twist vel_cmd; vel_cmd.linear.x = 1.5; vel_cmd.angular.z = -1.8; vel_pub.publish(vel_cmd); loop_rate.sleep(); } return 0; }
6. 调试建议
- 确保ROS网络正常运行,没有其他节点干扰。
- 使用`rostopic echo /turtle
以上为生成回答,仅供参考~