ros gazebo机械臂仿真,手动控制与MoveIt自动控制

本文总结归纳古月居胡春旭ros机械臂教程,给出了一些error的解决方法,补充了通过python运行moveit。十分建议去看github huchunxu源代码的repository。

创建机械臂的xacro模型

首先创建一个工作空间,在工作空间中创建arm_description功能包。功能包中创建一个urdf文件夹,放入机械臂模型文件arm.xacro

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

    <!-- Defining the colors used in this robot -->
    <material name="Black">
        <color rgba="0 0 0 1"/>
    </material>

    <material name="White">
        <color rgba="1 1 1 1"/>
    </material>

    <material name="Blue">
        <color rgba="0 0 1 1"/>
    </material>

    <material name="Red">
        <color rgba="1 0 0 1"/>
    </material>

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

    <!-- link1 properties -->
    <xacro:property name="link1_width" value="0.03" />
    <xacro:property name="link1_len" value="0.10" />

    <!-- link2 properties -->
    <xacro:property name="link2_width" value="0.03" />
    <xacro:property name="link2_len" value="0.14" />

    <!-- link3 properties -->
    <xacro:property name="link3_width" value="0.03" />
    <xacro:property name="link3_len" value="0.22" />

    <!-- link4 properties -->
    <xacro:property name="link4_width" value="0.025" />
    <xacro:property name="link4_len" value="0.06" />

    <!-- link5 properties -->
    <xacro:property name="link5_width" value="0.03" />
    <xacro:property name="link5_len" value="0.06" />

    <!-- link6 properties -->
    <xacro:property name="link6_width" value="0.04" />
    <xacro:property name="link6_len" value="0.02" />

    <!-- Left gripper -->
    <xacro:property name="left_gripper_len" value="0.08" />
    <xacro:property name="left_gripper_width" value="0.01" />
    <xacro:property name="left_gripper_height" value="0.01" />

    <!-- Right gripper -->
    <xacro:property name="right_gripper_len" value="0.08" />
    <xacro:property name="right_gripper_width" value="0.01" />
    <xacro:property name="right_gripper_height" value="0.01" />

    <!-- Gripper frame -->
    <xacro:property name="grasp_frame_radius" value="0.001" />

    <!-- Inertial matrix -->
    <xacro:macro name="inertial_matrix" params="mass">
        <inertial>
            <mass value="${mass}" />
            <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="0.5" iyz="0.0" izz="1.0" />
        </inertial>
    </xacro:macro>

    <!-- ///   bottom_joint   // -->
    <joint name="bottom_joint" type="fixed">
        <origin xyz="0 0 0" rpy="0 0 0" />
        <parent link="base_link"/>
        <child link="bottom_link"/>
    </joint>
    <link name="bottom_link">
        <visual>
              <origin xyz=" 0 0 -0.02"  rpy="0 0 0"/>
                  <geometry>
                       <box size="1 1 0.02" />
                  </geometry>
              <material name="Brown" />
        </visual>
        <collision>
            <origin xyz=" 0 0 -0.02"  rpy="0 0 0"/>
            <geometry>
                <box size="1 1 0.02" />
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="500"/>
    </link>

    <!-- /   BASE LINK    // -->
    <link name="base_link">
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <geometry>
                <box size="0.1 0.1 0.04" />
            </geometry>
            <material name="White" />
        </visual>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <geometry>
                <box size="0.1 0.1 0.04" />
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint1" type="revolute">
        <parent link="base_link"/>
        <child link="link1"/>
        <origin xyz="0 0 0.02" rpy="0 ${M_PI/2} 0" />
        <axis xyz="-1 0 0" />
        <limit effort="300" velocity="1" lower="-2.96" upper="2.96"/>
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- /   LINK1  // -->
    <link name="link1" >
        <visual>
            <origin xyz="-${link1_len/2} 0 0" rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link1_width}" length="${link1_len}"/>
            </geometry>
            <material name="Blue" />
        </visual>
        <collision>
            <origin xyz="-${link1_len/2} 0 0" rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link1_width}" length="${link1_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint2" type="revolute">
        <parent link="link1"/>
        <child link="link2"/>
        <origin xyz="-${link1_len} 0 0.0" rpy="-${M_PI/2} 0 ${M_PI/2}" />
        <axis xyz="1 0 0" />
        <limit effort="300" velocity="1" lower="-2.35" upper="2.35" />
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- ///   LINK2  // -->
    <link name="link2" >
        <visual>
            <origin xyz="0 0 ${link2_len/2}" rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link2_width}" length="${link2_len}"/>
            </geometry>
            <material name="White" />
        </visual>

        <collision>
            <origin xyz="0 0 ${link2_len/2}" rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link2_width}" length="${link2_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint3" type="revolute">
        <parent link="link2"/>
        <child link="link3"/>
        <origin xyz="0 0 ${link2_len}" rpy="0 ${M_PI} 0" />
        <axis xyz="-1 0 0" />
        <limit effort="300" velocity="1" lower="-2.62" upper="2.62" />
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- /   LINK3  / -->
    <link name="link3" >
        <visual>
            <origin xyz="0 0 -${link3_len/2}" rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link3_width}" length="${link3_len}"/>
            </geometry>
            <material name="Blue" />
        </visual>
        <collision>
            <origin xyz="0 0 -${link3_len/2}" rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link3_width}" length="${link3_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint4" type="revolute">
        <parent link="link3"/>
        <child link="link4"/>
        <origin xyz="0.0 0.0 -${link3_len}" rpy="0 ${M_PI/2} ${M_PI}" />
        <axis xyz="1 0 0" />
        <limit effort="300" velocity="1" lower="-2.62" upper="2.62" />
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- ///   LINK4   -->
    <link name="link4" >
        <visual>
            <origin xyz="${link4_len/2} 0 0" rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link4_width}" length="${link4_len}"/>
            </geometry>
            <material name="Black" />
        </visual>
        <collision>
            <origin xyz="${link4_len/2} 0 0" rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link4_width}" length="${link4_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint5" type="revolute">
        <parent link="link4"/>
        <child link="link5"/>
        <origin xyz="${link4_len} 0.0 0.0" rpy="0 ${M_PI/2} 0" />
        <axis xyz="1 0 0" />
        <limit effort="300" velocity="1" lower="-2.62" upper="2.62" />
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- //   LINK5  / -->
    <link name="link5">
        <visual>
            <origin xyz="0 0 ${link4_len/2}" rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link5_width}" length="${link5_len}"/>
            </geometry>
            <material name="White" />
        </visual>
        <collision>
            <origin xyz="0 0 ${link4_len/2} " rpy="0 0 0" />
            <geometry>
                <cylinder radius="${link5_width}" length="${link5_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="joint6" type="revolute">
        <parent link="link5"/>
        <child link="link6"/>
        <origin xyz="0 0 ${link4_len}" rpy="${1.5*M_PI} -${M_PI/2} 0" />
        <axis xyz="1 0 0" />
        <limit effort="300" velocity="1" lower="-6.28" upper="6.28" />
        <dynamics damping="50" friction="1"/>
    </joint>

    <!--    LINK6  / -->
    <link name="link6">
        <visual>
            <origin xyz="${link6_len/2} 0 0 " rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link6_width}" length="${link6_len}"/>
            </geometry>
            <material name="Blue" />
        </visual>
        <collision>
            <origin xyz="${link6_len/2} 0 0" rpy="0 ${M_PI/2} 0" />
            <geometry>
                <cylinder radius="${link6_width}" length="${link6_len}"/>
            </geometry>
        </collision>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="finger_joint1" type="prismatic">
        <parent link="link6"/>
        <child link="gripper_finger_link1"/>
        <origin xyz="0.0 0 0" />
        <axis xyz="0 1 0" />
        <limit effort="100" lower="0" upper="0.06" velocity="1.0"/>
        <dynamics damping="50" friction="1"/>
    </joint>

    <!-- //   gripper   // -->
    <!-- LEFT GRIPPER AFT LINK -->
    <link name="gripper_finger_link1">
        <visual>
            <origin xyz="0.04 -0.03 0"/>
            <geometry>
                <box size="${left_gripper_len} ${left_gripper_width} ${left_gripper_height}" />
            </geometry>
            <material name="White" />
        </visual>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <joint name="finger_joint2" type="fixed">
        <parent link="link6"/>
        <child link="gripper_finger_link2"/>
        <origin xyz="0.0 0 0" />
    </joint>

    <!-- RIGHT GRIPPER AFT LINK -->
    <link name="gripper_finger_link2">
        <visual>
            <origin xyz="0.04 0.03 0"/>
            <geometry>
                <box size="${right_gripper_len} ${right_gripper_width} ${right_gripper_height}" />
            </geometry>
            <material name="White" />
        </visual>
        <xacro:inertial_matrix mass="1"/>
    </link>

    <!-- Grasping frame -->
    <link name="grasping_frame"/>

    <joint name="grasping_frame_joint" type="fixed">
      <parent link="link6"/>
      <child link="grasping_frame"/>
      <origin xyz="0.08 0 0" rpy="0 0 0"/>
    </joint>

    <!-- /   Gazebo   // -->
    <gazebo reference="bottom_link">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="base_link">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="link1">
        <material>Gazebo/Blue</material>
    </gazebo>
    <gazebo reference="link2">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="link3">
        <material>Gazebo/Blue</material>
    </gazebo>
    <gazebo reference="link4">
        <material>Gazebo/Black</material>
    </gazebo>
    <gazebo reference="link5">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="link6">
        <material>Gazebo/Blue</material>
    </gazebo>
    <gazebo reference="gripper_finger_link1">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="gripper_finger_link2">
        <material>Gazebo/White</material>
    </gazebo>
    
    <!-- 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="joint1"/>
    <xacro:transmission_block joint_name="joint2"/>
    <xacro:transmission_block joint_name="joint3"/>
    <xacro:transmission_block joint_name="joint4"/>
    <xacro:transmission_block joint_name="joint5"/>
    <xacro:transmission_block joint_name="joint6"/>
    <xacro:transmission_block joint_name="finger_joint1"/>

    <!-- ros_control plugin -->
    <gazebo>
        <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
            <robotNamespace>/arm</robotNamespace>
        </plugin>
    </gazebo>

</robot>

Transmission for ROS Control那一部分相当于是给关节绑定上电机,通过控制电机控制关节运动。

再创建一个launch文件夹,创建view_arm.launch文件

<launch>
    <arg name="model" />
    <!-- 加载机器人模型参数 -->
    <param name="robot_description" command="$(find xacro)/xacro --inorder $(find arm_description)/urdf/arm.xacro" />

    <!-- 设置GUI参数,显示关节控制插件 -->
    <!-- <param name="use_gui" value="true"/> -->

    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    
    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />

    <!-- 运行rviz可视化界面 -->
    <node name="rviz" pkg="rviz" type="rviz"/>
</launch>

运行这个launch文件,在rviz中选择fixed frame,再加载Robot Model,就可以看见机械臂了。

在Gazebo中手动控制机械臂

在工作空间中再创建一个arm_gazebo功能包,添加launch文件夹,创建arm_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 arm_description)/urdf/arm.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 arm -param robot_description"/> 


</launch>

功能是:创建一个环境,并且将机器人模型放进去。

下面要做的是加载控制器,首先要设定pid控制器的参数。在arm_gazebo功能包中创建config文件夹,创建arm_gazebo_control.yaml,给6个关节设定pid控制器参数。

arm:
  # Publish all joint states -----------------------------------
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  
  
  # Position Controllers ---------------------------------------
  joint1_position_controller:
    type: position_controllers/JointPositionController
    joint: joint1
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint2_position_controller:
    type: position_controllers/JointPositionController
    joint: joint2
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint3_position_controller:
    type: position_controllers/JointPositionController
    joint: joint3
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint4_position_controller:
    type: position_controllers/JointPositionController
    joint: joint4
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint5_position_controller:
    type: position_controllers/JointPositionController
    joint: joint5
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint6_position_controller:
    type: position_controllers/JointPositionController
    joint: joint6
    pid: {p: 100.0, i: 0.01, d: 10.0}
 

在launch文件夹中创建arm_gazebo_controller.launch,实现的作用是加载刚才创建的pid参数yaml文件,创建控制器。

<launch>

    <!-- 将关节控制器的配置参数加载到参数服务器中 -->
    <rosparam file="$(find arm_gazebo)/config/arm_gazebo_control.yaml" command="load"/>

    <!-- 加载controllers -->
    <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
          output="screen" ns="/arm" args="joint_state_controller
                                          joint1_position_controller
                                          joint2_position_controller
                                          joint3_position_controller
                                          joint4_position_controller
                                          joint5_position_controller
                                          joint6_position_controller"/>

    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
          respawn="false" output="screen">
        <remap from="/joint_states" to="/arm/joint_states" />
    </node>

</launch>

最后再创建一个arm_gazebo_control.launch文件,其作用是,运行world launch和controller launch两个launch文件。

<launch>

    <!-- 启动Gazebo  -->
    <include file="$(find arm_gazebo)/launch/arm_world.launch" />   

    <!-- 启动Gazebo controllers -->
    <include file="$(find arm_gazebo)/launch/arm_gazebo_controller.launch" />   

</launch>

运行arm_gazebo_control.launch文件,再另外打开两个terminal,分别运行

rqt
rosrun rviz rviz

通过rqt发送指令,可以在gazebo和rviz中同时看到机械臂的动作。

配置MoveIt

rosrun moveit_setup_assistant moveit_setup_assistant

依次加载模型,生成碰撞矩阵,生成规划组,如下图所示,一个arm规划组和一个gripper规划组,注意“3”那里,新版本的moveit那里不一样,空着就好。

 

 

 添加一个初始位姿,命名为home

 配置终端夹爪

最后再添加作者信息,生成配置文件就可以了。命名为arm_moveit_config,和前面创建的两个功能包arm_description, arm_gazebo并列放在一起。

用moveIt控制gazebo中的机械臂

arm_gazebo功能包中创建关节轨迹控制器,一个控制器包含两个部分:yaml配置文件和launch运行文件,yaml配置文件放在功能包的config文件夹中,里面写着控制器的参数,运行文件放在launch文件夹中,用于运行控制器。

arm_moveit_config功能包中创建一个gazebo控制器,同样是一组.yaml和.launch文件(注意这个launch文件的后缀是.launch.xml,这个文件自动存在,不需要创建,我们要改内容),launch文件加载yaml文件,分别放在config文件夹和launch文件夹。以及另外一个单独的.launch(moveit_planning_execution.launch)。

moveit功能包中的控制器和gazebo功能包中的控制器的关系是:通过ros的Action机制,moveit功能包中的控制器发布关节轨迹点指令,gazebo功能包中的控制器控制关节电机是关节到达轨迹点。

还要在arm_gazebo功能包中创建一个关节状态控制器,用于发布关节状态和tf变换。这个是为了在rviz中可视化用。

总结:一共三个控制器7个文件(3个.yaml和4个.launch)

arm_gazebo功能包中的命名为:trajectory_control.yaml    arm_trajectory_controller.launch

arm_gazebo_joint_states.yaml      arm_gazebo_states.launch

arm_moveit_config功能包中的命名为:controllers_gazebo.yaml    arm_moveit_controller_manager.launch.xml

moveit_planning_execution.launch

以上文件的内容整理在后文。最后再创建一个.launch,其作用是一次性运行上面的所有.launch。命名为arm_bringup_moveit.launch,放在arm_gazebo功能包的launch文件夹。

运行最后写的那个.launch,就可以通过rviz中的moveit插件来控制gazebo中的机械臂了。

roslaunch marm_gazebo arm_bringup_moveit.launch

 trajectory_control.yaml 内容:

arm:
  arm_joint_controller:
    type: "position_controllers/JointTrajectoryController"
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6

    gains:
      joint1:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint2:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint3:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint4:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint5:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint6:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}


  gripper_controller:
    type: "position_controllers/JointTrajectoryController"
    joints:
      - finger_joint1
    gains:
      finger_joint1:  {p: 50.0, d: 1.0, i: 0.01, i_clamp: 1.0}

 arm_trajectory_controller.launch 内容:

<launch>

    <rosparam file="$(find arm_gazebo)/config/trajectory_control.yaml" command="load"/>

    <node name="arm_controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
          output="screen" ns="/arm" args="arm_joint_controller gripper_controller"/>

</launch>

arm_gazebo_joint_states.yaml 内容:

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

arm_gazebo_states.launch 内容:

<launch>
    <!-- 将关节控制器的配置参数加载到参数服务器中 -->
    <rosparam file="$(find arm_gazebo)/config/arm_gazebo_joint_states.yaml" command="load"/>

    <node name="joint_controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
          output="screen" ns="/arm" args="joint_state_controller" />

    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
        respawn="false" output="screen">
        <remap from="/joint_states" to="/arm/joint_states" />
    </node>

</launch>

controllers_gazebo.yaml内容:

controller_manager_ns: controller_manager
controller_list:
  - name: arm/arm_joint_controller
    action_ns: follow_joint_trajectory
    type: FollowJointTrajectory
    default: true
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6

  - name: arm/gripper_controller
    action_ns: follow_joint_trajectory
    type: FollowJointTrajectory
    default: true
    joints:
      - finger_joint1
      - finger_joint2

arm_moveit_controller_manager.launch.xml内容:

<launch>
  <!-- Set the param that trajectory_execution_manager needs to find the controller plugin -->
  <arg name="moveit_controller_manager" default="moveit_simple_controller_manager/MoveItSimpleControllerManager" />
  <param name="moveit_controller_manager" value="$(arg moveit_controller_manager)"/>

  <!-- load controller_list -->
  <!-- Arbotix -->
  <!-- <rosparam file="$(find marm_moveit_config)/config/controllers.yaml"/> -->
  <!-- Gazebo -->
  <rosparam file="$(find arm_moveit_config)/config/controllers_gazebo.yaml"/>
</launch>

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 arm_moveit_config)/launch/move_group.launch">
  <arg name="publish_monitored_planning_scene" value="true" />
 </include>
 # The visualization component of MoveIt!
 <include file="$(find arm_moveit_config)/launch/moveit_rviz.launch"/>

  <!-- 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">[/arm/joint_states]</rosparam>
  </node>

</launch>

arm_bringup_moveit.launch内容:

<launch>
  
    <!-- Launch Gazebo  -->
    <include file="$(find arm_gazebo)/launch/arm_world.launch" />

    <!-- ros_control arm launch file -->
    <include file="$(find arm_gazebo)/launch/arm_gazebo_states.launch" />   

    <!-- ros_control trajectory control dof arm launch file -->
    <include file="$(find arm_gazebo)/launch/arm_trajectory_controller.launch" />

    <!-- moveit launch file -->
    <include file="$(find arm_moveit_config)/launch/moveit_planning_execution.launch" />

</launch>

一些可能出现的报错:

Tried to advertise on topic but the topic is already advertised

解决办法:

arm_moveit_config功能包中,sensors_3d.yaml文件中,出现了重名topic,修改第二个topic的名称

 Unable to identify any set of controllers that can actuate the specified joints:

解决办法:修改

工作空间/src/marm_moveit_config/launch/trajectory_execution.launch.xml

删掉 pass_all_args="true"

通过python的接口运行moveit

上面是通过rviz中的插件来控制moveit,下面通过py文件来运行moveit,不需要在rviz中操作moveit插件。

还是先运行arm_bringup_moveit.launch

再运行这个py文件,group_name是在moveit_setup_assistant中配置的group,在joint_goal那里设定关节目标角度 弧度制。


import sys
import rospy
import moveit_commander
from moveit_commander import PlanningSceneInterface


moveit_commander.roscpp_initialize(sys.argv)
rospy.init_node('move_group_python_interface_tutorial', anonymous=True)

## Instantiate a `RobotCommander`_ object. Provides information such as the robot's
## kinematic model and the robot's current joint states
robot = moveit_commander.RobotCommander()

## Instantiate a `PlanningSceneInterface`_ object.  This provides a remote interface
## for getting, setting, and updating the robot's internal understanding of the
## surrounding world:
scene = moveit_commander.PlanningSceneInterface()

## Instantiate a `MoveGroupCommander`_ object.  This object is an interface
## to a planning group (group of joints).  In this tutorial the group is the primary
## arm joints in the Panda robot, so we set the group's name to "panda_arm".
## If you are using a different robot, change this value to the name of your robot
## arm planning group.
## This interface can be used to plan and execute motions:
group_name = "arm"
move_group = moveit_commander.MoveGroupCommander(group_name)
joint_goal = move_group.get_current_joint_values()
print(joint_goal)
joint_goal[0] = 0
joint_goal[1] = 0.9
joint_goal[2] = 0
joint_goal[3] = 0


# The go command can be called with joint values, poses, or without any
# parameters if you have already set the pose or joint target for the group
move_group.go(joint_goal, wait=True)

# Calling ``stop()`` ensures that there is no residual movement
move_group.stop()

## END_SUB_TUTORIAL

# For testing:
current_joints = move_group.get_current_joint_values()
print(current_joints)

如果是pycharm运行py文件,注意interpreter选择,我的虚拟机安装的是ubuntu18 和ros melodic,需要python2.7的interpreter,另外还要把melodic的python包放进pycharm的project structure。另外,在pycharm中添加两个环境变量。以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/305936.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt应用-实现图像截取功能类似QQ上传头像截取功能

本文演示利用Qt实现图像截取功能类似QQ上传头像截取功能。 效果如下,通过移动中间的裁剪区域可以获得一张裁剪后的图片。 目录

MySQL进阶之(二)索引的数据结构

二、索引的数据结构 2.1 关于索引2.1.1 什么是索引&#xff1f;2.1.2 为什么使用索引&#xff1f;2.1.3 索引的优缺点01、优点02、缺点 2.1.4 一个简单的索引设计方案 2.2 InnoDB 中的索引设计2.2.1 迭代①&#xff1a;目录项记录的页2.2.2 迭代②&#xff1a;多个目录项记录的…

程序媛的mac修炼手册-- 终端(terminal)常用命令

「终端&#xff08;terminal&#xff09;」相当于macOS的一个 App &#xff0c;它的特殊之处是&#xff0c;它是管理其它App的App&#xff0c;操作主要通过命令行界面 (CLI) 。 相比于我们日常熟悉的用户界面&#xff08;User Interface&#xff0c;UI&#xff09;&#xff0c…

顺序栈之共享栈实现——C语言

参考书&#xff1a;数据结构教程 第5版 李葆春 P83 #include <stdio.h> #include <string.h> #include <stdlib.h>#define MaxSize 10/*共享栈*/ typedef struct {char data[MaxSize];int top1,top2,len; }DStack;/*初始化*/ void InitStack(DStack *s){s-…

HCIA-Datacom题库(自己整理分类的)_17_简单的命令判断【11道题】

1.华为AR路由器的命令行界面下&#xff0c;save命令的作用是保存当前的系统时间。 解析&#xff1a;Save保存配置 2.VRP界面下&#xff0c;使用命令delete vrpcfg.zp删除文件&#xff0c;必须在回收站中清空&#xff0c;才能彻底删除文件。√ 解析&#xff1a;delete删除到回…

Selenium 学习(0.19)——软件测试之基本路径测试法——拓展案例

1、案例 请使用基本路径法为变量year设计测试用例&#xff0c;year的取值范围是1000<year<2001。代码如下&#xff1a; 2、步骤 先画控制流程图 再转化为控制流图&#xff08;标出节点&#xff09; V(G) 总区域数 4 V(G) E - N 2 (边数 - 节点数 2…

AArch64 Exception Model学习

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网文档为准。 1 Privilege and Exception Levels 1.1 为什么要划分权限&#xf…

5分钟使用Hologres实时湖仓加速分析挑战赛来袭

活动简介 5分钟快速使用Hologres实时湖仓能力&#xff0c;加速分析数据湖OSS上Hudi、Delta、Paimon、ORC等格式数据&#xff0c;赢取精美礼品 活动入口&#xff1a;Hologres实时湖仓分析挑战赛-阿里云开发者社区 或点击文末【阅读全文】参与挑战 活动时间 2024年1月4日-202…

爬取国家法律法规数据库法律条文

代码展现&#xff1a; import requests import os filename 法律条文\\ if not os.path.exists(filename):os.mkdir(filename) url https://flk.npc.gov.cn/api/? data {type: flfg,searchType: title;vague,sortTr: f_bbrq_s;desc,gbrqStart: ,gbrqEnd: ,sxrqStart: ,sx…

【C语言】TCP测速程序

一、服务端 下面是一个用 C 语言编写的测试 TCP 传输速度的基本程序示例。 这只是一个简单示例&#xff0c;没有做详细的错误检查和边缘情况处理。在实际应用中&#xff0c;可能需要增加更多的功能和完善的异常处理机制。 TCP 服务器 (server.c): #include <stdio.h> #…

【c++】vector模拟

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;能手撕vector模拟 > 毒鸡汤&#xff1a;在等待…

动态规划(分割等和子集)

416. 分割等和子集 题目难易&#xff1a;中等 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, 5, 11, 5] 输出: true 解释: 数…

STM32入门教程-2023版【3-3】gpio输入

关注 星标公众号 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 上两小节我们已经把GPIO的结构和8种输入输出模式都讲完了&#xff0c;到这里还不懂的可以回…

浅析内存一致性:内存屏障

文章目录 概述内存乱序访问Store Buffer和Invalidate QueueStore BufferStore ForwardingStore Buffer与内存屏障 Invalidate QueueInvalidate Queue与内存屏障 内存屏障分类编译器屏障CPU内存屏障 相关参考 概述 内存屏障&#xff0c;是一类同步屏障指令&#xff0c;是CPU或编…

Java中的输入输出处理(一)

文件 文件&#xff1a;文件是放在一起的数据的集合。比如1.TXT。 存储地方&#xff1a;文件一般存储在硬盘&#xff0c;CD里比如D盘 如何访问文件属性&#xff1a;我们可以通过java.io.File类对其处理 File类 常用方法&#xff1a; 方法名称说明boolean exists()判断文件或目…

处理机调度与死锁

目录 进程调度算法先来先服务调度算法FCFS最短作业优先调度算法SJF最高优先级调度算法***HPF***高响应比优先调度算法 ***HRRN***时间片轮转调度算法***RR***多级队列调度算法MFQ 进程调度算法 进程调度算法也称为CPU调度算法 当 CPU 空闲时&#xff0c;操作系统就选择内存中…

一天一个设计模式---工厂方法

概念 工厂模式是一种创建型设计模式&#xff0c;其主要目标是提供一个统一的接口来创建对象&#xff0c;而不必指定其具体类。工厂模式将对象的实例化过程抽象出来&#xff0c;使得客户端代码不需要知道实际创建的具体类&#xff0c;只需通过工厂接口或方法来获取所需的对象。…

uniapp中uview组件库丰富的Table 表格的使用方法

目录 #平台差异说明 #基本使用 #兼容性 #API #Table Props #Td Props #Th Props 表格组件一般用于展示大量结构化数据的场景 #平台差异说明 AppH5微信小程序支付宝小程序百度小程序头条小程序QQ小程序√√√√√√√ #基本使用 本组件标签类似HTML的table表格&#…

模型评估:评估指标的局限性

“没有测量&#xff0c;就没有科学。”这是科学家门捷列夫的名言。在计算机科学特别是机器学习领域中&#xff0c;对模型的评估同样至关重要。只有选择与问题相匹配的评估方法&#xff0c;才能快速地发现模型选择或训练过程中出现的问题&#xff0c;迭代地对模型进行优化。模型…

猫头虎分享:Linux 如何安装最新版的Docker和Docker-Compose 教程 ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…