ROS Learning Notes - Robot Project Practice

Posted by shawnyoung on Mon, 06 Sep 2021 19:34:18 +0200

1.URDF Modeling

Location: A file describing a robot model in XML format

Basic concepts and grammar

(1)link

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-XpfM1kHV-1630947457949).)https://z3.ax1x.com/2021/08/21/fxYEcQ.png)]

(2)joint

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-Yw34YH1u-1630947457952). (https://z3.ax1x.com/2021/08/21/fxYA1g.png)]

(3)robot Tags

  • Bottom Label of Complete Robot Model
  • Both and labels are included in the label
<robot name="<name of the robot>">    
    <link> ....... </link>    
    <joint>......</joint>
</robot>

(4) Common syntax for xacro files

Constant Definition

<xacro:property name="M_PI" value="3.14159"/>

Constant usage

<origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>

Mathematical calculation

<origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
  • Note: All mathematical operations will be converted to floating point numbers

Macro Definition

<xacro:macro name="name" params="A B C">    ......</xacro:macro>

Macro Call

<name A="A_value" B="B_value" C="C_value"/>

File contains

<xacro:include filename="$(find mbot_description)/urdf/xacro/mbot_base.xacro"/>

Code Samples

<launch>    
    <arg name="model" />   
 
    <!-- Loading Robot Model Parameters -->    
    <param name="robot_description" command="$(find xacro)/xacro --inorder $(find marm_description)/urdf/marm.xacro" />    
    
    <!-- Set up GUI Parameters, Display Joint Control Plug-in -->    
    <param name="use_gui" value="true"/> 
  
    <!-- Function joint_state_publisher Node, publish the joint state of the robot  -->   
    <node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />          
   
    <!-- Function robot_state_publisher Node, Publish tf  -->    
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />   
    
    <!-- Function rviz Visualization interface -->   
     <node name="rviz" pkg="rviz" type="rviz" args="-d $(find marm_description)/urdf.rviz" required="true" />
</launch>

2.SW file to URDF file

(1) Configure the rotation axis
i. Insert-Reference Geometry-Base Axis

ii. Select the corresponding parts on the assembly to generate the base axis

(2) Configure link and joint using sw2urdf plug-in

i. Tools - File-Export as URDF

ii. Configure the base axis for each link, the type of join, and the mechanical part that the link contains

iii. Set joint limits, force limits and maximum speed

iv. Generate Function Pack

(3) Compile functional packages

  • Change 2 in the mailbox of the package.xml file of the feature pack to @

  • Modify display.launch file

    <param    name="robot_description"    textfile="$(find UR3)/robots/UR3.urdf" />
    

    Change to

    <param    name="robot_description"    textfile="$(find UR3)/urdf/UR3.urdf" />
    
  • Compile

(4) Modify rviz configuration (only once)

  • Fixed Frame Select base_link

  • Add - RobotModel

  • Use the following command

    sudo chmod 777 /opt/ros/melodic/share/rviz/default.rviz
    

    Modify profile permissions and save configuration

(5) Testing

  • Modify display.launch file

      <arg    name="gui"    default="False" />
    

    Change to

    <arg    name="gui"    default="True" />
    

    Then reopen the launch file, and a small plug-in for joint adjustment appears, which can adjust the angle of each joint.

2.MoveIt!Study

1. Operation flow

  1. Create URDF model
  2. Use MoveIt!Setup Assistant Tool Generation Configuration File
  3. Add Robot Controller Plug-in
  4. Movelt!Control robot motion (algorithm simulation, physical simulation)

2. Visual Configuration

  1. Start Setup Assistant

    rosrun moveit_setup_assistant moveit_setup_assistant
    
  2. Select Model
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-e7alMoKV-1630947457954).)https://z3.ax1x.com/2021/08/23/h9tUZ4.png)]

  3. Setting up self-collision detection
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-abyOJBY5-1630947457955). (https://z3.ax1x.com/2021/08/23/h9tdo9.png)]

    • Here the minimum collision point is 10000, just leave the default value.
  4. Configuration Planning Group
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-SJPdd6dP-1630947457956). (https://z3.ax1x.com/2021/08/23/h9t0iR.png)]

    • Here's a bug, Solver Attempts doesn't need to be filled in, select RRT in OMPL Planning
  5. Predefined Posture
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-poulueFc-1630947457958). (https://z3.ax1x.com/2021/08/23/h9tadJ.png)]

  6. Enter author information
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-qfTbO3EB-1630947457959).)https://z3.ax1x.com/2021/08/23/h9ttLF.png)]

  7. Generate Configuration Feature Pack
    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-qfpknA8d-1630947457960).)https://z3.ax1x.com/2021/08/23/h9tBJ1.png)]

  8. test

    roslaunch package_name demo.launch
    

3. Build a simulation environment using moveit and gazebo

Dead work:

  • Download Controller

    sudo apt install ros-melodic-ros-controllers
    
  • There are many namespace s in the configuration process, so for consistency, they all use the name of the robot.

  • Robot_for all files belowName will be replaced with the name of your own robot.

  • demo to change

1. Model file

(1) Because you need to import the model into gazebo, convert the urdf file to xacro file, create the.Xacro file, copy the configuration of join and link in the.urdf file, and then do the following
i. Add File Header

<?xml version="1.0"?>
<robot name="<robot_name>" xmlns:xacro="http://www.ros.org/wiki/xacro">

ii. Add underlying link s and joins because base_in gazebo Link has no inertia attribute

 <link name="base_footprint"/>
  <joint name="joint_0" type="fixed">
    <origin xyz="0 0 0.0532" rpy="0 0 0" />
    <parent link="base_footprint" />
    <child link="base_link" />
  </joint>

iii. Add drive for join

  <!-- Transmissions for ROS Control -->
  <xacro:macro name="transmission_block" params="joint_name">
    <transmission name="tran1">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${joint_name}">
        <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor1">
        <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>
  </xacro:macro>
  
  <xacro:transmission_block joint_name="joint_1"/>
  <xacro:transmission_block joint_name="joint_2"/>
  <xacro:transmission_block joint_name="joint_3"/>
  <xacro:transmission_block joint_name="joint_4"/>
  <xacro:transmission_block joint_name="joint_5"/>
  <xacro:transmission_block joint_name="joint_6"/>

iv. Add gazebo controller plug-in

  <!-- ros_control plugin -->  
<gazebo>    
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">    
        <robotNamespace>/robot_name</robotNamespace>      
        <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>      
        <legacyModeNS>true</legacyModeNS>    
    </plugin>  
</gazebo>

v. Refer to "moveit" above!Learn, generate the moveit configuration feature pack "robot_name_moveit_config"

2.gazebo Feature Pack

  • Create a feature pack "robot_first"Name_Gazebo ", then create two new folders inside config and launch
  1. config file
    robot_name_gazebo_joint_states.yaml

    robot_name:
      # Publish all joint states -----------------------------------
      joint_state_controller:
        type: joint_state_controller/JointStateController
        publish_rate: 50
    

    robot_name_trajectory_control.yaml

    robot_name:
      arm_joint_controller:
        type: "position_controllers/JointTrajectoryController"
        joints:
          - joint_1
          - joint_2
          - joint_3
          - joint_4
          - joint_5
          - joint_6
    
        gains:
          joint_1:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
          joint_2:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
          joint_3:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
          joint_4:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
          joint_5:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
          joint_6:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
    
  2. launch file
    robot_name_trajectory_controller.launch

    <launch>
        <rosparam file="$(find robot_name_gazebo)/config/probot_anno_trajectory_control.yaml" command="load"/>
        <node name="arm_controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
              output="screen" ns="/robot_name" args="arm_joint_controller"/>
    </launch>
    

    robot_name_gazebo_states.launch

    <launch>
        <!-- Load the configuration parameters of the joint controller into the parameter server -->
        <rosparam file="$(find robot_name_gazebo)/config/robot_name_gazebo_joint_states.yaml" command="load"/>
    
        <node name="joint_controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
              output="screen" ns="/robot_name" args="joint_state_controller" />
    
        <!-- Function robot_state_publisher Node, Publish tf  -->
        <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
            respawn="false" output="screen">
            <remap from="/joint_states" to="/robot_name/joint_states" />
        </node>
    
    </launch>
    

    robot_name_gazebo_world.launch

    <launch>
    
      <!-- these are the arguments you can pass this launch file, for example paused:=true -->
      <arg name="paused" default="false"/>
      <arg name="use_sim_time" default="true"/>
      <arg name="gui" default="true"/>
      <arg name="headless" default="false"/>
      <arg name="debug" default="false"/>
    
      <!-- We resume the logic in empty_world.launch -->
      <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="debug" value="$(arg debug)" />
        <arg name="gui" value="$(arg gui)" />
        <arg name="paused" value="$(arg paused)"/>
        <arg name="use_sim_time" value="$(arg use_sim_time)"/>
        <arg name="headless" value="$(arg headless)"/>
      </include>
    
      <!-- Load the URDF into the ROS Parameter Server -->
      <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find robot_name_description)/urdf/robot_name.xacro'" /> 
    
    
      <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
      <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
        args="-urdf -model robot_name -param robot_description"/> 
    
    </launch>
    

    robot_name_bringup_moveit.launch

    <launch>
      
        <!-- Launch Gazebo  -->
        <include file="$(find robot_name_gazebo)/launch/robot_name/robot_name_gazebo_world.launch" />
    
        <!-- ros_control arm launch file -->
        <include file="$(find robot_name)/launch/robot_name/robot_name_gazebo_states.launch" />   
    
        <!-- ros_control trajectory control dof arm launch file -->
        <include file="$(find robot_name)/launch/robot_name/robot_name_trajectory_controller.launch" />
    
        <!-- moveit launch file -->
        <include file="$(find robot_name_moveit_config)/launch/moveit_planning_execution.launch" />
    
    </launch>
    

3.moveit profile

  1. Create a new file "controllers_in the config folder"Gazebo.yaml"

    controller_manager_ns: controller_manager
    controller_list:
      - name: robot_name/arm_joint_controller
        action_ns: follow_joint_trajectory
        type: FollowJointTrajectory
        default: true
        joints:
          - joint_1
          - joint_2
          - joint_3
          - joint_4
          - joint_5
          - joint_6
    
  2. Modifications in launch folder
    i. Increase moveit_planning_execution.launch

     <launch>
    
      <!--The planning and execution components of MoveIt! configured to 
          publish the current configuration of the robot (simulated or real) 
          and the current state of the world as seen by the planner-->
     <include file="$(find robot_name_moveit_config)/launch/move_group.launch">
      <arg name="publish_monitored_planning_scene" value="true" />
     </include>
    
      <!--The visualization component of MoveIt!-->
     <include file="$(find robot_name_moveit_config)/launch/moveit_rviz.launch">
      <arg name="config" value="true" />
     </include>
    
        <!-- We do not have a robot connected, so publish fake joint states -->
      <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
        <param name="/use_gui" value="false"/> 
        <rosparam param="/source_list">[/robot_name/joint_states]</rosparam>
      </node>
    
    </launch>
    

    ii. Modify moveit_rviz.launch

    <launch>
    
      <arg name="debug" default="false" />
      <arg unless="$(arg debug)" name="launch_prefix" value="" />
      <arg     if="$(arg debug)" name="launch_prefix" value="gdb --ex run --args" />
    
      <arg name="config" default="false" />
      <arg unless="$(arg config)" name="command_args" default="" />
      <arg     if="$(arg config)" name="command_args" default="-d $(find robot_name_moveit_config)/launch/moveit.rviz" />
    
      <node name="$(anon rviz)" launch-prefix="$(arg launch_prefix)" pkg="rviz" type="rviz" respawn="false"
        args="$(arg command_args)" output="screen">
        <rosparam command="load" file="$(find robot_name_moveit_config)/config/kinematics.yaml"/>
      </node>
    
    </launch>
    

    iii. Modify robot_name_moveit_controller_manager.launch.xml

    <launch>
    
      <!-- loads moveit_controller_manager on the parameter server which is taken as argument
        if no argument is passed, moveit_simple_controller_manager will be set -->
      <arg name="moveit_controller_manager" default="moveit_simple_controller_manager/MoveItSimpleControllerManager" />
      <param name="moveit_controller_manager" value="$(arg moveit_controller_manager)"/>
    
    <arg name="execution_type" />
      <arg name="use_controller_manager" default="true" />
      <param name="use_controller_manager" value="$(arg use_controller_manager)" />
      
      <!-- loads ros_controllers to the param server -->
      <rosparam file="$(find probot_moveit_config)/config/controllers_gazebo.yaml"/>
    </launch>
    
  • With the above modifications, demo.launch in the file will not execute and can be replaced with the following file.

    <launch>
    
      <!-- By default, we do not start a database (it can be large) -->
      <arg name="db" default="false" />
      <!-- Allow user to specify database location -->
      <arg name="db_path" default="$(find robot_name_moveit_config)/default_warehouse_mongo_db" />
    
      <!-- By default, we are not in debug mode -->
      <arg name="debug" default="false" />
    
      <!--
      By default, hide joint_state_publisher's GUI
    
      MoveIt!'s "demo" mode replaces the real robot driver with the joint_state_publisher.
      The latter one maintains and publishes the current joint configuration of the simulated robot.
      It also provides a GUI to move the simulated robot around "manually".
      This corresponds to moving around the real robot without the use of MoveIt.
      -->
      <arg name="use_gui" default="false" />
    
      <!-- Load the URDF, SRDF and other .yaml configuration files on the param server -->
      <include file="$(find robot_name_moveit_config)/launch/planning_context.launch">
        <arg name="load_robot_description" value="true"/>
      </include>
    
      <!-- If needed, broadcast static tf for robot root -->
      
    
      <!-- We do not have a robot connected, so publish fake joint states -->
      <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
        <param name="use_gui" value="$(arg use_gui)"/>
        <rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
      </node>
    
      <!-- Given the published joint states, publish tf for the robot links -->
      <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
    
      <!-- Run the main MoveIt! executable without trajectory execution (we do not have controllers configured by default) -->
      <include file="$(find robot_name_moveit_config)/launch/move_group.launch">
        <arg name="allow_trajectory_execution" value="true"/>
        <arg name="fake_execution" value="true"/>
        <arg name="info" value="true"/>
        <arg name="debug" value="$(arg debug)"/>
      </include>
    
      <!-- Run Rviz and load the default config to see the state of the move_group node -->
      <include file="$(find robot_name_moveit_config)/launch/moveit_rviz.launch">
        <arg name="config" value="true"/>
        <arg name="debug" value="$(arg debug)"/>
      </include>
    
      <!-- If database loading was enabled, start mongodb as well -->
      <include file="$(find robot_name_moveit_config)/launch/default_warehouse_db.launch" if="$(arg db)">
        <arg name="moveit_warehouse_database_path" value="$(arg db_path)"/>
      </include>
    
    </launch>
    

4. Testing

  • Function

    roslaunch robot_name_gazebo robot_name_bringup_moveit.launch
    
  • rviz configuration: Add - RobotModel, TF

4. Programming Control of Moveit

  • Create functional packages for operations

    catkin_create_pkg moveit_program_demo roscpp rospy  moveit_msgs moveit_ros_perception moveit_ros_planning_interface trajectory_msgs
    
  • Coding

    • Implementation process
    1. ROS initialization, creating single/multithreaded
    2. Create a planning group instance and set parameters for route planning
    3. (Optional) Create a scene instance and add a colliding object to test obstacle avoidance
    4. Set target posture, select joint space or Cartesian space for path planning
    5. implement
    6. Close Threads

5.Moveit!Replace Kinematic Plug-in

  1. KDL

    • This library is used by default when generating a moveit configuration file, so you only need to configure the kinematics.yaml file
    manipulator:
      kinematics_solver: kdl_kinematics_plugin/KDLKinematicsPlugin
      kinematics_solver_search_resolution: 0.005
      kinematics_solver_timeout: 0.005
      kinematics_solver_attempts: 3
    
  2. TRAC-IK

    • Install library files
    sudo apt-get install ros-melodic-trac-ik-kinematics-plugin
    
    • Configure kinematics.yaml file
    manipulator:
      kinematics_solver: trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin
      kinematics_solver_attempts: 3
      kinematics_solver_search_resolution: 0.005
      kinematics_solver_timeout: 0.05
    
  3. IKFast

    The following steps take place once for each model

    • Create collada file
    export MYROBOT_NAME="<robot_name>"
    rosrun xacro xacro -o "$MYROBOT_NAME".urdf "$MYROBOT_NAME".xacro    
    rosrun collada_urdf urdf_to_collada "$MYROBOT_NAME".urdf "$MYROBOT_NAME".dae
    
    • Create a dae file
    export IKFAST_PRECISION="5"
    cp "$MYROBOT_NAME".dae "$MYROBOT_NAME".backup.dae 
    rosrun moveit_kinematics round_collada_numbers.py "$MYROBOT_NAME".dae "$MYROBOT_NAME".dae "$IKFAST_PRECISION"
    
    • View the generated model
    openrave-robot.py "$MYROBOT_NAME".dae --info links
    openrave "$MYROBOT_NAME".dae
    
    • Generate program files
    export PLANNING_GROUP="manipulator"
    export BASE_LINK="1"
    export EEF_LINK="8"
    export IKFAST_OUTPUT_PATH=`pwd`/ikfast61_"$PLANNING_GROUP".cpp
    python `openrave-config --python-dir`/openravepy/_openravepy_/ikfast.py --robot="$MYROBOT_NAME".dae --iktype=transform6d --baselink="$BASE_LINK" --eelink="$EEF_LINK" --savefile="$IKFAST_OUTPUT_PATH"
    
    • Create plug-ins
    export MOVEIT_IK_PLUGIN_PKG="$MYROBOT_NAME"_ikfast_"$PLANNING_GROUP"_plugin
    cd ~/catkin_ws/src
    catkin_create_pkg "$MOVEIT_IK_PLUGIN_PKG"
    rosrun moveit_kinematics create_ikfast_moveit_plugin.py "$MYROBOT_NAME" "$PLANNING_GROUP" "$MOVEIT_IK_PLUGIN_PKG" "$IKFAST_OUTPUT_PATH"
    
    • MoveIt!configuration file
    manipulator:
      kinematics_solver: <myrobot_name>_<planning_group>_kinematics/IKFastKinematicsPlugin
      kinematics_solver_search_resolution: 0.005
      kinematics_solver_timeout: 0.005
      kinematics_solver_attempts: 3
    
    • Note: Program files and.dae files can be deleted after plugin generation

Topics: Linux