Gazebo与ros_control(1):让模型动起来
learningros
learningros 16596 2
2016-08-01 17:47
组图

    版权声明:本文为博主原创文章,如需转载,有劳您注明出处,谢谢O(∩_∩)O~

    http://blog.csdn.net/yaked/article/details/51412781


    图片:20160515120753192.jpg

    图片:20160515120035346.jpg

    图片:20160515115921970.jpg

    图片:20160515115840657.jpg


    不久前,师弟问了我一个问题:“师兄,我要控制一个机器人在仿真环境下运动,需要学什么,或者从哪里入手呢?“
    这个问题不是那么好回答,urdf——Gazebo——ros_control——MoveIt,这是我在很久后才能给出的一个答案。那么之前我是怎么做仿真的呢?

    1. 借助Arbotix舵机接口来仿真



    之前是在学习《ros by example volume 2 》的时候,接触到一个rbx2_bringup 的package,仿照着里面的https://github.com/pirobot/rbx2/blob/indigo-devel/rbx2_bringup/launch/pi_robot_with_gripper.launch 文件写了一个关于youbot的关节的,另外加上一些static_tf转换。
    内容如下



    [html] view plain copy
    1. <launch>  
    2.   <!-- Make sure we are not using simulated time -->  
    3.   <param name="/use_sim_time" value="false" />  
    4.  
    5.   <!-- Launch the arbotix driver in fake mode by default -->  
    6.   <arg name="sim" default="true" />  
    7.  
    8.    <!-- If using a real controller, look on /dev/ttyUSB0 by default -->  
    9.   <arg name="port" default="/dev/ttyUSB0" />  
    10.  
    11.   <!-- Load the URDF/Xacro model of our robot -->  
    12.   <param name="robot_description" command="$(find xacro)/xacro.py '$(find youbot_description)/robots/youbot.urdf.xacro'" />  
    13.   <param name="use_gui" value="true"/>  
    14.  
    15.   <node name="rviz" pkg="rviz" type="rviz" />  
    16.  
    17. <!--   <include file="$(find urdf_tutorial)/launch/display.launch" />-->  
    18.  
    19.   <!-- Bring up the arbotix driver with a configuration file appropriate to the robot -->  
    20.   <node name="arbotix" pkg="arbotix_python" type="arbotix_driver" clear_params="true" output="screen">  
    21.      <rosparam file="$(find rbx2_bringup)/config/fake_youbot_arbotix.yaml" command="load" />  
    22.      <param name="sim" value="$(arg sim)" />  
    23.      <param name="port" value="$(arg port)" />  
    24.   </node>  
    25.  
    26.   <!-- Run a separate controller for the one sided gripper -->  
    27.   <node name="right_gripper_controller" pkg="arbotix_controllers" type="gripper_controller" output="screen">  
    28.      <rosparam>  
    29.         model: dualservo  
    30.         min_opening: 0.0  
    31.         max_opening: 0.009  
    32.         invert_left: false  
    33.         invert_right: false  
    34.         center_left: 0.0  
    35.         center_right: 0.0  
    36.         pad_width: 0.015  
    37.         finger_length: 0.04  
    38.         joint_left: gripper_finger_joint_l  
    39.         joint_right: gripper_finger_joint_r  
    40.      </rosparam>  
    41.   </node>  
    42.  
    43.   <!-- Publish the robot state -->  
    44.   <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher">  
    45.       <param name="publish_frequency" type="double" value="20.0" />  
    46.   </node>  
    47.  
    48. <!--   <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />-->  
    49.  
    50.   <!-- Start all servos in a relaxed state -->  
    51.   <node pkg="rbx2_dynamixels" type="arbotix_relax_all_servos.py" name="relax_all_servos" unless="$(arg sim)" />  
    52.  
    53.   <!-- Load diagnostics -->  
    54.   <node pkg="diagnostic_aggregator" type="aggregator_node" name="diagnostic_aggregator" clear_params="true" unless="$(arg sim)">  
    55.      <rosparam command="load" file="$(find rbx2_dynamixels)/config/dynamixel_diagnostics.yaml" />  
    56.   </node>  
    57.  
    58.   <node pkg="rqt_robot_monitor" type="rqt_robot_monitor" name="rqt_robot_monitor" unless="$(arg sim)" /><!-- Unless value evaluates to false then include tag and its contents,inverse with if  -->  
    59.  
    60. <!--   http://wiki.ros.org/tf#static_transform_publisher-->  
    61. <!--yaw is rotation about Z, pitch is rotation about Y, and roll is rotation about X frame_id child_frame_id-->  
    62.   <!-- Run a static transform between /base_link and /base_footprint needed for SLAM -->  
    63.  <node pkg="tf" type="static_transform_publisher" name="wheel_link_fl2base_link" args="0.228 0.158 -0.034 0 0 0 /base_link /wheel_link_fl 100" />  
    64.  <node pkg="tf" type="static_transform_publisher" name="wheel_link_fr2base_link" args="0.228 -0.158 -0.034 0 0 0 /base_link /wheel_link_fr 100" />  
    65.  <node pkg="tf" type="static_transform_publisher" name="wheel_link_bl2base_link" args="-0.228 0.158 -0.034 0 0 0 /base_link /wheel_link_bl 100" />  
    66.  <node pkg="tf" type="static_transform_publisher" name="wheel_link_br2base_link" args="-0.228 -0.158 -0.034 0 0 0 /base_link /wheel_link_br 100" />  
    67.  
    68.  <node pkg="tf" type="static_transform_publisher" name="caster_link_fl2base_link" args="0.228 0.158 -0.034 0 0 0 /base_link /caster_link_fl 100" />  
    69.  <node pkg="tf" type="static_transform_publisher" name="caster_link_fr2base_link" args="0.228 -0.158 -0.034 0 0 0 /base_link /caster_link_fr 100" />  
    70.  <node pkg="tf" type="static_transform_publisher" name="caster_link_bl2base_link" args="-0.228 0.158 -0.034 0 0 0 /base_link /caster_link_bl 100" />  
    71.  <node pkg="tf" type="static_transform_publisher" name="caster_link_bf2base_link" args="-0.228 -0.158 -0.034 0 0 0 /base_link /caster_link_br 100" />  
    72.  
    73. </launch>  



    它加载的yaml文件内容如下



    [python] view plain copy
    1. port: /dev/ttyUSB0  
    2. baud: 115200  
    3. rate: 20  
    4. sync_write: True  
    5. sync_read: True  
    6. read_rate: 20  
    7. write_rate: 20  
    8.  
    9. joints: {  
    10. #    wheel_joint_fl: {id: 1, neutral: 512, max_speed: 684, min_angle: 0, max_angle: 360, invert: False},  
    11. #    wheel_joint_fr: {id: 2, neutral: 512, max_speed: 684, min_angle: 0, max_angle: 360, invert: False},  
    12. #    wheel_joint_bl: {id: 3, neutral: 512, max_speed: 684, min_angle: 0, max_angle: 360, invert: False},  
    13. #    wheel_joint_br: {id: 4, neutral: 512, max_speed: 684, min_angle: 0, max_angle: 360, invert: False},  
    14.      
    15.    wheel_joint_fl: {id: 1, neutral: 512, max_speed: 684, invert: False},  
    16.    wheel_joint_fr: {id: 2, neutral: 512, max_speed: 684, invert: False},  
    17.    wheel_joint_bl: {id: 3, neutral: 512, max_speed: 684, invert: False},  
    18.    wheel_joint_br: {id: 4, neutral: 512, max_speed: 684, invert: False},  
    19.      
    20.    arm_joint_1: {id: 5, neutral: 512, max_speed: 684, min_angle: -169, max_angle: 169, invert: False},  
    21.    arm_joint_2: {id: 6, neutral: 512, max_speed: 684, min_angle: -65, max_angle: 90, invert: False},  
    22.    arm_joint_3: {id: 7, neutral: 512, max_speed: 684, min_angle: -151, max_angle: 146, invert: False},  
    23.    arm_joint_4: {id: 8, neutral: 512, max_speed: 684, min_angle: -102.5, max_angle: 102.5, invert: False},  
    24.    arm_joint_5: {id: 9, neutral: 512, max_speed: 684, min_angle: -167.5, max_angle: 167.5, invert: False},  
    25.      
    26.    gripper_finger_joint_l: {id: 10,neutral: 512, max_speed: 684, invert: False},  
    27.    gripper_finger_joint_r: {id: 11,neutral: 512, max_speed: 684,  invert: False}  
    28. }  
    29. #http://wiki.ros.org/arbotix_python  
    30. controllers: {  
    31.   #  Pololu motors: 1856 cpr = 0.3888105m travel = 4773 ticks per meter (empirical: 4684) WheelRadius_[meter] = 0.0475 EncoderTicksPerRound = 4000  
    32.    base_controller: {type: diff_controller, base_frame_id: base_link, base_width: 0.38, ticks_meter: 4684, Kp: 50, Kd: 0, Ki: 20, Ko: 50, accel_limit: 1.0 },  
    33.    arm_controller: {type: follow_controller, joints: [arm_joint_1, arm_joint_2, arm_joint_3, arm_joint_4, arm_joint_5], action_name: arm_1/arm_controller/follow_joint_trajectory}  
    34. # rbx2/rbx2_dynamixels/config/arbotix/pi_robot_with_gripper.yaml    
    35. #    arm_controller: {type: follow_controller, joints: [right_arm_shoulder_pan_joint, right_arm_shoulder_lift_joint, right_arm_shoulder_roll_joint, right_arm_elbow_flex_joint, right_arm_forearm_flex_joint], action_name: arm_1/arm_controller/follow_joint_trajectory}  
    36. }  
    启动后,运行起来的节点图


    图片:20160514220406815.jpg


    如果用这个仿真,很大程度上是有问题的,虽然也能够让模型动起来,主要是因为Arbotix是针对舵机的,而实际中很多的机器人不只是舵机,也有步进电机等等。我们的KUKA youBot机械臂是步进电机。以前的仿真中主要用的是follow_joint_trajectory action topics。而实际的youbot_driver也会启动这个topic,所以格式方面,仿真中能够用的,实际也可以直接用上,最大的问题是,仿真的参数与实际动作的相似度有有多少,这里是有个很大的问号的。

    2. 借助Moveit


    关于Moveit之前研究过一段时间,也总结成了三篇博客。
    在利用命令roslaunch moveit_setup_assistant setup_assistant.launch 配置好一些config文件后。要控制实际的机器人,我们还得自己设置一个~/catkin_ws/src/moveit_youbot/config/controllers.yaml的配置文件,我的配置如下



    [plain] view plain copy
    1. controller_list:  
    2.  - name: arm_1/arm_controller  
    3.    action_ns: follow_joint_trajectory  
    4.    type: FollowJointTrajectory  
    5.    default: true  
    6.    joints:  
    7.      - arm_joint_1  
    8.      - arm_joint_2  
    9.      - arm_joint_3  
    10.      - arm_joint_4  
    11.      - arm_joint_5  
    从这里也可以看出,它也是用的Action接口来达到控制的目的的。搜索过一些资料后发现好像还真没其他的配置的方法,基本都是用action来做的。


    其实根据youbot实际的Driver

    图片:20160514223859438.jpg


    我还尝试过这样的配置,为的是只使用/arm_1/arm_controller/position_command这个topic,而非action。也有网上的资料说那个type是ros_controller的type,而它又是与Gazebo相关的。在这里我设置的是topic 的type



    [plain] view plain copy
    1. controller_list:  
    2.  - name: arm_1/arm_controller/position_command  
    3.    type: brics_actuator/JointPositions  
    4.    default: true  
    5.    joints:  
    6.      - arm_joint_1  
    7.      - arm_joint_2  
    8.      - arm_joint_3  
    9.      - arm_joint_4  
    10.      - arm_joint_5  
    ~/catkin_ws/src/moveit_youbot/launchyoubot_moveit_controller_manager.launch.xml 则如下:





    [plain] view plain copy
    1. <launch>  
    2.  <arg name="moveit_controller_manager" default="moveit_simple_controller_manager/MoveItSimpleControllerManager"/>  
    3. <!--  <arg name="moveit_controller_manager" default="moveit_ros_control_interface/MoveItControllerManager"/>-->  
    4.  <param name="moveit_controller_manager" value="$(arg moveit_controller_manager)"/>  
    5.  
    6.  <rosparam file="$(find moveit_youbot)/config/controllers.yaml"/>  
    7.  
    8. </launch>  

    图片:20160514231740043.jpg




    貌似也只能使用MoveItSimpleControllerManager了。根据这里的说明点击打开链接。它提供action的接口,绕了个路还是回到了action。也就是这种方式貌似是行不通。

    3. Gazebo与ros_control


    很久之前学习Gazebo的时候,那个官方tutorial的rrbot,2自由度连杆机器人,结合rqt的一些工具联合调pid,现在依然印象深刻,视频地址点击打开链接。不过当时没太深入,现在随着积累的东西多了,慢慢又会回头看看以前的东西,总有新的收获。而这次则主要是关于ros_control。这里我会先跑一遍官方的例子,然后结合youBot的相关文件来对比说明。
    整理了一下,基本上按照这几个地方就好,按照顺序跑一遍:
    1. http://gazebosim.org/tutorials?tut=ros_roslaunch
    2. http://gazebosim.org/tutorials/?tut=ros_urdf
    3. http://gazebosim.org/tutorials?tut=ros_gzplugins
    4. http://gazebosim.org/tutorials/?tut=ros_control

    其中涉及urdf的相关知识,具体参考查看roswiki, http://wiki.ros.org/urdf/XML
    官方package的目录结构如下

    图片:20160515150923094.jpg


    这里,我主要是想说说plugin和ros_control,介绍可以看看http://wiki.ros.org/ros_control,开头的那个PPT很不错,可以有个大概了解。


    图片:20160515114012791.jpg

    ros_control主要是提供各种controller和Hardware硬件抽象层,而实体机器人或者仿真部件就是其控制的资源,它用来连接它们

    图片:20160515114617369.jpg


    下面就结合具体的官方代码来分析下,是如何让仿真中的模型动起来的。首先~/catkin_ws/src/gazebo_ros_demos/rrbot_description/urdf/rrbot.xacro文件定义了两个运动关节的transmission,它的type是:transmission_interface/SimpleTransmission,它的hardwareInterface是:EffortJointInterface



    [html] view plain copy
    1. <transmission name="tran1">  
    2.  <type>transmission_interface/SimpleTransmission</type>  
    3.  <joint name="joint1">  
    4.    <hardwareInterface>EffortJointInterface</hardwareInterface>  
    5.  </joint>  
    6.  <actuator name="motor1">  
    7.    <hardwareInterface>EffortJointInterface</hardwareInterface>  
    8.    <mechanicalReduction>1</mechanicalReduction>  
    9.  </actuator>  
    10. </transmission>  

    接着~/catkin_ws/src/gazebo_ros_demos/rrbot_description/urdf/rrbot.gazebo里有一些传感器的pluginlibgazebo_ros_control.solibgazebo_ros_gpu_laser.solibgazebo_ros_camera.sohokuyo激光雷达的如下,也就是说即使没有传感器,也可以仿真得到传感器的数据。





    [html] view plain copy
    [list=1]
  • <gazebo reference="hokuyo_link">  
  •   <sensor type="gpu_ray" name="head_hokuyo_sensor">  
  •     <pose>0 0 0 0 0 0</pose>  
  •     <visualize>false</visualize>  
  •     <update_rate>40</update_rate>  
  •     <ray>  
  •       <scan>  
  •         <horizontal>  
  •           <samples>720</samples>  
  •           <resolution>1</resolution>  
  •           <min_angle>-1.570796</min_angle>  
  •           <max_angle>1.570796</max_angle>  
  •         </horizontal>  
  •       </scan>  
  •       <range>  
  •         <min>0.10</min>  
  •         <max>30.0</max>  
  •         <resolution>0.01</resolution>  
  •       </range>  
  •       <noise>  
  •         <type>gaussian</type>  
  •         <!-- Noise parameters based on published spec for Hokuyo laser  
  • 分享:
    游客
    要评论请先登录 或者 注册
    tanxiaohai 初代型 2016-08-24 14:49 沙发
    大神
    看完自后感觉还是不知道怎么入手去仿真机器人啊
    tanxiaohai 初代型 2016-08-24 15:03 板凳
    在你的这篇文章:http://blog.csdn.net/yaked/article/details/45618877
    感觉看懂了写东西,现在动手谢谢

    感谢大神分享
     返回顶部