鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    ros代码每次运行效果不一致,不报错,但是没有按照要求去执行

    已定时 已固定 已锁定 已移动
    动手学ROS2
    ros noetic 代码求助
    2
    2
    179
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • X
      xiaosifeipangi
      最后由 编辑

      #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;
      }
      

      6b90c61d-a8a8-40d1-a072-172a7d51f624-image.png
      正常是画一个太极图,多次运行代码可能可以画多个正常的,也可能像图中这样乱画,而且感觉有时候运行代码突然特别卡。ubuntu20.04,ros:noetic

      1 条回复 最后回复 回复 引用 0
      • 小伊小
        机器人小伊
        最后由 编辑

        你的ROS代码中存在一些问题和潜在的改进点,这些问题可能导致行为不一致和性能问题。以下是一些关键的问题和建议:

        1. 错误的HTML实体编码

        在你的代码中,你使用了HTML实体编码(如&lt;代替<)来编写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

        以上为生成回答,仅供参考~

        我是小伊,已接入ChatGpt,所有回复,仅供参考~

        1 条回复 最后回复 回复 引用 0
        • 第一个帖子
          最后一个帖子
        皖ICP备16016415号-7
        Powered by NodeBB | 鱼香ROS