zoukankan      html  css  js  c++  java
  • 基于ROS1.0的stdr simulation搭建多移动机器人(multiple robots)仿真系统

    基于ROS1.0的stdr simulation搭建多移动机器人(multiple robots)仿真系统
    原创SimileciWH 最后发布于2018-10-26 17:12:20 https://blog.csdn.net/SimileciWH/article/details/83416437
     

    多移动机器人的概念就不叙述了,直接讲如何正确的在ROS系统下构建基于stdr simulation和gazebo平台下的仿真实验。

    1    前提准备

    安装好如下几个基本的包:

    stdr simulation
    amcl
    move_base
    gazebo_ros
    turtlebot2的完整包
    等其他必要的ROS环境

    2    单移动机器人和多移动机器人的配置区别

    单移动机器人比较简单,也不用关注与namespace这些问题,二多移动机器人,因为每个机器人都具备同样的基本功能,因此不可避免的需要用到namespace(以下简称ns)的概念将他们区分开,这样就可以一直通过namespace复制同样基本功能的机器人了。如果你不采用ns的方式,而是简单的不断生成新的机器人,即使你保证他们的位置不同,但是因为node名重复,ROS会kill之前的node保留最后一个生成的机器人状态。

    但是除了namespace外,还需要配置tf_prefixes的参数值,这是最大的区别之处,也是最重要的,能否成功的生成多个移动机器人。

    2.1    要明确的概念

    构造多移动机器人在一张map中,这个map可以使slam构建的,无论你是用cartographer,hector_slam,gmapping等。我们都是希望map只有一张,每个机器人是全局共享的。

    每个机器人之间除了初始时刻的位姿不同以外,其他的结构,携带的传感器类型都完全一样,没有差别。当然你可以根据自己的需求使得他们不同。如果希望每个机器人都可以通过amcl和move_base进行自主导航和实时定位,那么每个机器人都应当具备amcl和move_base。

    因此,map是全局的,不需要ns,机器人的构建,amcl和move_base是需要ns的,因为每个移动机器人都需要具备这些属性。

    如下结构所示:

    /map
    /robot1/robot_state_publisher /robot2/robot_state_publisher
    /robot1/robot_pose_ekf /robot2/robot_pose_ekf
    /robot1/amcl /robot2/amcl
    /robot1/move_base /robot2/move_base
    /robot1/laser_0 /robot2/laser_0
    /robot1/sensor0 /robot2/sensor0
    /robot1/sensor1 /robot2/sensor0
    ....... ........
    2.2    配置单个机器人的launch文件,然后就可以在其他launch文件中无限的复制单个移动机器人的个数了:

    2.2.1      在你的工作空间下新建一个项目:

    cd ~/catkin_ns/src
    catkin_creat_pkg multi_robots
    cd multi_robots
    mkdir launch map param rviz
    tree
    最终如下所示:

    ~/catkin_ws/src/multi_robots$ tree
    .
    ├── CMakeLists.txt
    ├── launch
    ├── map
    ├── package.xml
    ├── param
    └── rviz

    4 directories, 2 files
    在launch文件下,新建one_robot.launch

    内容如下:

    <!--
    这是在gazebo平台的仿真实验
    本文件名为:one_robot.launch
    -->
    <launch>
    <arg name="robot_name"/>
    <arg name="init_pose"/>

    <node name="spawn_minibot_model" pkg="gazebo_ros" type="spawn_model"
    args="$(arg init_pose) -urdf -param /robot_description -model $(arg robot_name)"
    respawn="false" output="screen" />

    <node pkg="robot_state_publisher" type="robot_state_publisher"
    name="robot_state_publisher" output="screen"/>

    <!-- The odometry estimator, throttling, fake laser etc. go here -->
    <!-- All the stuff as from usual robot launch file -->
    </launch>
    在launch文件中,有两个变量,robot_name和init_pose,可以通过这两个参数生成无数个移动机器人。

    2.2.2    在launch文件夹下创建,名为:myrobots.launch的文件

    文件内容如下:

    <!--
    这是在gazebo平台的仿真实验
    本文件名为:myrobots.launch
    在这个文件中首先加载了turtlebot2的模型
    然后创建了3个移动机器人
    -->
    <launch>
    <!-- No namespace here as we will share this description.
    Access with slash at the beginning -->
    <param name="robot_description"
    command="$(find xacro)/xacro.py $(find turtlebot_description)/robots/kobuki_hexagons_asus_xtion_pro.urdf.xacro" />

    <!-- BEGIN ROBOT 1-->
    <group ns="robot1">
    <param name="tf_prefix" value="robot1_tf" />
    <include file="$(find multi_robots)/launch/one_robot.launch" >
    <arg name="init_pose" value="-x 1 -y 1 -z 0" />
    <arg name="robot_name" value="Robot1" />
    </include>
    </group>

    <!-- BEGIN ROBOT 2-->
    <group ns="robot2">
    <param name="tf_prefix" value="robot2_tf" />
    <include file="$(find multi_robots)/launch/one_robot.launch" >
    <arg name="init_pose" value="-x -1 -y 1 -z 0" />
    <arg name="robot_name" value="Robot2" />
    </include>
    </group>

    <!-- BEGIN ROBOT 3-->
    <group ns="robot3">
    <param name="tf_prefix" value="robot3_tf" />
    <include file="$(find multi_robots)/launch/one_robot.launch" >
    <arg name="init_pose" value="-x 1 -y 2 -z 0" />
    <arg name="robot_name" value="Robot3" />
    </include>
    </group>
    </launch>
    2.2.3    在launch文件夹下,创建main.launch,用来加载之前的myroobts.launch并且还可以将其他的内容加在这里,所以命名成main.launch

    内容如下:

    <!--
    这是在gazebo平台的仿真实验
    本文件名为:main.launch
    第一段是运行gazebo中的一个地图环境,直接使用的是tuetlebot_gazebo中的,你也可以加载自己的地图
    第二段是运行创建的移动机器人群体
    -->
    <launch>
    <param name="/use_sim_time" value="true" />

    <!-- start world -->
    <node name="gazebo" pkg="gazebo_ros" type="gazebo"
    args="$(find turtlebot_gazebo)/worlds/playground.world" respawn="false" output="screen" />


    <!-- include our robots -->
    <include file="$(find multi_robots)/launch/myrobots.launch"/>
    </launch>
    至此初步的配置已经完成了。

    如果你是按照我的工程名字建立的,则不需要改动,如果你的包是你自定义的,则需要讲myrobots.launch文件中的multi_robots全部替换成你的包的名字。

    3    查看在gazebo仿真中的情况

    roslaunch multi_robots main.launch
    注意第一次加载gazebo会话费很长时间,或者报错,请耐心等待,或者重新运行launch文件。

    结果如下图1所示:

                              

                                                                                         图1

    三个turtlebot2成功的在地图中创建了。

    现在你可以订阅cmd_vel话题,使用键盘控制每一个小车移动了

    当然你也可以编写自己的运动控制算法来验证自己的算法了。 
                   

                                                                                                   图2

    图2为运行时的node和参数,注意tf_prefix一定要设置,很关键

    从图2中可以看出,三个移动机器人分别属于robot1,robot2,robot3,的命名空间。

    rostopic list 的全部信息如下所示:

    /clock
    /gazebo/link_states
    /gazebo/model_states
    /gazebo/parameter_descriptions
    /gazebo/parameter_updates
    /gazebo/set_link_state
    /gazebo/set_model_state
    /robot1/camera/depth/camera_info
    /robot1/camera/depth/image_raw
    /robot1/camera/depth/points
    /robot1/camera/parameter_descriptions
    /robot1/camera/parameter_updates
    /robot1/camera/rgb/camera_info
    /robot1/camera/rgb/image_raw
    /robot1/camera/rgb/image_raw/compressed
    /robot1/camera/rgb/image_raw/compressed/parameter_descriptions
    /robot1/camera/rgb/image_raw/compressed/parameter_updates
    /robot1/camera/rgb/image_raw/compressedDepth
    /robot1/camera/rgb/image_raw/compressedDepth/parameter_descriptions
    /robot1/camera/rgb/image_raw/compressedDepth/parameter_updates
    /robot1/camera/rgb/image_raw/theora
    /robot1/camera/rgb/image_raw/theora/parameter_descriptions
    /robot1/camera/rgb/image_raw/theora/parameter_updates
    /robot1/joint_states
    /robot1/mobile_base/commands/motor_power
    /robot1/mobile_base/commands/reset_odometry
    /robot1/mobile_base/commands/velocity
    /robot1/mobile_base/events/bumper
    /robot1/mobile_base/events/cliff
    /robot1/mobile_base/sensors/imu_data
    /robot1/odom
    /robot2/camera/depth/camera_info
    /robot2/camera/depth/image_raw
    /robot2/camera/depth/points
    /robot2/camera/parameter_descriptions
    /robot2/camera/parameter_updates
    /robot2/camera/rgb/camera_info
    /robot2/camera/rgb/image_raw
    /robot2/camera/rgb/image_raw/compressed
    /robot2/camera/rgb/image_raw/compressed/parameter_descriptions
    /robot2/camera/rgb/image_raw/compressed/parameter_updates
    /robot2/camera/rgb/image_raw/compressedDepth
    /robot2/camera/rgb/image_raw/compressedDepth/parameter_descriptions
    /robot2/camera/rgb/image_raw/compressedDepth/parameter_updates
    /robot2/camera/rgb/image_raw/theora
    /robot2/camera/rgb/image_raw/theora/parameter_descriptions
    /robot2/camera/rgb/image_raw/theora/parameter_updates
    /robot2/joint_states
    /robot2/mobile_base/commands/motor_power
    /robot2/mobile_base/commands/reset_odometry
    /robot2/mobile_base/commands/velocity
    /robot2/mobile_base/events/bumper
    /robot2/mobile_base/events/cliff
    /robot2/mobile_base/sensors/imu_data
    /robot2/odom
    /robot3/camera/depth/camera_info
    /robot3/camera/depth/image_raw
    /robot3/camera/depth/points
    /robot3/camera/parameter_descriptions
    /robot3/camera/parameter_updates
    /robot3/camera/rgb/camera_info
    /robot3/camera/rgb/image_raw
    /robot3/camera/rgb/image_raw/compressed
    /robot3/camera/rgb/image_raw/compressed/parameter_descriptions
    /robot3/camera/rgb/image_raw/compressed/parameter_updates
    /robot3/camera/rgb/image_raw/compressedDepth
    /robot3/camera/rgb/image_raw/compressedDepth/parameter_descriptions
    /robot3/camera/rgb/image_raw/compressedDepth/parameter_updates
    /robot3/camera/rgb/image_raw/theora
    /robot3/camera/rgb/image_raw/theora/parameter_descriptions
    /robot3/camera/rgb/image_raw/theora/parameter_updates
    /robot3/joint_states
    /robot3/mobile_base/commands/motor_power
    /robot3/mobile_base/commands/reset_odometry
    /robot3/mobile_base/commands/velocity
    /robot3/mobile_base/events/bumper
    /robot3/mobile_base/events/cliff
    /robot3/mobile_base/sensors/imu_data
    /robot3/odom
    /rosout
    /rosout_agg
    /tf
    /tf_static
    可以看到,属于不同robot命名空间的移动机器人基本功能完全一样。rqt_graph就不贴了,太大了,截图也看不清楚。

    至此在gazebo中的基本加载多机器人的仿真环境已经具备,你可以通过订阅话题对你的运动控制算法进行验证了。

    注意,如果你要加载laser_scan激光雷达或者其他传感器,只需要在one_robot.launch注释的位置之间添加就可以了,其他文件不用修改。

    可以参考链接:

    multi-robots+laser rviz :https://answers.ros.org/question/40397/multirobot-laser-rviz/

    4     配置导航包

    导航包的写法可以参考ROS官网给出的实例:

    link:http://wiki.ros.org/navigation/Tutorials/RobotSetup

    在launch文件下新建一个move_base.launch文件,

    内容如下:

    <launch>
    <!--- Run AMCL -->
    <include file="$(find amcl)/examples/amcl_diff.launch" />

    <!-- Define your move_base node -->
    <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
    <rosparam file="$(find your_pkg)/costmap_common_params.yaml" command="load" ns="global_costmap"/>
    <rosparam file="$(find your_pkg)/costmap_common_params.yaml" command="load" ns="local_costmap" />
    <rosparam file="$(find your_pkg)/local_costmap_params.yaml" command="load" />
    <rosparam file="$(find your_pkg)/global_costmap_params.yaml" command="load" />
    <rosparam file="$(find your_pkg)/base_local_planner_params.yaml" command="load" />

    <remap from="map" to="/map" />
    </node>
    </launch>
    接着继续新建一个navigation.launch文件,

    内容如下:

    <launch>
    <param name="/use_sim_time" value="true"/>

    <!-- Run the map server -->
    <node name="map_server" pkg="map_server" type="map_server" args="$(find your_pkg)/map/map.yaml" >
    <param name="frame_id" value="/map" />
    </node>

    <group ns="robot1">
    <param name="tf_prefix" value="robot1_tf" />
    <param name="amcl/initial_pose_x" value="1" />
    <param name="amcl/initial_pose_y" value="1" />
    <include file="$(find your_pkg)/launch/move_base.launch" />
    </group>

    <group ns="robot2">
    <param name="tf_prefix" value="robot2_tf" />
    <param name="amcl/initial_pose_x" value="-1" />
    <param name="amcl/initial_pose_y" value="1" />
    <include file="$(find your_pkg)/launch/move_base.launch" />
    </group>

    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find your_pkg)/config/multi.vcg"
    output="screen" />

    </launch>
    这几个launch文件都需要针对你自己的环境做修改的,之间运行是不正确的。

    5    关于tf_prefix的信息,可以在ROS官网看到

    link:http://wiki.ros.org/tf2/Migration

    6     如果运行launch文件时提示tf2  “/” 的错误

    这是由于tf2中去除了“/”的检测,这与tf是有区别的,解决办法就是讲话题的“/”全部删除

    7    还可以通过这个视屏学习关于multiple robots的配置

    link:https://www.youtube.com/watch?v=mFTkN5v4Jzc&t=370s 

    8    stdr simulation 平台实现多移动机器人的创建,amcl定位和move_base的导航

    updating
    ————————————————
    版权声明:本文为CSDN博主「SimileciWH」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/simileciwh/article/details/83416437

  • 相关阅读:
    DECLARE_MESSAGE_MAP用法
    BEGIN_MESSAGE_MAP
    2019-2020-1 20175314 《信息安全系统设计基础》第2周学习总结
    2019-2020-1 20175314 《信息安全系统设计基础》第1周学习总结
    20175314 实验五 Java网络编程
    20175314 实验四 Android开发基础
    20175314 《Java程序设计》第十一周学习总结
    20175314薛勐 数据结构-排序(选做)
    20175314薛勐 数据结构-单链表(选做)
    20175314 《Java程序设计》第十周学习总结
  • 原文地址:https://www.cnblogs.com/dayspring/p/12547101.html
Copyright © 2011-2022 走看看