ROS探索总结(十五)——amcl(导航与定位)

  • 内容
  • 评论
  • 相关

        在理解了move_base的基础上,我们开始机器人的定位与导航。gmaping包是用来生成地图的,需要使用实际的机器人获取激光或者深度数据,所以我们先在已有的地图上进行导航与定位的仿真。

        amcl是移动机器人二维环境下的概率定位系统。它实现了自适应(或kld采样)的蒙特卡罗定位方法,其中针对已有的地图使用粒子滤波器跟踪一个机器人的姿态。

一、测试

        首先运行机器人节点:
        roslaunch rbx1_bringup fake_turtlebot.launch 
        然后运行amcl节点,使用测试地图:   
        roslaunch rbx1_nav fake_amcl.launch map:=test_map.yaml 
        可以看一下fake_amcl.launch这个文件的内容:

  1. <launch>  
  2.   <!-- Set the name of the map yaml file: can be overridden on the command line. -->  
  3.   <arg name="map" default="test_map.yaml" />  
  4.   <!-- Run the map server with the desired map -->  
  5.   <node name="map_server" pkg="map_server" type="map_server" args="$(find rbx1_nav)/maps/$(arg map)"/>  
  6.   <!-- The move_base node -->  
  7.   <include file="$(find rbx1_nav)/launch/fake_move_base.launch" />  
  8.  
  9.   <!-- Run fake localization compatible with AMCL output -->  
  10.   <node pkg="fake_localization" type="fake_localization"  name="fake_localization" output="screen" />  
  11.   <!-- For fake localization we need static transforms between /odom and /map and /map and /world -->  
  12.   <node pkg="tf" type="static_transform_publisher" name="odom_map_broadcaster"   
  13. args="0 0 0 0 0 0 /odom /map 100" />  
  14. </launch>

         这个lanuch文件作用是加载地图,并且调用fake_move_base.launch文件打开move_base节点并加载配置文件,最后运行amcl。
         然后运行rviz:
         rosrun rviz rviz -d `rospack find rbx1_nav`/nav_fuerte.vcg 
         这时在rvoiz中就应该显示出了地图和机器人:

        现在就可以通过rviz在地图上选择目标位置了,然后就会看到机器人自动规划出一条全局路径,并且导航前进:

二、自主导航

        在实际应用中,我们往往希望机器人能够自主进行定位和导航,不需要认为的干预,这样才更智能化。在这一节的测试中,我们让目标点在地图中随机生成,然后机器人自动导航到达目标。
        这里运行的主要文件是:fake_nav_test.launch,让我们来看一下这个文件的内容:  

  1. <launch>  
  2.  
  3.   <param name="use_sim_time" value="false" />  
  4.  
  5.   <!-- Start the ArbotiX controller -->  
  6.   <include file="$(find rbx1_bringup)/launch/fake_turtlebot.launch" />  
  7.  
  8.   <!-- Run the map server with the desired map -->  
  9.   <node name="map_server" pkg="map_server" type="map_server" args="$(find rbx1_nav)/maps/test_map.yaml"/>  
  10.  
  11.   <!-- The move_base node -->  
  12.   <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">  
  13.     <rosparam file="$(find rbx1_nav)/config/fake/costmap_common_params.yaml" command="load" ns="global_costmap" />  
  14.     <rosparam file="$(find rbx1_nav)/config/fake/costmap_common_params.yaml" command="load" ns="local_costmap" />  
  15.     <rosparam file="$(find rbx1_nav)/config/fake/local_costmap_params.yaml" command="load" />  
  16.     <rosparam file="$(find rbx1_nav)/config/fake/global_costmap_params.yaml" command="load" />  
  17.     <rosparam file="$(find rbx1_nav)/config/fake/base_local_planner_params.yaml" command="load" />  
  18.     <rosparam file="$(find rbx1_nav)/config/nav_test_params.yaml" command="load" />  
  19.   </node>  
  20.  
  21.   <!-- Run fake localization compatible with AMCL output -->  
  22.   <node pkg="fake_localization" type="fake_localization" name="fake_localization" output="screen" />  
  23.  
  24.   <!-- For fake localization we need static transform between /odom and /map -->  
  25.   <node pkg="tf" type="static_transform_publisher" name="map_odom_broadcaster" args="0 0 0 0 0 0 /map /odom 100" />  
  26.  
  27.   <!-- Start the navigation test -->  
  28.   <node pkg="rbx1_nav" type="nav_test.py" name="nav_test" output="screen">  
  29.     <param name="rest_time" value="1" />  
  30.     <param name="fake_test" value="true" />  
  31.   </node>  
  32.  
  33. </launch>


 

        这个lanuch的功能比较多:
      (1) 加载机器人驱动
      (2) 加载地图
      (3) 启动move_base节点,并且加载配置文件
      (4) 运行amcl节点
      (5) 然后加载nav_test.py执行文件,进行随机导航
        相当于是把我们之前实验中的多个lanuch文件合成了一个文件。
        现在开始进行测试,先运行ROS:

        roscore

        然后我们运行一个监控的窗口,可以实时看到机器人发送的数据:
        rxconsole 

        接着运行lanuch文件,并且在一个新的终端中打开rviz:

  1. roslaunch rbx1_nav fake_nav_test.launch  
  2. (打开新终端)  
  3. rosrun rviz rviz -d `rospack find rbx1_nav`/nav_test_fuerte.vcg


        好了,此时就看到了机器人已经放在地图当中了。然后我们点击rviz上的“2D Pose Estimate”按键,然后左键在机器人上单击,让绿色的箭头和黄色的箭头重合,机器人就开始随机选择目标导航了:
       

         在监控窗口中,我们可以看到机器人发送的状态信息:


        其中包括距离信息、状态信息、目标的编号、成功率和速度等信息。

三、导航代码分析

  1. #!/usr/bin/env python  
  2.  
  3. import roslib; roslib.load_manifest('rbx1_nav')  
  4. import rospy  
  5. import actionlib  
  6. from actionlib_msgs.msg import *  
  7. from geometry_msgs.msg import Pose, PoseWithCovarianceStamped, Point, Quaternion, Twist  
  8. from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal  
  9. from random import sample  
  10. from math import pow, sqrt  
  11.  
  12. class NavTest():  
  13.     def __init__(self):  
  14.         rospy.init_node('nav_test', anonymous=True)  
  15.  
  16.         rospy.on_shutdown(self.shutdown)  
  17.  
  18.         # How long in seconds should the robot pause at each location?  
  19.         # 在每个目标位置暂停的时间  
  20.         self.rest_time = rospy.get_param("~rest_time", 10)  
  21.  
  22.         # Are we running in the fake simulator?  
  23.         # 是否仿真?  
  24.         self.fake_test = rospy.get_param("~fake_test", False)  
  25.  
  26.         # Goal state return values  
  27.         # 到达目标的状态  
  28.         goal_states = ['PENDING', 'ACTIVE', 'PREEMPTED',   
  29.                        'SUCCEEDED', 'ABORTED', 'REJECTED',  
  30.                        'PREEMPTING', 'RECALLING', 'RECALLED',  
  31.                        'LOST']  
  32.  
  33.         # Set up the goal locations. Poses are defined in the map frame.    
  34.         # An easy way to find the pose coordinates is to point-and-click  
  35.         # Nav Goals in RViz when running in the simulator.  
  36.         # Pose coordinates are then displayed in the terminal  
  37.         # that was used to launch RViz.  
  38.         # 设置目标点的位置  
  39.         # 如果想要获得某一点的坐标,在rviz中点击 2D Nav Goal 按键,然后单机地图中一点  
  40.         # 在终端中就会看到坐标信息  
  41.         locations = dict()  
  42.  
  43.         locations['hall_foyer'] = Pose(Point(0.643, 4.720, 0.000), Quaternion(0.000, 0.000, 0.223, 0.975))  
  44.         locations['hall_kitchen'] = Pose(Point(-1.994, 4.382, 0.000), Quaternion(0.000, 0.000, -0.670, 0.743))  
  45.         locations['hall_bedroom'] = Pose(Point(-3.719, 4.401, 0.000), Quaternion(0.000, 0.000, 0.733, 0.680))  
  46.         locations['living_room_1'] = Pose(Point(0.720, 2.229, 0.000), Quaternion(0.000, 0.000, 0.786, 0.618))  
  47.         locations['living_room_2'] = Pose(Point(1.471, 1.007, 0.000), Quaternion(0.000, 0.000, 0.480, 0.877))  
  48.         locations['dining_room_1'] = Pose(Point(-0.861, -0.019, 0.000), Quaternion(0.000, 0.000, 0.892, -0.451))  
  49.  
  50.         # Publisher to manually control the robot (e.g. to stop it)  
  51.         # 发布控制机器人的消息  
  52.         self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist)  
  53.  
  54.         # Subscribe to the move_base action server  
  55.         # 订阅move_base服务器的消息  
  56.         self.move_base = actionlib.SimpleActionClient("move_base", MoveBaseAction)  
  57.  
  58.         rospy.loginfo("Waiting for move_base action server...")  
  59.  
  60.         # Wait 60 seconds for the action server to become available  
  61.         # 60s等待时间限制  
  62.         self.move_base.wait_for_server(rospy.Duration(60))  
  63.  
  64.         rospy.loginfo("Connected to move base server")  
  65.  
  66.         # A variable to hold the initial pose of the robot to be set by   
  67.         # the user in RViz  
  68.         # 保存机器人的在rviz中的初始位置  
  69.         initial_pose = PoseWithCovarianceStamped()  
  70.  
  71.         # Variables to keep track of success rate, running time,  
  72.         # and distance traveled  
  73.         # 保存成功率、运行时间、和距离的变量  
  74.         n_locations = len(locations)  
  75.         n_goals = 0  
  76.         n_successes = 0  
  77.         i = n_locations  
  78.         distance_traveled = 0  
  79.         start_time = rospy.Time.now()  
  80.         running_time = 0  
  81.         location = ""  
  82.         last_location = ""  
  83.  
  84.         # Get the initial pose from the user  
  85.         # 获取初始位置(仿真中可以不需要)  
  86.         rospy.loginfo("*** Click the 2D Pose Estimate button in RViz to set the robot's initial pose...")  
  87.         rospy.wait_for_message('initialpose', PoseWithCovarianceStamped)  
  88.         self.last_location = Pose()  
  89.         rospy.Subscriber('initialpose', PoseWithCovarianceStamped, self.update_initial_pose)  
  90.  
  91.         # Make sure we have the initial pose  
  92.         # 确保有初始位置  
  93.         while initial_pose.header.stamp == "":  
  94.             rospy.sleep(1)  
  95.  
  96.         rospy.loginfo("Starting navigation test")  
  97.  
  98.         # Begin the main loop and run through a sequence of locations  
  99.         # 开始主循环,随机导航  
  100.         while not rospy.is_shutdown():  
  101.             # If we've gone through the current sequence,  
  102.             # start with a new random sequence  
  103.             # 如果已经走完了所有点,再重新开始排序  
  104.             if i == n_locations:  
  105.                 i = 0  
  106.                 sequence = sample(locations, n_locations)  
  107.                 # Skip over first location if it is the same as  
  108.                 # the last location  
  109.                 # 如果最后一个点和第一个点相同,则跳过  
  110.                 if sequence[0] == last_location:  
  111.                     i = 1  
  112.  
  113.             # Get the next location in the current sequence  
  114.             # 在当前的排序中获取下一个目标点  
  115.             location = sequence[i]  
  116.  
  117.             # Keep track of the distance traveled.  
  118.             # Use updated initial pose if available.  
  119.             # 跟踪形式距离  
  120.             # 使用更新的初始位置  
  121.             if initial_pose.header.stamp == "":  
  122.                 distance = sqrt(pow(locations[location].position.x -   
  123.                                     locations[last_location].position.x, 2) +  
  124.                                 pow(locations[location].position.y -   
  125.                                     locations[last_location].position.y, 2))  
  126.             else:  
  127.                 rospy.loginfo("Updating current pose.")  
  128.                 distance = sqrt(pow(locations[location].position.x -   
  129.                                     initial_pose.pose.pose.position.x, 2) +  
  130.                                 pow(locations[location].position.y -   
  131.                                     initial_pose.pose.pose.position.y, 2))  
  132.                 initial_pose.header.stamp = ""  
  133.  
  134.             # Store the last location for distance calculations  
  135.             # 存储上一次的位置,计算距离  
  136.             last_location = location  
  137.  
  138.             # Increment the counters  
  139.             # 计数器加1  
  140.             i += 1  
  141.             n_goals += 1  
  142.  
  143.             # Set up the next goal location  
  144.             # 设定下一个目标点  
  145.             self.goal = MoveBaseGoal()  
  146.             self.goal.target_pose.pose = locations[location]  
  147.             self.goal.target_pose.header.frame_id = 'map'  
  148.             self.goal.target_pose.header.stamp = rospy.Time.now()  
  149.  
  150.             # Let the user know where the robot is going next  
  151.             # 让用户知道下一个位置  
  152.             rospy.loginfo("Going to: " + str(location))  
  153.  
  154.             # Start the robot toward the next location  
  155.             # 向下一个位置进发  
  156.             self.move_base.send_goal(self.goal)  
  157.  
  158.             # Allow 5 minutes to get there  
  159.             # 五分钟时间限制  
  160.             finished_within_time = self.move_base.wait_for_result(rospy.Duration(300))   
  161.  
  162.             # Check for success or failure  
  163.             # 查看是否成功到达  
  164.             if not finished_within_time:  
  165.                 self.move_base.cancel_goal()  
  166.                 rospy.loginfo("Timed out achieving goal")  
  167.             else:  
  168.                 state = self.move_base.get_state()  
  169.                 if state == GoalStatus.SUCCEEDED:  
  170.                     rospy.loginfo("Goal succeeded!")  
  171.                     n_successes += 1  
  172.                     distance_traveled += distance  
  173.                     rospy.loginfo("State:" + str(state))  
  174.                 else:  
  175.                   rospy.loginfo("Goal failed with error code: " + str(goal_states[state]))  
  176.  
  177.             # How long have we been running?  
  178.             # 运行所用时间  
  179.             running_time = rospy.Time.now() - start_time  
  180.             running_time = running_time.secs / 60.0  
  181.  
  182.             # Print a summary success/failure, distance traveled and time elapsed  
  183.             # 输出本次导航的所有信息  
  184.             rospy.loginfo("Success so far: " + str(n_successes) + "/" +   
  185.                           str(n_goals) + " = " +   
  186.                           str(100 * n_successes/n_goals) + "%")  
  187.             rospy.loginfo("Running time: " + str(trunc(running_time, 1)) +   
  188.                           " min Distance: " + str(trunc(distance_traveled, 1)) + " m")  
  189.             rospy.sleep(self.rest_time)  
  190.  
  191.     def update_initial_pose(self, initial_pose):  
  192.         self.initial_pose = initial_pose  
  193.  
  194.     def shutdown(self):  
  195.         rospy.loginfo("Stopping the robot...")  
  196.         self.move_base.cancel_goal()  
  197.         rospy.sleep(2)  
  198.         self.cmd_vel_pub.publish(Twist())  
  199.         rospy.sleep(1)  
  200.  
  201. def trunc(f, n):  
  202.     # Truncates/pads a float f to n decimal places without rounding  
  203.     slen = len('%.*f' % (n, f))  
  204.     return float(str(f)[:slen])  
  205.  
  206. if __name__ == '__main__':  
  207.     try:  
  208.         NavTest()  
  209.         rospy.spin()  
  210.     except rospy.ROSInterruptException:  
  211.         rospy.loginfo("AMCL navigation test finished.")



原创文章,转载请注明: 转载自古月居

本文链接地址: ROS探索总结(十五)——amcl(导航与定位)

微信 OR 支付宝 扫描二维码
为本文作者 打个赏
pay_weixinpay_weixin

评论

115条评论
  1. Gravatar 头像

    小白菜 回复

    胡老师,您好。我想请问一下,机器人怎么在不事先使用激光SLAM获取地图情况下,就能一般导航定位?也就是说,在第一次构建环境地图的过程中,机器人就能完成定位与路径规划?这种要求能实现吗?,谢谢!

  2. Gravatar 头像

    fish9210 回复

    胡老师,请教您一个问题:我用A2和gmapping来做的建图,底盘控制用的ROSArduinoBridge。同时使用了teleop_twist和一个自己写的程序来键盘控制底盘。在实验过程中,发现一个非常奇怪的现象,当我用键盘控制机器人前后左右移动时,底盘是正常运转的,运动方向也是与预期符合。但是,在rviz中,odom显示的左转或者右转的轨迹,与实际方向相反(前进和后退却是相同的)。也就是说,键盘控制机器人实际在左转,而rviz中的odom轨迹却是在右转。为什么会这样呢?是不是rviz中odom的轨迹,也是按照ROS的右手系来显示的,odom轨迹的Z轴是以逆时针为正方向? 还是其他问题导致的?请您赐教,万分感谢!

  3. Gravatar 头像

    sun tian 回复

    大神,您好。我在做您第九章的实验,图9-15的效果一直出现不了,map选项一直都是no map received。robotmodel和laserscan都是有问题。大神你知道怎么解决吗

  4. Gravatar 头像

    罗西 回复

    月哥,你好 我有两个问题想请教一下 一个是机器人在建图的时候地图的原点是机器人开始建图的那个点吗? 第二个是我有一张建好的无无障碍的空白地图,我用这张地图在导航的时候想让其中的一些区域设置成障碍区 有没有什么办法能实现? 谢谢

    • 古月

      古月 回复

      @罗西 1. 默认是的
      2. 可以用绘图软件GIMP在空白地图上画黑线,就会成为障碍

      • Gravatar 头像

        罗西 回复

        @古月 我在gimp上修改地图之后保存,发现只能保存成xcf的格式,在导航的时候把地图文件换成.xcf文件可以吗?

        • Gravatar 头像

          罗西 回复

          @罗西 刚刚找到了解决方法,自己解决了 ,多谢解答

  5. Gravatar 头像

    steven 回复

    古老师您好,中秋节快乐!我现在有一个应用场景:一开始机器人加载了一个和房间结构相同的静态地图,在房间里导航从起点到达终点。之后在房间里增加一面墙,但是静态地图没有更新,就是说静态地图里是没有后加入这面墙的,然后机器人从起点到终点需要绕过这面墙,当机器人刚绕过后加入这面墙便会找不到自己在哪里了,costmap不是实时更新的么?为什么会找不到自己在哪里呢?把加入那面墙当作障碍物绕过不就可以了么?

    • 古月

      古月 回复

      @steven 我试过类似的功能,相当于动态加入了一个障碍物,但是并不会出现你所说的现象,机器人会绕过障碍物移动到目标点。

      • Gravatar 头像

        steven 回复

        @古月 我又看了一下,最开始是提示“None of the XX first of XX (0) points of the global plan were in the local costmap and free”,然后会开始进行recovery,最后就找到不自己的位置了。前边那个错误提示是什么原因呢?

      • Gravatar 头像

        steven 回复

        @古月 None of the points of the global plan were in the local costmap,global plan points too far from robot
        None of the 117 first of 117 (117) points of the global plan were in the local costmap and free
        None of the 117 first of 117 (117) points of the global plan were in the local costmap and free
        None of the points of the global plan were in the local costmap,global plan points too far from robot
        DWA planner failed to produce path
        Got new plan
        None of the points of the global plan were in the local costmap,global plan points too far from robot
        None of the 107 first of 107 (107) points of the global plan were in the local costmap and free
        None of the 107 first of 107 (107) points of the global plan were in the local costmap and free
        None of the points of the global plan were in the local costmap,global plan points too far from robot
        DWA planner failed to produce path
        Got new plan
        .......
        之后又重复了几次上边类似的报错,然后就是恢复,然后就恢复不了,就停止了

        • 古月

          古月 回复

          @steven 错误提示应该是在本地地图上找不到规划的点,我还没遇到过类似的问题

  6. Gravatar 头像

    王霏 回复

    博主您好,我看着您的书在学习自主导航建图的时候出现一个问题,我使用gazebo和rviz仿真,运行.py文件后,机器人不能识别第一个目标点,并于五分钟后驶向第二个目标点,这是什么原因?
    [INFO] [1536215264.747235, 0.000000]: Waiting for move_base action server...
    [INFO] [1536215264.757513, 388.309000]: Connected to move base server
    [INFO] [1536215264.757686, 388.309000]: Starting navigation test
    [INFO] [1536215264.757954, 388.310000]: Updating current pose.
    [INFO] [1536215264.758135, 388.310000]: Going to: 3
    [INFO] [1536215565.081251, 688.310000]: Timed out achieving goal
    [INFO] [1536215565.081564, 688.311000]: Success so far: 0/1 = 0%
    [INFO] [1536215565.081727, 688.311000]: Running time: 5.0 min Distance: 0.0 m
    [INFO] [1536215567.084418, 690.311000]: Going to: 4

    • 古月

      古月 回复

      @王霏 应该是等待超时了,随机从设定好的坐标中抽取的目标位置,可以修改代码中的坐标值

  7. Gravatar 头像

    lican 回复

    您好,我想请教您一下在机器人启动时加载一张地图,将机器人放在任意位置,能不能根据当前的激光数据获得机器人在地图上的位置?现在在做一个室内机器人,想要确定开机后机器人的初始位置,请问有没有相关的教程推荐?麻烦您了。

    • 古月

      古月 回复

      @lican 这个需要在google找下有没有实现的功能包

        • Gravatar 头像

          α_ω 回复

          @lican 请问您的功能实现了么?我也遇到这个问题了 😐

  8. Gravatar 头像

    beyoungglh 回复

    古月老师,我现在做的机器人需要切换地图,但是切换地图后好像amcl定位会出问题,激光扫描的和地图无法重合,匹配不上,不知道哪里问题,切换地图对amcl有影响吗

    • 古月

      古月 回复

      @beyoungglh 是有影响的,调整一下amcl的参数试试吧,amcl也不能保证一定匹配上

  9. Gravatar 头像

    舒恒 回复

    您好,我最近在用ros导航包,关于amcl我问一下,amcl是发布odom到map的tf,这和最开始odom_map_broadcaster发布的odom到map的固定tf不冲突吗,这两者之间是什么关系?求解,谢谢!!!

    • 古月

      古月 回复

      @舒恒 之前的odom_map_broadcaster是和fake_localization配合使用的,没有用到amcl包,所以自己建立了一个这样的tf。如果调用amcl的话,就不用odom_map_broadcaster了

      • Gravatar 头像

        舒恒 回复

        @古月 不好意思这么晚看到,为什么如果我不发布odom_map_broadcaster 的话 即使启动acml也没法建立完整的tf树,找不到机器人到地图的变换,是不是一开始要发布,后面才取消这个odom_map_broadcaster

        • 古月

          古月 回复

          @舒恒 可以参考《ROS by example》中的例程源码,amcl是可以建立出来tf的连接的,如果实在没有的话,就在launch里加上odom_map_broadcaster试一下,不用取消。

  10. Gravatar 头像

    suixin 回复

    古月老师您好,我在使用zed做机器人导航,在pointcloud_to_laserscan时候总是检测不到摄像头,是什么原因呢,zed源码已经安装好,在ros中rviz上也可以显示点云数据。

    • 古月

      古月 回复

      @suixin pointcloud_to_laserscan是将点云转换成激光数据,你的意思是找不到点云的话题么?检查驱动发布的点云话题名,是不是和pointcloud_to_laserscan配置的输入匹配

      • Gravatar 头像

        suixin 回复

        @古月 谢谢您,真的是这样。

  11. Gravatar 头像

    罗西 回复

    月哥,想问一个问题,我现在用turtlebot3建图的时候发现,建图很模糊,边缘全是小四边形,没有网上实例中的那么清晰,这个问题是不是地图分辨率造成的? 应该怎么调整?

  12. Gravatar 头像

    Drow 回复

    你好古月老师,我现在想publish一下我自己设的点,按照您给的代码publish的话小车会接收吗?我总感觉我自己publish的话题如果不改程序源码的话就不会被订阅吧?但是我想改源码也不知道去哪里改……

    • 古月

      古月 回复

      @Drow movebase包提供了发布目标位置的action接口,通过这个action发布目标,小车是可以接收的

  13. Gravatar 头像

    大力 回复

    博主,您好,我想询问一下,如何修改gmapping和amcl的参数实现仿真机器人一边行走一边建地图。查看文档,修改了use_map_topic参数后还是没效果

    • 古月

      古月 回复

      @大力 请参考《ROS by example》这本书及其源码的配置来做

      • Gravatar 头像

        大力 回复

        @古月 好的,谢谢胡老师。我去看看这本书。自己根据ros wiki上提供的slam和navigation两个案例修改launch文件,把map_server替换掉,用仿真上的激光雷达进行数据采集,rviz上的小车会跳动,navigation部分好像也失效。感觉应该是配置没改完善。

      • Gravatar 头像

        大力 回复

        @古月 我用slam_gmapping代替map_serve动态生成地图,调用amcl和move_base想实现机器人的自动路径规划和避障。貌似amcl不支持动态全局地图,直接报警报:“The origin for the sensor at (0.01, -0.00) is out of map bounds. So, the costmap cannot raytrace for it.”目测需要修改源码之类的才能实现一边自动路径规划一边创建地图。

      • Gravatar 头像

        大力 回复

        @古月 胡老师,我把ros by example上导航的章节和代码跑了,也是用静态地图去实现导航的。不知胡老师还有什么其他推荐吗

        • 古月

          古月 回复

          @大力 ROS社区中关于SLAM的导航的功能包很多,可以google上搜一下,找一个适合自己的,深入开发的话,可能还是会涉及到功能包源码的修改

          • Gravatar 头像

            大力 回复

            @古月 好的,非常感谢胡老师,找了许久,目测没有可以直接用的,应该需要改源码才能实现。

          • Gravatar 头像

            大力 回复

            @古月 胡老师,我调出来了,不需要改代码,直接把map_server和amcl去掉即可(之前全局地图改成动态的,结果老是抖动,保留原有设置为静态就好)。通过快捷P在rviz上发布goal没法相应,但是通过手动pub可以实现。

  14. Gravatar 头像

    回复

    您好,请问一下amcl估计的实时位姿坐标可以提取出来吗,或者说发布到一个topics上?

    • 古月

      古月 回复

      @航 本来就是有的,amcl_pose,参考:http://wiki.ros.org/amcl

      • Gravatar 头像

        回复

        @古月 谢谢您,目前我在做导航时遇到一个问题,[WARN】Could not get transform ,irgnoring laser scan! Lookup would require extrapolation into the past.请问是什么情况,怎么解决?

        • 古月

          古月 回复

          @航 可能是激光雷达的数据或坐标系更新慢

  15. Gravatar 头像

    知者 回复

    您好,我图已经建好保存了,运行导航的lanuch时候提示ERROR: cannot launch node of type [amcl/amcl]: can't locate node [amcl] in package [amcl]
    但我安装了amcl。。。问下,什么问题

    • 古月

      古月 回复

      @知者 在ros安装目录里找找amcl,确定是否安装成功了

  16. Gravatar 头像

    栾宇思 回复

    古月老师,您好!我想向您请教一个问题。就是基于已有地图定位,机器人的动态地图与已知的静态地图不匹配,只能靠手动进行匹配,如何做到自动匹配呢?

      • Gravatar 头像

        栾宇思 回复

        @古月 初始状态 使用了amcl 初始状态只能使用2D Pose Estimate来进行位姿矫正

        • 古月

          古月 回复

          @栾宇思 初始状态只能用2D Pose Estimate校正,或者修改地图匹配的yaml文件

          • Gravatar 头像

            栾宇思 回复

            @古月 老师,如果使用2D Pose Estimate校正后,在小车导航过程中渐渐出现了动态地图与静态地图不匹配的问题,那这个问题有什么比较好的解决办法呢?
            如果AGV用到工业现场中,难道每次初始状态都要手动校准位姿吗?

            • 古月

              古月 回复

              @栾宇思 用amcl可以达到一定匹配的功能,或者找下有没有其他类似的功能包。ROS这些功能包可以实现基础功能,但是问题也会很多,不可能直接应用的,很多功能都需要我们自己开发或者基于原有的代码优化。

  17. Gravatar 头像

    zjh33car 回复

    古老师,怎么您网站里里多个帖子的图片都看不了?都是一个×,显示不不出来呢

    • 古月

      古月 回复

      @zjh33car 之前csdn的图片都不让转了,就消失了,有时间我再加上去吧,暂时可以先看我csdn上的博文,内容一样的

  18. Gravatar 头像

    邹调清 回复

    请问一下,我在校准了轮子的里程计之后,再加上imu,但是在建图过程中发现底盘在跑了一段时间后,imu的坐标会有一个不小的漂移,直接影响建图效果,希望古月你能指导一下,大概是什么原因?

    • 古月

      古月 回复

      @邹调清 数据融合的问题吧,imu的加入应该是可以提减少里程计的误差的,但是需要通过滤波的方式把数据做融合

  19. Gravatar 头像

    夏至 回复

    胡老师,您好,我用hector slam跑的图做fake move base的时候,我看图上路径能规划出来,但机器实际跑的时候就乱跑了,这为什么呢?盼复~

    • 古月

      古月 回复

      @夏至 那就是本地规划器有问题了,检查一下这部分的参数设置,另外还有传感器的状态

  20. Gravatar 头像

    kk 回复

    请问,这个导航功能包navigation能用在无人机上进行自主导航和路径规划吗?目前我只知道有mavros这个package用于ros系统与飞控之间的通信,后面就不是很清楚了,希望月神给点指导

    • 古月

      古月 回复

      @kk move_base是用于平面机器人的,不能用于无人机,但是ROS中有针对无人机的功能包,这方面我不了解,你可以在google上找找

  21. Gravatar 头像

    罗西 回复

    月哥,想问一下,怎么把你的例子中的黄色箭头调出来,我按照教程上的来,模型能动,但是没有箭头。 谢谢

      • Gravatar 头像

        罗西 回复

        @古月 谢谢月哥 要是想编辑修改已经地图,就是.pgm文件,可以用什么编辑器?

          • Gravatar 头像

            罗西 回复

            @古月 月哥,我在<>中关于点云数据的部分,里面的点云数据存在.pcd文件中的,我想把建图的.pgm或者数据包转化成点云数据后,做后面的匹配算法,分割算法,想问一下应该如何操作,谢谢

              • Gravatar 头像

                罗西 回复

                @古月 这样啊 好的 谢谢额,再有问题再来请教

                • Gravatar 头像

                  罗西 回复

                  @罗西 月哥,有个问题 我想在我安装的ros中看看move——base包底层的算法程序,但是找了半天没找到,想问一下在哪里能找到?

                  • 古月

                    古月 回复

                    @罗西 安装的ros是没有源码的,需要去github或wiki上找

  22. Gravatar 头像

    study ROS 回复

    古大神,您好,我在学习导航这部分内容的时候,从github上下载的Navigation包在编译的时候出现如下错误:
    CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
    Could NOT find SDL (missing: SDL_LIBRARY SDL_INCLUDE_DIR)
    那么这个SDL是要额外装,还是怎么弄,查了很多资料都没有找到很好的解决办法!希望古大神,指导我一下!

    • 古月

      古月 回复

      @study ROS 参考:https://github.com/ros-planning/navigation/issues/579,
      其中有安装方法

      • Gravatar 头像

        study ROS 回复

        @古月 古大神,我按照您给的这个网址去安装,出现了:下列软件包有未满足的依赖关系:
        libsdl1.2-dev : 依赖: libpulse-dev 但是它将不会被安装
        E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系
        然后我就根据sudo apt-get install libpulse-dev往下安装,之后就出现了:下列软件包有未满足的依赖关系:
        libpulse-dev : 依赖: libpulse0 (= 1:8.0-0ubuntu3) 但是 1:8.0-0ubuntu3.4 正要被安装
        依赖: libpulse-mainloop-glib0 (= 1:8.0-0ubuntu3) 但是 1:8.0-0ubuntu3.4 正要被安装
        按照它的要求我安装这些依赖后,再去安装之前的libsdl1.2-devel,还是装不上,我就开始查找,说了各种换服务器啊什么的,就是装不上请问这是什么情况,具体怎么解决?请指教一下,非常感谢!

          • Gravatar 头像

            study ROS 回复

            @古月 多谢古老师,上次的错误解决了。最近又遇到一个问题,在编译pr2机器人的moveit_tutorials这个包的过程中,出现了:
            cannot convert ‘moveit::planning_interface::MoveItErrorCode’ to ‘bool’ in initialization
            bool success = move_group.plan(my_plan);
            ^
            就是有bool常量声明的地方,都出现这种错误,这是怎么回事,怎么才能解决呢?

            • 古月

              古月 回复

              @study ROS 返回值是moveit::planning_interface::MoveItErrorCode,不是bool

  23. Gravatar 头像

    James 回复

    老师您好,请教您一个问题。我用cartographer跑离线的数据包,怎么将跑出来的栅格地图保存下来呢???

    • 古月

      古月 回复

      @James 用这个命令试试:rosservice call /finish_trajectory "map",默认生成的地图在.ros文件夹里

  24. Gravatar 头像

    罗盼 回复

    博主您好!我看了您的这篇博文,和我的问题有点类似,请问如果我在已知的地图上框选了一块区域,要在该区域内提取一些无碰撞点,然后让机器人在这些点上进行遍历,请问有什么好的方法吗?谢谢解答

    • 古月

      古月 回复

      @罗盼 您好,我没做过这样的功能,不知使用类似粒子采样的方法行不行,在指定区域内选择很多点,然后尝试是否可以导航规划,再把障碍点删掉。

  25. Gravatar 头像

    大宇 回复

    博主你好:
    从8月份开始入ROS的坑,一直在看您的博客,收获颇丰。我想像您咨询一下,amcl算法是否可以更改,如果可以我需要从什么地方进行更改(amcl的代码在哪改)?还有这一方面的算法除了看概率机器人,您还有别的推荐吗?感激不尽

    • 古月

      古月 回复

      @大宇 amcl相关的代码可以从github上下载,wiki上可以找到;关于该功能包的源码算法,我就不清楚了,如果可以搞明白代码,修改肯定是没问题的

      • Gravatar 头像

        大宇 回复

        @古月 好的明白了,谢谢大神。假如我算法改完了需要验证,我该如何让机器人执行我更改后的算法,我修改后的算法应该放到什么地方?

        • 古月

          古月 回复

          @大宇 不客气,如果直接在已有功能包的源码上修改,把环境变量设置后,验证的时候运行修改之后的功能包就行

  26. Gravatar 头像

    王翰 回复

    古大神:
    我再基于地图运行AMCL的时候,慢速的行走可以匹配的很好,定位也很好,但是一转,就无法匹配了,但是建图的时候,都没有什么问题,导航也挺好的,我想定位好之后导航,但是基于地图的,就是一直弄不好,大神有什么建议吗?
    谢谢

    • 古月

      古月 回复

      @王翰 首先要校准里程计,尤其是在旋转时,如果单一传感器效果不好的话,可能需要考虑加入姿态传感器,amcl支持多信息源的输入进行融合

  27. Gravatar 头像

    Peggy 回复

    我的地图是激光雷达扫描获取的,我要怎么进行这一步导航和定位呢?

    • 古月

      古月 回复

      @Peggy 很多书上有现成的案例,在launch文件里加载自己的地图即可

    • Gravatar 头像

      summer 回复

      @Peggy 我看你用的激光,是3D的吗?UDP解析,ros里有用于解析UDP的库吗?

  28. Gravatar 头像

    齐欢 回复

    你好!请问怎么调低turtlebot在自主导航时的行驶速度,感觉有点太 😉 快

    • Gravatar 头像

      齐欢 回复

      @齐欢 已经知道了不用了

  29. Gravatar 头像

    Dasrio 回复

    博主你好,我想问下rviz里面的map,global map,local map有什么区别,为什么我用map_server载入我自己的地图之后,map中的地图是官方demo地图,而global map才是我自己的地图呢?

  30. Gravatar 头像

    小咔星 回复

    我也是在做绘制地图,不过要求在绘制过程中检测到规定的图片后在该位置画出一个图形进行标记,我的思路是检测到图片后发布一个话题,然后接收后在地图中小车当前位置标记,不过我不知道怎么得到小车在地图中当前的坐标,博主能指点一下吗

  31. Gravatar 头像

    hoshi 回复

    大神,请问这种昂贵的激光传感器还有什么替代品么,因为还只是学生,所以经费有限。如果实在不能用别的替代,可以用ros手动绘制地图么?谢谢大神~期待您的回复

    • 古月

      古月 回复

      @hoshi 可以用Kinect,几百块钱,在淘宝上就可以买到。ROS生成的栅格地图也是可以手动绘制的,用图片编辑软件就可以。另外,也可以使用gazebo仿真激光传感器,零成本

  32. Gravatar 头像

    周志敏 回复

    古大神你好,我通过sudo apt-get install ros-indigo-navigation安装了move_base, gmapping和map_server等一系列跟SLAM相关的安装包,不过不知道为什么我这边的map_server安装包有问题,我输入rosrun map_server map_server的时候提示我couldn't find executable named map_server,我在launch file里面想要launch也不行,提示我can't locate node map_server in package map_server。ps:我用roscd map_server是可以进入到map_server包的。这个问题卡住我好久了。。古大神你知道怎么回事吗?

    • Gravatar 头像

      周志敏 回复

      @周志敏 ps:我也是在看ros by example这个教程,然后看到第八章,要输入指令roslaunch rbx1_nav fake_move_base_blank_map.launch的时候提示出错

    • Gravatar 头像

      ncnynl 回复

      @周志敏 rosrun map_server 你是保存地图的话,应该是map_saver

    • Gravatar 头像

      jack 回复

      @周志敏 你的问题解决了吗 我也遇到跟你一样的问题了 不过我用的是 map_saver

  33. Gravatar 头像

    柚子Betty 回复

    博主,你好,最近开始接触SLAM,进而知道ROS,想问下ROS里面的explore package能不能进行自主探索,而不是人为操作机器人进行地图构建?

    • 古月

      古月 回复

      @柚子Betty 可以实现,机器人可以在SLAM的过程中自主避障,可以参考ROS wiki中的huskey机器人仿真,有实现类似的功能

  34. Gravatar 头像

    浪迹江北 回复

    博主您好,我最近在看您的博客文章。环境Ubuntu14.04 + ROS (Indigo)。运行 roslaunch rbx1_nav fake_amcl.launch map:=test_map.yaml 报错
    [move_base-2] process has died [pid 3741, exit code -11, cmd /home/ntrqz/rbe_ws/devel/lib/move_base/move_base __name:=move_base __log:=/home/ntrqz/.ros/log/9ccff348-2928-11e6-a5ce-20689de2cfb9/move_base-2.log].
    log file: /home/ntrqz/.ros/log/9ccff348-2928-11e6-a5ce-20689de2cfb9/move_base-2*.log
    这种错误要怎么弄,求博主点拨啊。

  35. Gravatar 头像

    黄建辉 回复

    博主你好
    运行 roslaunch rbx1_nav fake_amcl.launch map:=test_map.yaml
    出错
    [move_base-2] process has died [pid 31982, exit code -11, cmd /home/ntrqz/rbe_ws/devel/lib/move_base/move_base __name:=move_base __log:=/home/ntrqz/.ros/log/e6b53aec-289f-11e6-928f-20689de2cfb9/move_base-2.log].
    这个是什么情况?
    log file: /home/ntrqz/.ros/log/e6b53aec-289f-11e6-928f-20689de2cfb9/move_base-2*.log

  36. Gravatar 头像

    QuanQhow 回复

    博主你好,我在用Learning ROS for Robotics Programming 第二版书的代码创建地图时候运行rosrun map_server map_saver -f map
    出现错误:
    Waiting for the map
    而且在rviz中显示warn:no map received.我的QQ841691229,可以加个好友一起交流下吗?谢谢!

    • 古月

      古月 回复

      @QuanQhow 这个命令是用来保存建立好的地图,你的地图已经建立完毕了么?

  37. Gravatar 头像

    郑锐钊 回复

    您好,我是最近开始学习ROS的,用的是indigo的版本。我看了您的教程,收获颇丰。在这里向请教一个问题。
    我是自己兴趣学习的ROS,所以按照《ROS机器人程序设计》这本书里的教程和参考网上的各种资料在学习,但是在学习的到地图构建部分,需呀奥用到激光雷达传感器,如果不买设备,只是使用仿真的话,能够在仿真软件中获取到数据吗?
    我使用的是gazebo仿真,激光雷达能够仿真出来,但是我不清楚是否能够正常收集到数据,还有如何在rviz中得到地图?

    • 古月

      古月 回复

      @郑锐钊 可以的,在gazebo中可以仿真激光传感器,和真实设备的使用一样。使用gamapping可以在rviz中看到地图。

      • Gravatar 头像

        郑锐钊 回复

        @古月 能否出一个简单的教程呢?

        • 古月

          古月 回复

          @郑锐钊 后续有时间可能会总结一下这部分内容,你可以先参考一下《Mastering ROS for RoboticsProgramming》

          • Gravatar 头像

            郑锐钊 回复

            @古月 恩恩。非常感谢!再请教一个问题,如果我的机器人在启动时加载进一张地图,那我如何确定机器人启动时是位于地图中的哪个位置?关于这方面的,是否有哪些教程或者方法推荐。

            • 古月

              古月 回复

              @郑锐钊 每个地图都有一个配置文件,里边可以设置机器人的初始位置,默认就是建图时的原点位置

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据