当前位置: 首页 > news >正文

ROS实践-虚拟仿真平台Stage/Gazebo

1. 区别

StageGazebo 都是 ROS 生态系统中的仿真工具,但它们的功能侧重点不同。

Stage:轻量级的 2D 仿真工具,适用于大规模机器人群体仿真。

Gazebo:功能更强大的 3D 物理仿真环境,支持复杂物理交互、传感器建模和机器人动力学仿真。

2. Stage仿真

(1)安装stage仿真软件 

        使用命令:sudo apt-get install ros-noetic-stage-ros来安装。这个平台中有一些自带的.world地图文件,我们可以加载它自带的地图,也可以自己来编写地图文件。

(2)编写控制代码

功能:控制机器人走圆形路线。

#!/usr/bin/python
import rospy
from geometry_msgs.msg import Twistdef cmd_velmodule():# 初始化ROS节点,节点名称为 'circle_drawer',anonymous=False 使其名称唯一rospy.init_node('circle_drawer', anonymous=False)  # 创建一个Publisher,发布消息到 /cmd_vel 话题,消息类型为 Twist,队列大小为10cmd_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)  # 设置发布频率为 10Hzrate = rospy.Rate(10)  # 创建一个 Twist 消息对象,用于存储速度指令twist = Twist()rospy.loginfo("Start controlling robot to draw a circle")  # 记录日志信息# 进入主循环,持续发布速度指令,直到节点被终止while not rospy.is_shutdown():twist.linear.x = 0.2  # 设置线速度,单位:m/stwist.angular.z = 0.4  # 设置角速度,单位:rad/s(正值表示逆时针旋转)cmd_pub.publish(twist)  # 发布速度指令到 /cmd_vel 话题rate.sleep()  # 休眠以保持 10Hz 的循环频率
if __name__ == "__main__":try:cmd_velmodule()  # 运行控制函数except rospy.ROSInterruptException:pass  # 异常处理,当节点被中断时,安全退出

(3)虚拟平台显示

        启动主节点,使用命令运行虚拟地图:rosrun stage_ros stageros $(rospack find stage_ros)/world/willow-erratic.world

        地图运行完毕后,运行上面我们自己编写的代码文件,就可以看到小车在按照我们编程程序的轨迹在虚拟地图上运行(按照圆形轨迹运动)。

3. Cazebo仿真 

(1)安装Gazebo。

4. 疑难解答

问题1:代码中发布的话题是如何和虚拟平台上的机器人联系起来的呢?

        在 ROS 机器人仿真或实际应用中,Python 脚本通过 rospy.PublisherTwist 速度指令发布到 /cmd_vel 话题。而机器人本体(无论是 Gazebo 仿真环境中的机器人,还是实际硬件机器人)通常会运行一个运动控制器(如 diff_drive_controllermove_base),该控制器会订阅 /cmd_vel 话题,并解析其中的线速度(linear.x)和角速度(angular.z)指令,进而驱动底盘运动。

         在 Stage(Stage ROS 或 Stagefaa) 进行仿真时,机器人模型 并不是 直接由 URDF 定义的,而是通过 world 文件(.world 进行描述的。

        在 Gazebo 仿真环境中,机器人通常是通过 URDF/SDF 文件定义的,并且 Gazebo 插件(如 gazebo_ros_controlgazebo_ros_diff_drive)会负责订阅 /cmd_vel 话题并控制模型的物理运动。而在实际机器人中,控制器通常运行在嵌入式系统(如 Raspberry Pi 或 STM32)上,解析 /cmd_vel 指令,并将其转换为电机驱动信号,使机器人按照给定的速度移动。

问题2:那么这个机器人模型是在哪定义的呢?如何查看它订阅的哪个话题?

        机器人模型通常定义在 URDF(.urdf 或 .xacro)SDF(.sdf) 文件中,用于描述机器人的结构、关节和传感器等信息。而 .world 文件 主要用于 Gazebo 仿真环境,负责定义仿真场景,包括机器人、传感器、地形和其他环境元素。

        在仿真中,机器人一般会 订阅某个速度控制话题(例如 /cmd_vel),并根据接收到的指令进行运动。如果场景中只有一个机器人,通常会默认订阅 /cmd_vel 话题来接收速度指令并执行相应动作。

问题3:既然是读取/cmd_vel话题,那么如果有多个机器人模型需要执行不同的动作怎么办呢?

        对于多个机器人,每个机器人需要订阅不同的控制话题,例如 /cmd_vel_robot1/cmd_vel_robot2,以便分别控制各自的运动。每个机器人都可以通过不同的话题接收各自的控制命令。比如,机器人 A 和机器人 B 可以分别使用 /cmd_vel_robot1/cmd_vel_robot2 这两个话题。在 ROS 中,你只需要确保每个机器人订阅的是不同的命令话题,这样每个机器人就能接收到对应的控制指令。

(1)修改python脚本文件,使得不同的机器人模型订阅不同的话题。

#!/usr/bin/python
import rospy
from geometry_msgs.msg import Twistdef cmd_velmodule_robot1():rospy.init_node('multi_robot_controller', anonymous=False)  # 初始化ROS节点cmd_pub_robot1 = rospy.Publisher('/cmd_vel_robot1', Twist, queue_size=10)  # 发布到 /cmd_vel_robot1 话题cmd_pub_robot2 = rospy.Publisher('/cmd_vel_robot2', Twist, queue_size=10)  # 发布到 /cmd_vel_robot2 话题rate = rospy.Rate(10)  # 10Hztwist1 = Twist()twist2 = Twist()rospy.loginfo("Start controlling robots")while not rospy.is_shutdown():# 控制机器人1twist1.linear.x = 0.2  # 机器人1的线速度twist1.angular.z = 0.4  # 机器人1的角速度cmd_pub_robot1.publish(twist1)  # 发布速度指令到机器人1# 控制机器人2twist2.linear.x = 0.1  # 机器人2的线速度twist2.angular.z = 0.6  # 机器人2的角速度cmd_pub_robot2.publish(twist2)  # 发布速度指令到机器人2rate.sleep()  # 休眠,保证10Hz循环if __name__ == "__main__":try:cmd_velmodule_robot1()except rospy.ROSInterruptException:pass

(2)修改虚拟地图文件.world

robot
(name "roomba1"pose [-8.0 6.0 0.0 0.0] drive "diff"cmd_vel_topic "/cmd_vel_robot1"  # 机器人1订阅这个话题
)robot
(name "roomba2"pose [8.0 -6.0 0.0 0.0] drive "diff"cmd_vel_topic "/cmd_vel_robot2"  # 机器人2订阅这个话题
)


http://www.mrgr.cn/news/93519.html

相关文章:

  • 第三次CCF-CSP认证(含C++源码)
  • DeepSeek大模型 —— 全维度技术解析
  • vite:初学 p5.js demo
  • 【DuodooTEKr 】多度科技 以开源之力,驱动企业数字化转型
  • 选择排序算法的SIMD优化
  • AMD(xilinx) FPGA书籍推荐
  • 如何在rust中解析 windows 的 lnk文件(快捷方式)
  • 【C语言】指针篇
  • Java基于SringBoot的果树的生长信息管理系统,附源码+文档说明
  • dify在腾讯云服务器上部署
  • C++11新特性 3.constexpr
  • Windows Server开启审计功能
  • 基于大模型的视神经脊髓炎手术全流程风险预测与诊疗方案研究
  • IDEA 接入 Deepseek
  • 鬼泣:动画2
  • OpenManus的安装与体验
  • 数据结构--顺序表
  • 深入解析 JVM —— 从基础概念到实战调优的全链路学习指南
  • 我的世界1.20.1forge模组开发(8)——自定义实体、AI
  • 小谈java内存马