IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 基于ROS和turtlebot2的多机器人导航定位配置记录 -> 正文阅读

[人工智能]基于ROS和turtlebot2的多机器人导航定位配置记录

基于ROS和turtlebot2的多机器人导航定位配置记录

整个流程是:
1 先用单个机器人完成环境建图
2 配置两个机器人的主从机
3 配置两个机器人的turtlebot_bringup、amcl、key_teleop、move_base

需要的前置知识:ROS的命名空间,TFtree

先列一下参考文章:
古月居博客的多机器人导航
ROS配置多机器人导航
多机器人导航与编队(一)
多机器人导航与编队(二)

需要修改的文件:
turtlebot_bringup minimal.launch robot.launch.xml
turtlebot_teleop keboard_teleop.launch
turtlebot_navigation amcl.launch, movebase.launch,hokuyo_laser.launch
kobuki_node base.yaml

turtlebot_bringup minimal.launch:需要加入 命名空间 group ns=“robot1”

<launch>  
<group ns="robot1">
	<!-- Turtlebot -->
  <arg name="base"              default="$(env TURTLEBOT_BASE)"         doc="mobile base type [create, roomba]"/>
  <arg name="battery"           default="$(env TURTLEBOT_BATTERY)"      doc="kernel provided locatio for battery info, use /proc/acpi/battery/BAT0 in 2.6 or earlier kernels." />
  <arg name="stacks"            default="$(env TURTLEBOT_STACKS)"       doc="stack type displayed in visualisation/simulation [circles, hexagons]"/>
  <arg name="3d_sensor"         default="$(env TURTLEBOT_3D_SENSOR)"    doc="3d sensor types [kinect, asux_xtion_pro]"/>
  <arg name="simulation"        default="$(env TURTLEBOT_SIMULATION)"   doc="set flags to indicate this turtle is run in simulation mode."/>
  <arg name="serialport"        default="$(env TURTLEBOT_SERIAL_PORT)"  doc="used by create to configure the port it is connected on [/dev/ttyUSB0, /dev/ttyS0]"/>

  <param name="/use_sim_time" value="$(arg simulation)"/>

  <include file="$(find turtlebot_bringup)/launch/includes/robot.launch.xml">
    <arg name="base" value="$(arg base)" />
    <arg name="stacks" value="$(arg stacks)" />
    <arg name="3d_sensor" value="$(arg 3d_sensor)" />
  </include>
  <include file="$(find turtlebot_bringup)/launch/includes/mobile_base.launch.xml">
    <arg name="base" value="$(arg base)" />
    <arg name="serialport" value="$(arg serialport)" />
  </include>
  <include unless="$(eval arg('battery') == 'None')" file="$(find turtlebot_bringup)/launch/includes/netbook.launch.xml">
    <arg name="battery" value="$(arg battery)" />
  </include>
</group>
</launch>

keboard_teleop.launch 加入group命名空间

<launch>
<group ns="robot1">
  <!-- turtlebot_teleop_key already has its own built in velocity smoother -->
    <node pkg="turtlebot_teleop" type="turtlebot_teleop_key" name="turtlebot_teleop_keyboard"  output="screen">
    <param name="scale_linear" value="0.5" type="double"/>
    <param name="scale_angular" value="1.5" type="double"/>
    <remap from="turtlebot_teleop_keyboard/cmd_vel" to="cmd_vel_mux/input/teleop"/>
  </node>
</group>
</launch>

robot.launch.xml:添加<param name="tf_prefix" value="robot1" />robot_state_publisher
作用是给tf添加前缀

<!--
  Collection of robot-centric definitions and nodes for the turtlebot. 
 -->
<launch>
  <arg name="base"/>
  <arg name="stacks"/>
  <arg name="3d_sensor"/>
  
  <include file="$(find turtlebot_bringup)/launch/includes/description.launch.xml">
    <arg name="base" value="$(arg base)" />
    <arg name="stacks" value="$(arg stacks)" />
    <arg name="3d_sensor" value="$(arg 3d_sensor)" />
  </include>

  <!-- important generally, but specifically utilised by the current app manager -->  
  <param name="robot/name" value="$(optenv ROBOT turtlebot)"/>
  <param name="robot/type" value="turtlebot"/>
  
  <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher">
    <param name="publish_frequency" type="double" value="5.0" />
    <param name="tf_prefix" value="robot1" />
  </node>

  <node pkg="diagnostic_aggregator" type="aggregator_node" name="diagnostic_aggregator" >
    <rosparam command="load" file="$(find turtlebot_bringup)/param/$(arg base)/diagnostics.yaml" />
  </node>
</launch>

amcl.launch 修改map路径,并发布连接上maprobot1/odom的tf,加入group ns

<launch>
<group ns="robot1">
  <!-- Map server -->
  <arg name="map_file" default="/home/gglin/map/map.yaml"/>
  <node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)" >
     <param name="frame_id" value="map" />
</node>

  <node pkg="tf" type="static_transform_publisher" name="map_to_odom" args="0.0 0.0 0.0 0 0 0.0 map robot1/odom 1000"/>
  

  <!-- AMCL -->
  <arg name="custom_amcl_launch_file" default="$(find multi_robots_navgation)/launch/includes/robot1_amcl.launch.xml"/>
  <arg name="initial_pose_x" default="0.0"/> <!-- Use 17.0 for willow's map in simulation -->
  <arg name="initial_pose_y" default="0.0"/> <!-- Use 17.0 for willow's map in simulation -->
  <arg name="initial_pose_a" default="0.0"/>
  <include file="$(arg custom_amcl_launch_file)">
    <arg name="initial_pose_x" value="$(arg initial_pose_x)"/>
    <arg name="initial_pose_y" value="$(arg initial_pose_y)"/>
    <arg name="initial_pose_a" value="$(arg initial_pose_a)"/>
  </include>

  <!-- Move base -->
  <include file="$(find multi_robots_navgation)/launch/includes/robot1_move_base.launch.xml">
  </include>

</group>
</launch>

其包含的 robot1_amcl.launch.xml 如下 修改odom_frame_idodom_frame_id

<launch>
  <arg name="use_map_topic"   default="false"/>
  <arg name="scan_topic"      default="scan"/> 
  <arg name="initial_pose_x"  default="0.0"/>
  <arg name="initial_pose_y"  default="0.0"/>
  <arg name="initial_pose_a"  default="0.0"/>
  <arg name="odom_frame_id"   default="robot1/odom"/>
  <arg name="base_frame_id"   default="robot1/base_footprint"/>
  <arg name="global_frame_id" default="map"/>

  <node pkg="amcl" type="amcl" name="amcl">
    <param name="use_map_topic"             value="$(arg use_map_topic)"/>
    <!-- Publish scans from best pose at a max of 10 Hz -->
    <param name="odom_model_type"           value="diff"/>
    <param name="odom_alpha5"               value="0.1"/>
    <param name="gui_publish_rate"          value="10.0"/>
    <param name="laser_max_beams"             value="60"/>
    <param name="laser_max_range"           value="26.0"/>
    <param name="min_particles"             value="500"/>
    <param name="max_particles"             value="2000"/>
    <param name="kld_err"                   value="0.05"/>
    <param name="kld_z"                     value="0.99"/>
    <param name="odom_alpha1"               value="0.2"/>
    <param name="odom_alpha2"               value="0.2"/>
    <!-- translation std dev, m -->
    <param name="odom_alpha3"               value="0.2"/>
    <param name="odom_alpha4"               value="0.2"/>
    <param name="laser_z_hit"               value="0.5"/>
    <param name="laser_z_short"             value="0.05"/>
    <param name="laser_z_max"               value="0.05"/>
    <param name="laser_z_rand"              value="0.5"/>
    <param name="laser_sigma_hit"           value="0.2"/>
    <param name="laser_lambda_short"        value="0.1"/>
    <param name="laser_model_type"          value="likelihood_field"/>
    <!-- <param name="laser_model_type" value="beam"/> -->
    <param name="laser_likelihood_max_dist" value="2.0"/>
    <param name="update_min_d"              value="0.2"/>
    <param name="update_min_a"              value="0.2"/>
    <param name="odom_frame_id"             value="$(arg odom_frame_id)"/> 
    <param name="base_frame_id"             value="$(arg base_frame_id)"/> 
    <param name="global_frame_id"           value="$(arg global_frame_id)"/>
    <param name="resample_interval"         value="1"/>
    <!-- Increase tolerance because the computer can get quite busy -->
    <param name="transform_tolerance"       value="1.0"/>
    <param name="recovery_alpha_slow"       value="0.0"/>
    <param name="recovery_alpha_fast"       value="0.0"/>
    <param name="initial_pose_x"            value="$(arg initial_pose_x)"/>
    <param name="initial_pose_y"            value="$(arg initial_pose_y)"/>
    <param name="initial_pose_a"            value="$(arg initial_pose_a)"/>
    <remap from="scan"                      to="$(arg scan_topic)"/>
  </node>
</launch>

amcl包含的robot1_move_base.launch.xml 如下,修改的地方 odom_frame_id base_frame_id

<!-- 
    ROS navigation stack with velocity smoother and safety (reactive) controller
-->
<launch>
  <include file="$(find multi_robots_navgation)/launch/includes/velocity_smoother.launch.xml"/>
  <include file="$(find multi_robots_navgation)/launch/includes/safety_controller.launch.xml"/>
  
  <arg name="odom_frame_id"   default="robot1/odom"/>
  <arg name="base_frame_id"   default="robot1/base_footprint"/>
  <arg name="global_frame_id" default="map"/>
  <arg name="odom_topic" default="odom" />
  <arg name="laser_topic" default="scan" />
  <arg name="custom_param_file" default="$(find multi_robots_navgation)/param/dummy.yaml"/>

  <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
    <rosparam file="$(find multi_robots_navgation)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
    <rosparam file="$(find multi_robots_navgation)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />   
    <rosparam file="$(find multi_robots_navgation)/param/local_costmap_params.yaml" command="load" />   
    <rosparam file="$(find multi_robots_navgation)/param/global_costmap_params.yaml" command="load" />
    <rosparam file="$(find multi_robots_navgation)/param/dwa_local_planner_params.yaml" command="load" />
    <rosparam file="$(find multi_robots_navgation)/param/move_base_params.yaml" command="load" />
    <rosparam file="$(find multi_robots_navgation)/param/global_planner_params.yaml" command="load" />
    <rosparam file="$(find multi_robots_navgation)/param/navfn_global_planner_params.yaml" command="load" />
    <!-- external params file that could be loaded into the move_base namespace -->
    <rosparam file="$(arg custom_param_file)" command="load" />
    
    <!-- reset frame_id parameters using user input data -->
    <param name="global_costmap/global_frame" value="$(arg global_frame_id)"/>
    <param name="global_costmap/robot_base_frame" value="$(arg base_frame_id)"/>
    <param name="local_costmap/global_frame" value="$(arg odom_frame_id)"/>
    <param name="local_costmap/robot_base_frame" value="$(arg base_frame_id)"/>
    <param name="DWAPlannerROS/global_frame_id" value="$(arg odom_frame_id)"/>

    <remap from="cmd_vel" to="navigation_velocity_smoother/raw_cmd_vel"/>
    <remap from="odom" to="$(arg odom_topic)"/>
    <remap from="scan" to="$(arg laser_topic)"/>
  </node>
</launch>

hokuyo_laser.launch 添加group ns 和 发布静态tf

<launch>
<group ns="robot1">
  <node name="hokuyo" pkg="hokuyo_node" type="hokuyo_node" respawn="false" output="screen">

  <!-- Starts up faster, but timestamps will be inaccurate. --> 
  <param name="calibrate_time" type="bool" value="false"/> 

  <!-- Set the port to connect to here -->
  <param name="port" type="string" value="/dev/hokuyo"/> 
  <param name="frame_id"  type="string" value="robot1/laser"/>
  <param name="intensity" type="bool" value="false"/>
  </node>

  <node pkg="tf" type="static_transform_publisher" name="base_to_laser" args="0.0 0.0 0.18 0 0.0 0.0 robot1/base_link robot1/laser 100"/>
</group>
</launch>

base.yaml: 修改odom_framebase_frame

##############################################################################
# Firmware Source
##############################################################################

device_port: /dev/kobuki

# published joint states
wheel_left_joint_name: wheel_left_joint
wheel_right_joint_name: wheel_right_joint

# battery voltage at full charge (100%) (float, default: 16.5)
battery_capacity: 16.5

# battery voltage at first warning (15%) (float, default: 13.5)
battery_low: 14.0

# battery voltage at critical level (5%) (float, default: 13.2)
battery_dangerous: 13.2

# If a new command isn't received within this many seconds, the base is stopped (double, default: 0.6)
cmd_vel_timeout: 0.6

# Causes node to publish TF for odom_frame to base_frame. Disable only if you plan to use robot_pose_ekf
# (see use_imu_heading description) (bool, default: true)
publish_tf: true

# Use imu readings for heading instead of encoders. That's the normal operation mode for Kobuki, as its
# gyro is very reliable. Disable only if you want to fuse encoders and imu readings in a more sophisticated
# way, for example filtering and fussing with robot_pose_ekf (bool, default: true)
use_imu_heading: true

# Name of the odometry TF frame (string, default: odom)
odom_frame: robot1/odom

# Name of the base TF frame  (string, default: base_footprint)
base_frame: robot1/base_footprint

正常的tf应该类似这样
在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:32:47  更:2022-07-21 21:34:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:46:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码