Ros:people包下子包leg_detector及其相关包笔记

people包下的leg_detector(http://wiki.ros.org/leg_detector)用于通过激光数据检测人腿。大致过程是对每一帧激光(scan)数据,先进行分割,分成多个数据段,然后计算这些数据段的特征,如半径,曲率,中心点之类的,并用这些数据通过训练好的随机森林进行判断当前数据段是否人腿。之后用卡尔曼滤波器跟踪估计每一帧同一条腿的位置,并按两条腿匹配成一个人配对出人。

该包年代久远,而且作者并没有写任何wiki任何使用方法,并且最初用于训练的数据集已经丧失(其维护者在Q&A中提到),只留下了训练好的yaml文件,因而调试起来比较浪费时间。本文对此包做一定解释,便于后续使用者调试(虽然甚至不一定有人看)。嘛,也当做笔记了。

环境:Ubuntu14.04,ros版本:indigo, opencv是indigo自带的(反正是2的哪个版本, 目前测试了2.4.13.6,或者2.4.11是可以的


 leg_detector(以下为包内文件夹)

  • cfg:存放leg_detector.cpp所用动态配置文件
  • config:存放随机森林训练出来的结果yaml文件
  • include:头文件
  • launch:有3个launch文件,但基本只用leg_detector.launch(另外两个我并没看所以不写了)
  • src:源文件

 

launch文件解析:

  • leg_detector.launch:

        启动leg_detector节点,并将话题”/scan“映射为”/base_scan“,将所用的yaml文件(训练好的随机森林)指向config文件夹内的那个。(实际上大多数激光驱动发布的话题都是"/scan",所以可以不用那个映射。总之目的是让leg_detector订阅的激光数据话题名与激光发布的话题名一致。)

        要注意的是直接启动这个和激光节点还是不能正确运行,因为还需要激光的frame到里程计的frame: odom_combined的tf变换才可以。详细的会在leg_detector.cpp解释。

 

cpp文件解析:

  • calc_leg_feature.cpp::计算一个数据段(不是一帧scan数据,是scan数据进行切割以后得到的小段)中的十几个特征值,用于检测
  • laser_processor.cpp: 处理一帧scan数据所需函数
  • train_leg_detector.cpp:训练yaml文件用的cpp,但是里面的ros::recorder被ros弃用了(好像),改成了rosbag(应该说合并进去吧),通过不了编译(简单来说就是我不会调),故这个文件暂时无法使用。我对其进行了修改,修改后的东西查看:https://blog.csdn.net/rezrezre/article/details/88380962。当然不是说自带的训练出来的yaml不能用,只是它训练时雷达是在距地面30cm处的,如果你的雷达高度不一样那效果可能不太好,可以尝试自己采数据训练。
  • leg_detector.cpp:检测人腿,包含2只腿匹配出一个人的过程,有个叫use_seed的模式,此模式下会调用peole_tracking_filter包(好像是用滤波器得到人的最优估计位姿),但是目前不会用(因为某个订阅器订阅的话题信息类型与发布到之中的话题类型不统一(发布那个被作者改了,然后订阅的又没改回去),总之Q&A里维护者也指出了这个问题,暂时没想着解决。)

 

leg_detector使用:

        leg_detector中激光雷达信息被订阅之后,还要找到激光信息的frame到里程计的frame:”/odom_combined“ 的tf变换,才能进入回调函数"laserCallback"正常工作。(激光的frame就是激光数据(laserscan类型)的header.frame_id)。需要自己写一个tf变换发布器发布这两个frame之间的变换。大概就这样就行:

(laser_odom_tf.py)

#!/usr/bin/env python  
# -*- coding: utf-8 -*-
import rospy
import tf

if __name__ == '__main__':
    rospy.init_node('odom_laser_tf_broadcaster')
    
    laser_frame_name=rospy.get_param("~laser_frame_id","laser")  # /scan 话题的消息的frame名字
    odom_frame_name=rospy.get_param("~odom_frame_id","/odom_combined")  # leg_detector要能找到/scan话题的frame与/odom_combined的tf变换,这里直接发布这个变换

    br = tf.TransformBroadcaster()
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        br.sendTransform((0.3, 0.0, 0.1),
                            (0.0, 0.0, 0.0, 1.0),
                            rospy.Time.now(),
                            laser_frame_name,
                            odom_frame_name)  # 站在odom看laser

        rate.sleep()

然后launch文件启动leg_detector, tf变换发布器,和激光即可:

(laser_odom_tf.py被我放在新建的leg_detection包里)



  
  
    
  


    
  
    
    
  

  
  
  

  
  


想用use_seeds直接改launch文件里use_seeds的值改为true即可,但是会报错,因为同一个话题的数据类型不一样。总之没调好,改成true也莫得用。

 

如果想用rosbag录制的数据来代替激光的话:



  
  
  
  

  
  
    
    
  

  
  
  
  
  
  


把第四行的xxx改成录制下来的.bag文件的路径即可


 people_velocity_tracker:

         用于跟踪预测人的速度大小及方向,需配合leg_detector使用,启动方法直接参考该包的launch文件,加3句话进上述launch文件即可。但该包通过编译还要wu_ros_tools包(http://wiki.ros.org/wu_ros_tools?distro=melodic)中的easy_markers包和kalman_filter包


 people_tracking_filter:

        被leg_detector的use_seeds模式调用的东西,有问题用不了


people_msgs:

        people包所用的各种message类型的定义


RVIZ设定:

        打开rviz

        先将Global Option的Fixed Frame 改成odom_combined,  点击add添加laserscan类型数据,topic设为”/scan“; 点击add添加Marker类型数据,topic设为”/visualization_marker“。

       

你可能感兴趣的:(ROS,ubuntu,ros,leg_detector)