有多少人工,就有多少智能

Franka Ros1 简介

Franka Ros 暂时在Windows上不受支持。

 

封装的示意图franka_ros

元包franka_ros集成libfranka到 ROS 和 ROS 控件中。这里我们介绍它的包,并简要介绍如何编写控制器

本节中传递给启动文件的所有参数都带有默认值,因此如果使用默认网络地址和 ROS 命名空间,则可以省略这些参数。确保使用source工作区中的设置脚本调用该命令:

source /path/to/catkin_ws/devel/setup.sh

franka_description

该包包含我们的机器人和末端执行器在运动学,关节限制,视觉表现和碰撞空间方面的描述。碰撞空间是视觉描述的简化版本,用于提高碰撞检测的性能。根据URDF XML文档, 这些描述基于URDF格式。

如果你想模拟FR3机器人, 您可以参考参数传递gazebo给XACRO文件。 franka_description 包含所有Franka Robotics机器人模型的文件。

xacro $(rospack find franka_description)/robots/fr3/fr3.urdf.xacro gazebo:=true
<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="fr3">

  <xacro:include filename="$(find franka_description)/robots/common/franka_robot.xacro"/>

  <!-- Name for this robot -->
  <xacro:arg name="arm_id" default="fr3" />

  <!-- Should a franka_gripper be mounted at the flange?" -->
  <xacro:arg name="hand" default="false" />
  <!-- Positional offset between $(arm_id)_hand -> $(arm_id)_hand_tcp [m]. Only used when hand:=true -->
  <xacro:arg name="tcp_xyz" default="0 0 0.1034" />
  <!-- Rotational offset between $(arm_id)_hand -> $(arm_id)_hand_tcp [rad]. Only used when hand:=true -->
  <xacro:arg name="tcp_rpy" default="0 0 0" />

  <!-- Is the robot being simulated in gazebo?" -->
  <xacro:arg name="gazebo" default="false" />
  <!-- If `gazebo` arg is set, to which frame shall $(arm_id)_link0 be parented. Empty string for not fixing at all -->
  <xacro:arg name="parent" default="world" />
  <!-- If `gazebo` arg is set and `parent` not empty, what position offset between `parent` & $(arm_id)_link0 -->
  <xacro:arg name="xyz" default="0 0 0" />
  <!-- If `gazebo` arg is set and `parent` not empty, what rotation offset between `parent` & $(arm_id)_link0 -->
  <xacro:arg name="rpy" default="0 0 0" />

  <xacro:franka_robot arm_id="$(arg arm_id)"
                      joint_limits="${xacro.load_yaml('$(find franka_description)/robots/fr3/joint_limits.yaml')}"
                      hand="$(arg hand)"
                      tcp_xyz="$(arg tcp_xyz)"
                      tcp_rpy="$(arg tcp_rpy)"
                      gazebo="$(arg gazebo)"
                      parent="$(arg parent)"
                      xyz="$(arg xyz)"
                      rpy="$(arg rpy)">
  </xacro:franka_robot>

</robot>

主要包含以下内容:

  1. 根元素 <robot>定义了机器人的名称。

  2. xacro:include引入了另一个URDF文件franka_robot.xacro,这个文件可能包含了Franka机器人的核心定义。

  3. 通过一系列 xacro:arg元素定义了一些参数,包括:

    • arm_id: 机器人臂的ID
    • hand: 是否安装了夹持器
    • tcp_xyz和tcp_rpy: 夹持器TCP的位置和旋转角度偏移
    • gazebo: 是否在Gazebo仿真环境中使用
    • parent、xyz和rpy: Gazebo仿真中机器人基座的父坐标系及其位置和旋转偏移
  4. xacro:franka_robot元素是Franka机器人的主要定义,它使用了前面定义的参数。

 

franka_robot.xacro

<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
  <xacro:macro name="franka_robot" params="arm_id joint_limits parent:='world' xyz:='0 0 0' rpy:='0 0 0' hand:=false gazebo:=false tcp_xyz:='0 0 0.1034' tcp_rpy='0 0 0'">

    <xacro:include filename="$(find franka_description)/robots/common/utils.xacro" />
    <xacro:include filename="$(find franka_description)/robots/common/franka_arm.xacro" />

    <xacro:franka_arm arm_id="${arm_id}" safety_distance="0.03" gazebo="${gazebo}" joint_limits="${joint_limits}"/>

    <xacro:if value="${hand}">
      <xacro:include filename="$(find franka_description)/robots/common/franka_hand.xacro"/>
      <xacro:franka_hand
          arm_id="${arm_id}"
          rpy="0 0 ${-pi/4}"
          tcp_xyz="${tcp_xyz}"
          tcp_rpy="${tcp_rpy}"
          connected_to="${arm_id}_link8"
          safety_distance="0.03"
          gazebo="${gazebo}"
       />
    </xacro:if>

    <!-- Define additional Gazebo tags -->
    <xacro:if value="${gazebo}">

      <xacro:if value="${parent != ''}">
        <!-- Gazebo requires a joint to a link called "world" for statically mounted robots -->
        <xacro:if value="${parent == 'world'}">
          <link name="${parent}" />
        </xacro:if>
        <joint name="${parent}_joint" type="fixed">
          <origin xyz="${xyz}" rpy="${rpy}" />
          <parent link="${parent}" />
          <child  link="${arm_id}_link0" />
        </joint>
      </xacro:if>

      <xacro:gazebo-joint joint="${arm_id}_joint1" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint2" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint3" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint4" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint5" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint6" transmission="hardware_interface/PositionJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint7" transmission="hardware_interface/PositionJointInterface" />

      <xacro:gazebo-joint joint="${arm_id}_joint1" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint2" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint3" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint4" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint5" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint6" transmission="hardware_interface/VelocityJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint7" transmission="hardware_interface/VelocityJointInterface" />

      <xacro:gazebo-joint joint="${arm_id}_joint1" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint2" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint3" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint4" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint5" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint6" transmission="hardware_interface/EffortJointInterface" />
      <xacro:gazebo-joint joint="${arm_id}_joint7" transmission="hardware_interface/EffortJointInterface" />

      <xacro:transmission-franka-state arm_id="${arm_id}" />
      <xacro:transmission-franka-model arm_id="${arm_id}"
         root="${arm_id}_joint1"
         tip="${arm_id}_joint8"
       />

      <xacro:if value="${hand}">
        <xacro:gazebo-joint joint="${arm_id}_finger_joint1" transmission="hardware_interface/EffortJointInterface" />
        <xacro:gazebo-joint joint="${arm_id}_finger_joint2" transmission="hardware_interface/EffortJointInterface" />
        <!-- Friction specific material for Rubber/Rubber contact -->
        <xacro:gazebo-friction link="${arm_id}_leftfinger" mu="1.13" />
        <xacro:gazebo-friction link="${arm_id}_rightfinger" mu="1.13" />
      </xacro:if>

      <gazebo>
        <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
          <controlPeriod>0.001</controlPeriod>
          <robotSimType>franka_gazebo/FrankaHWSim</robotSimType>
        </plugin>
        <self_collide>true</self_collide>
      </gazebo>
    </xacro:if>
  </xacro:macro>
</robot>

这段代码是一个 ROS (Robot Operating System) 中的 URDF (统一机器人描述格式) 文件,用于定义 Franka 机器人的参数和属性。下面我对这段代码进行逐步解释:

  1. 这个 URDF 文件使用了 xacro 宏,可以通过参数化的方式定义机器人的属性。

  2. franka_robot 宏定义了 Franka 机器人的整体结构,包括机械臂和可选的机械手。可以通过设置参数来决定是否包含机械手,以及机器人在 Gazebo 模拟器中的显示。

  3. 这个宏引用了另外两个 xacro 文件:

    • franka_arm.xacro: 定义了 Franka 机械臂的结构和联动关系。
    • franka_hand.xacro: 定义了 Franka 机械手的结构和联动关系。
  4. 对于 Gazebo 模拟,这个宏定义了以下内容:

    • 将机器人固定在世界坐标系或其他链接上。
    • 为每个关节定义了三种不同的接口:位置、速度和力矩。
    • 定义了 Gazebo 中的插件,用于控制机器人的仿真。

总的来说,这个 URDF 文件提供了一种灵活的方式来定义 Franka 机器人的结构和属性,方便在 ROS 和 Gazebo 中进行仿真和控制。通过设置不同的参数,可以快速生成各种不同配置的 Franka 机器人模型。

 

utils.xacro

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

  <!-- Load inertial properties. Property is implicitly passed to macros. -->
  <xacro:property name="inertial_config" value="$(find franka_description)/robots/common/inertial.yaml"/>
  <xacro:property name="inertial" value="${xacro.load_yaml(inertial_config)}"/>

  <!-- ============================================================== -->
  <!-- Macro to add an <inertial> tag based on yaml-load properties   -->
  <!--                                                                -->
  <!-- name:     Name of the robot link (without prefix)              -->
  <!-- inertial: Dictionary of inertia properties (see inertial.yaml) -->
  <!-- ============================================================== -->
  <xacro:macro name="inertial_props" params="name inertial:=^">
      <xacro:unless value="${name in inertial}">${xacro.warning('No inertia properties defined for: ' + name)}</xacro:unless>
      <xacro:if value="${name in inertial}">
        <!-- Access inertia properties of link 'name' -->
        <xacro:property name="inertial" value="${inertial[name]}" lazy_eval="false" />
        <inertial>
          <origin rpy="${inertial.origin.rpy}" xyz="${inertial.origin.xyz}" />
          <mass value="${inertial.mass}" />
          <xacro:property name="I" value="${inertial.inertia}" />
          <inertia ixx="${I.xx}" ixy="${I.xy}" ixz="${I.xz}" iyy="${I.yy}" iyz="${I.yz}" izz="${I.zz}" />
        </inertial>
      </xacro:if>
  </xacro:macro>

  <!-- ========================================================== -->
  <!-- Macro to add a single link, both with                      -->
  <!--  * detailed meshes for environmental collision checking    -->
  <!--  * and coarse geometry models for self-collision checking  -->
  <!--    (only if 'gazebo' param is set)                         -->
  <!--                                                            -->
  <!-- name:  Name of the robot link (without prefix)             -->
  <!-- rpy:   Rotation of the *_sc link relative to parent [rad]  -->
  <!-- self_collision_geometries:  self <collision> models        -->
  <!-- ========================================================== -->
  <xacro:macro name="link_with_sc" params="name prefix=${arm_id}_ rpy:='0 0 0' **self_collision_geometries gazebo:=false">
    <!-- sub-link defining detailed meshes for collision with environment -->
    <link name="${prefix}${name}">
      <visual>
        <geometry>
          <mesh filename="package://${description_pkg}/meshes/visual/${name}.dae" />
        </geometry>
      </visual>
      <collision>
        <geometry>
          <mesh filename="package://franka_description/meshes/collision/${name}.stl" />
        </geometry>
      </collision>
      <xacro:if value="${gazebo}">
        <xacro:inertial_props name="${name}" />
      </xacro:if>
    </link>
    <!-- sub-link defining coarse geometries of real robot's internal self-collision -->
    <link name="${prefix}${name}_sc">
      <xacro:unless value="${gazebo}">
        <xacro:insert_block name="self_collision_geometries" />
      </xacro:unless>
    </link>
    <!-- fixed joint between both sub-links -->
    <joint name="${prefix}${name}_sc_joint" type="fixed">
      <origin rpy="${rpy}" />
      <parent link="${prefix}${name}" />
      <child link="${prefix}${name}_sc" />
    </joint>
  </xacro:macro>

  <!-- =========================================================== -->
  <!-- Add a <collision> tag with a capsule, made from a cylinder  -->
  <!-- with two spheres at its caps. The capsule will always be    -->
  <!-- aligned with the axis of 'direction' you pass along.        -->
  <!--                                                             -->
  <!-- radius: Radii of both the cylinder and both spheres [m]     -->
  <!-- length: Length of the cylinder/distance between the centers -->
  <!--         of the spheres. NOT overall length of capsule!      -->
  <!-- xyz:    Position of the center of the capsule/cylinder      -->
  <!-- direction: One of { x, y, z, -x, -y, -z }                   -->
  <!-- =========================================================== -->
<!-- =========================================================== -->
<!-- 添加一个由圆柱和两个球体组成的胶囊型 <collision> 标签 -->
<!-- 胶囊将始终与您传入的 'direction' 轴向对齐。 --> <!-- -->
<!-- radius: 圆柱和两个球体的半径 [m] -->
<!-- length: 圆柱的长度/两个球体中心之间的距离。 -->
<!-- 不是胶囊的总长度! -->
<!-- xyz: 胶囊/圆柱中心的位置 -->
<!-- direction: 取值为 { x, y, z, -x, -y, -z } 之一 -->
<!-- =========================================================== -->
<xacro:macro name="collision_capsule" params="radius length xyz:='0 0 0' direction:='z'"> <xacro:property name="r" value="${pi/2.0 if 'y' in direction else 0}" /> <xacro:property name="p" value="${pi/2.0 if 'x' in direction else 0}" /> <xacro:property name="y" value="0" /> <xacro:property name="x" value="${xyz.split(' ')[0]}" /> <xacro:property name="y" value="${xyz.split(' ')[1]}" /> <xacro:property name="z" value="${xyz.split(' ')[2]}" /> <!-- Sphere center offsets from center of cylinder --> <xacro:property name="sx" value="${length / 2.0 if 'x' in direction else 0}" /> <xacro:property name="sy" value="${length / 2.0 if 'y' in direction else 0}" /> <xacro:property name="sz" value="${length / 2.0 if 'z' in direction else 0}" /> <collision> <origin xyz="${x} ${y} ${z}" rpy="${r} ${p} ${y}"/> <geometry> <cylinder radius="${radius}" length="${length}" /> </geometry> </collision> <collision> <origin xyz="${x+sx} ${y+sy} ${z+sz}" /> <geometry> <sphere radius="${radius}" /> </geometry> </collision> <collision> <origin xyz="${x-sx} ${y-sy} ${z-sz}" /> <geometry> <sphere radius="${radius}" /> </geometry> </collision> </xacro:macro> <!-- ========================================================== --> <!-- Adds the required tags to simulate one joint in gazebo --> <!-- --> <!-- joint - Name of the panda joint to simulate --> <!-- transmission - type of the transmission of the joint --> <!-- ========================================================== -->
<!-- ========================================================== -->
<!-- 添加所需的标签来在Gazebo中模拟一个关节 -->
<!-- -->
<!-- joint - 要模拟的Panda关节的名称 -->
<!-- transmission - 关节传动类型 -->
<!-- ========================================================== -->
<xacro:macro name="gazebo-joint" params="joint transmission:=hardware_interface/EffortJointInterface"> <gazebo reference="${joint}"> <!-- Needed for ODE to output external wrenches on joints --> <provideFeedback>true</provideFeedback> </gazebo> <transmission name="${joint}_transmission"> <type>transmission_interface/SimpleTransmission</type> <joint name="${joint}"> <hardwareInterface>${transmission}</hardwareInterface> </joint> <actuator name="${joint}_motor"> <hardwareInterface>${transmission}</hardwareInterface> </actuator> </transmission> </xacro:macro>

   <!-- link: 要应用摩擦属性的链接名称。
     mu1: 与地面接触时的摩擦系数。
     mu2: 滑动接触时的摩擦系数。
     kp: 滚动接触时的摩擦系数。
     kd: 滚动接触时的阻尼系数。-->

  <xacro:macro name="gazebo-friction" params="link mu">
    <gazebo reference="${link}">
      <collision>
        <max_contacts>10</max_contacts>
        <surface>
          <contact>
            <ode>
              <!-- These two parameter need application specific tuning. -->
              <!-- Usually you want no "snap out" velocity and a generous -->
              <!-- penetration depth to keep the grasping stable -->
              <max_vel>0</max_vel>
              <min_depth>0.001</min_depth>
            </ode>
          </contact>
          <friction>
            <ode>
              <mu>${mu}</mu>
              <mu2>${mu}</mu2>
            </ode>
          </friction>
          <bounce/>
        </surface>
      </collision>
    </gazebo>
  </xacro:macro>

  <!-- ========================================================== -->
  <!-- Adds the required tags to provide a `FrankaStateInterface` -->
  <!-- when simulating with franka_hw_sim plugin                  -->
  <!--                                                            -->
  <!-- arm_id - Arm ID of the panda to simulate (default 'panda') -->
  <!-- ========================================================== -->
<!-- ========================================================== --> 
<!-- 在使用 franka_hw_sim 插件进行仿真时,添加提供 FrankaStateInterface 所需的标签 --> 
<!-- --> 
<!-- arm_id - 要模拟的 Panda 机械臂的 ID (默认为 'panda') -->
  <!-- ========================================================== -->
<xacro:macro name="transmission-franka-state" params="arm_id:=panda"> <transmission name="${arm_id}_franka_state"> <type>franka_hw/FrankaStateInterface</type> <joint name="${arm_id}_joint1"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint2"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint3"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint4"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint5"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint6"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <joint name="${arm_id}_joint7"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint> <actuator name="${arm_id}_motor1"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor2"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor3"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor4"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor5"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor6"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> <actuator name="${arm_id}_motor7"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator> </transmission> </xacro:macro> <!-- ============================================================ --> <!-- Adds the required tags to provide a `FrankaModelInterface` --> <!-- when simulating with franka_hw_sim plugin --> <!-- --> <!-- arm_id - Arm ID of the panda to simulate (default 'panda') --> <!-- root - Joint name of the base of the robot --> <!-- tip - Joint name of the tip of the robot (flange or hand) --> <!-- ============================================================ --> <xacro:macro name="transmission-franka-model" params="arm_id:=panda root:=panda_joint1 tip:=panda_joint7"> <transmission name="${arm_id}_franka_model"> <type>franka_hw/FrankaModelInterface</type> <joint name="${root}"> <role>root</role> <hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface> </joint> <joint name="${tip}"> <role>tip</role> <hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface> </joint> <actuator name="${root}_motor_root"><hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface></actuator> <actuator name="${tip}_motor_tip" ><hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface></actuator> </transmission> </xacro:macro> <xacro:macro name="inertia-cylinder" params="mass radius h"> <inertial> <mass value="${mass}" /> <inertia ixx="${1./12 * mass * (3 * radius**2 + h**2)}" ixy = "0" ixz = "0" iyy="${1./12 * mass * (3 * radius**2 + h**2)}" iyz = "0" izz="${1./2 * mass * radius**2}" /> </inertial> </xacro:macro> <!-- ========================================================================= --> <!-- Adds the <limit ... /> & <safety_controller/> tags given a config file --> <!-- of joint limits --> <!-- --> <!-- config - YAML struct defining joint limits (e.g. panda/joint_limits.yaml) --> <!-- name - Name of the joint for which to add limits to --> <!-- ========================================================================= --> <xacro:macro name="franka-limits" params="config name"> <xacro:property name="limits" value="${config[name]['limit']}" lazy_eval="false" /> <limit lower="${limits.lower}" upper="${limits.upper}" effort="${limits.effort}" velocity="${limits.velocity}" /> <safety_controller k_position="100.0" k_velocity="40.0" soft_lower_limit="${limits.lower}" soft_upper_limit="${limits.upper}" /> </xacro:macro> </robot>

 

 

franka_arm.axcro

<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="panda">

  <xacro:include filename="$(find franka_description)/robots/common/utils.xacro" />

  <!-- safety_distance: Minimum safety distance in [m] by which the collision volumes are expanded and which is enforced during robot motions -->
  <!-- arm_id: Namespace of the robot arm. Serves to differentiate between arms in case of multiple instances. -->
  <!-- joint_limits: description of the joint limits that comes from a YAML file. Example definition: ${xacro.load_yaml('$(find franka_description)/robots/fr3/joint_limits.yaml')} -->
  <xacro:macro name="franka_arm" params="arm_id:='panda' description_pkg:='franka_description' connected_to:='' xyz:='0 0 0' rpy:='0 0 0' gazebo:=false safety_distance:=0 joint_limits" >
    <xacro:unless value="${not connected_to}">
      <joint name="${arm_id}_joint_${connected_to}" type="fixed">
        <parent link="${connected_to}"/>
        <child link="${arm_id}_link0"/>
        <origin rpy="${rpy}" xyz="${xyz}"/>
      </joint>
    </xacro:unless>

    <xacro:link_with_sc name="link0" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="-0.075 0 0.06" direction="x" radius="${0.06+safety_distance}" length="0.03" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <xacro:link_with_sc name="link1" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 -191.5e-3" radius="${0.06+safety_distance}" length="0.283" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint1" type="revolute">
      <origin rpy="0 0 0" xyz="0 0 0.333" />
      <parent link="${arm_id}_link0" />
      <child link="${arm_id}_link1" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint1" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link2" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 0" radius="${0.06+safety_distance}" length="0.12" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint2" type="revolute">
      <origin rpy="${-pi/2} 0 0" xyz="0 0 0" />
      <parent link="${arm_id}_link1" />
      <child link="${arm_id}_link2" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint2" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link3" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 -0.145" radius="${0.06+safety_distance}" length="0.15" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint3" type="revolute">
      <origin rpy="${pi/2} 0 0" xyz="0 -0.316 0" />
      <parent link="${arm_id}_link2" />
      <child link="${arm_id}_link3" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint3" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link4" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 0" radius="${0.06+safety_distance}" length="0.12" />
     </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint4" type="revolute">
      <origin rpy="${pi/2} 0 0" xyz="0.0825 0 0" />
      <parent link="${arm_id}_link3" />
      <child link="${arm_id}_link4" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint4" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link5" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 -0.26"    radius="${0.060+safety_distance}" length="0.10" />
        <xacro:collision_capsule xyz="0 0.08 -0.13" radius="${0.025+safety_distance}" length="0.14" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint5" type="revolute">
      <origin rpy="${-pi/2} 0 0" xyz="-0.0825 0.384 0" />
      <parent link="${arm_id}_link4" />
      <child link="${arm_id}_link5" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint5" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link6" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 -0.03" radius="${0.05+safety_distance}" length="0.08" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint6" type="revolute">
      <origin rpy="${pi/2} 0 0" xyz="0 0 0" />
      <parent link="${arm_id}_link5" />
      <child link="${arm_id}_link6" />
      <axis xyz="0 0 1" />
      <xacro:franka-limits name="joint6" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16" />
    </joint>

    <xacro:link_with_sc name="link7" gazebo="${gazebo}" rpy="0 0 ${pi/4}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 0.01" direction="z" radius="${0.04+safety_distance}" length="0.14" />
        <xacro:collision_capsule xyz="0.06 0 0.082" direction="x" radius="${0.03+safety_distance}"  length="0.01" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <joint name="${arm_id}_joint7" type="revolute">
      <origin rpy="${pi/2} 0 0" xyz="0.088 0 0"/>
      <parent link="${arm_id}_link6"/>
      <child link="${arm_id}_link7"/>
      <axis xyz="0 0 1"/>
      <xacro:franka-limits name="joint7" config="${joint_limits}" />
      <dynamics D="1" K="7000" damping="0.003" friction="0.0" mu_coulomb="0" mu_viscous="16"/>
    </joint>

    <link name="${arm_id}_link8"/>

    <joint name="${arm_id}_joint8" type="fixed">
      <origin rpy="0 0 0" xyz="0 0 0.107"/>
      <parent link="${arm_id}_link7"/>
      <child link="${arm_id}_link8"/>
    </joint>
  </xacro:macro>
</robot>

franka_hand.xacro

<?xml version="1.0" encoding="utf-8"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="hand">
  <!-- safety_distance: Minimum safety distance in [m] by which the collision volumes are expanded and which is enforced during robot motions -->
  <xacro:macro name="franka_hand" params="connected_to:='' arm_id:='panda' rpy:='0 0 0' xyz:='0 0 0' tcp_xyz:='0 0 0.1034' tcp_rpy:='0 0 0' safety_distance:=0 gazebo:=false description_pkg:=franka_description">
    <xacro:unless value="${connected_to == ''}">
      <joint name="${arm_id}_hand_joint" type="fixed">
        <parent link="${connected_to}" />
        <child link="${arm_id}_hand" />
        <origin xyz="${xyz}" rpy="${rpy}" />
      </joint>
    </xacro:unless>

    <xacro:link_with_sc name="hand" gazebo="${gazebo}">
      <self_collision_geometries>
        <xacro:collision_capsule xyz="0 0 0.04" direction="y" radius="${0.04+safety_distance}" length="0.1" />
        <xacro:collision_capsule xyz="0 0 0.10" direction="y" radius="${0.02+safety_distance}" length="0.1" />
      </self_collision_geometries>
    </xacro:link_with_sc>

    <!-- Define the hand_tcp frame -->
    <link name="${arm_id}_hand_tcp" />
    <joint name="${arm_id}_hand_tcp_joint" type="fixed">
      <origin xyz="${tcp_xyz}" rpy="${tcp_rpy}" />
      <parent link="${arm_id}_hand" />
      <child link="${arm_id}_hand_tcp" />
    </joint>
    <link name="${arm_id}_leftfinger">
      <visual>
        <geometry>
          <mesh filename="package://${description_pkg}/meshes/visual/finger.dae" />
        </geometry>
      </visual>
      <!-- screw mount -->
      <collision>
        <origin xyz="0 18.5e-3 11e-3" rpy="0 0 0" />
        <geometry>
          <box size="22e-3 15e-3 20e-3" />
        </geometry>
      </collision>
      <!-- cartriage sledge -->
      <collision>
        <origin xyz="0 6.8e-3 2.2e-3" rpy="0 0 0" />
        <geometry>
          <box size="22e-3 8.8e-3 3.8e-3" />
        </geometry>
      </collision>
      <!-- diagonal finger -->
      <collision>
        <origin xyz="0 15.9e-3 28.35e-3" rpy="${pi/6} 0 0" />
        <geometry>
          <box size="17.5e-3 7e-3 23.5e-3" />
        </geometry>
      </collision>
      <!-- rubber tip with which to grasp -->
      <collision>
        <origin xyz="0 7.58e-3 45.25e-3" rpy="0 0 0" />
        <geometry>
          <box size="17.5e-3 15.2e-3 18.5e-3" />
        </geometry>
      </collision>
      <xacro:if value="${gazebo}">
        <xacro:inertial_props name="leftfinger" />
      </xacro:if>
    </link>
    <link name="${arm_id}_rightfinger">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 ${pi}" />
        <geometry>
          <mesh filename="package://${description_pkg}/meshes/visual/finger.dae" />
        </geometry>
      </visual>
      <!-- screw mount -->
      <collision>
        <origin xyz="0 -18.5e-3 11e-3" rpy="0 0 0" />
        <geometry>
          <box size="22e-3 15e-3 20e-3" />
        </geometry>
      </collision>
      <!-- cartriage sledge -->
      <collision>
        <origin xyz="0 -6.8e-3 2.2e-3" rpy="0 0 0" />
        <geometry>
          <box size="22e-3 8.8e-3 3.8e-3" />
        </geometry>
      </collision>
      <!-- diagonal finger -->
      <collision>
        <origin xyz="0 -15.9e-3 28.35e-3" rpy="${-pi/6} 0 0" />
        <geometry>
          <box size="17.5e-3 7e-3 23.5e-3" />
        </geometry>
      </collision>
      <!-- rubber tip with which to grasp -->
      <collision>
        <origin xyz="0 -7.58e-3 45.25e-3" rpy="0 0 0" />
        <geometry>
          <box size="17.5e-3 15.2e-3 18.5e-3" />
        </geometry>
      </collision>
      <xacro:if value="${gazebo}">
        <xacro:inertial_props name="rightfinger" />
      </xacro:if>
    </link>
    <joint name="${arm_id}_finger_joint1" type="prismatic">
      <parent link="${arm_id}_hand" />
      <child link="${arm_id}_leftfinger" />
      <origin xyz="0 0 0.0584" rpy="0 0 0" />
      <axis xyz="0 1 0" />
      <limit effort="100" lower="0.0" upper="0.04" velocity="0.2" />
      <dynamics damping="0.3" />
    </joint>
    <joint name="${arm_id}_finger_joint2" type="prismatic">
      <parent link="${arm_id}_hand" />
      <child link="${arm_id}_rightfinger" />
      <origin xyz="0 0 0.0584" rpy="0 0 0" />
      <axis xyz="0 -1 0" />
      <limit effort="100" lower="0.0" upper="0.04" velocity="0.2" />
      <mimic joint="${arm_id}_finger_joint1" />
      <dynamics damping="0.3" />
    </joint>
  </xacro:macro>
</robot>

hand.urdf.xacro

<?xml version="1.0" encoding="utf-8"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="hand">
  <xacro:include filename="$(find franka_description)/robots/common/utils.xacro" />
  <xacro:include filename="franka_hand.xacro"/>
  <xacro:franka_hand arm_id="panda" safety_distance="0.03"/>
</robot>

inertial.yam

# This file does not contain official inertial properties
# of panda robot. The values are from the identification
# results published in: Identification of the Franka Robotics
# PandaRobot With Retrieval of Feasible Parameters Using
# Penalty-Based Optimization
# by: Claudio Gaz, Marco Cognetti, Alexander Oliva,
# Paolo Robuffo Giordano, Alessandro de Luca
link0:
  origin:
    xyz: -0.041018 -0.00014 0.049974
    rpy: 0 0 0
  mass: 0.629769
  inertia:
    xx: 0.00315
    yy: 0.00388
    zz: 0.004285
    xy: 8.2904E-07
    xz: 0.00015
    yz: 8.2299E-06

link1:
  origin:
    xyz: 0.003875 0.002081 -0.04762
    rpy: 0 0 0
  mass: 4.970684
  inertia:
    xx: 0.70337
    yy: 0.70661
    zz: 0.0091170
    xy: -0.00013900
    xz: 0.0067720
    yz: 0.019169

link2:
  origin:
    xyz:  -0.003141 -0.02872  0.003495
    rpy: 0 0 0
  mass: 0.646926
  inertia:
    xx: 0.0079620
    yy: 2.8110e-02
    zz: 2.5995e-02
    xy: -3.9250e-3
    xz: 1.0254e-02
    yz: 7.0400e-04

link3:
  origin:
    xyz: 2.7518e-02 3.9252e-02 -6.6502e-02
    rpy: 0 0 0
  mass: 3.228604
  inertia:
    xx: 3.7242e-02
    yy: 3.6155e-02
    zz: 1.0830e-02
    xy: -4.7610e-03
    xz: -1.1396e-02
    yz: -1.2805e-02

link4:
  origin:
    xyz: -5.317e-02 1.04419e-01 2.7454e-02
    rpy: 0 0 0
  mass: 3.587895
  inertia:
    xx: 2.5853e-02
    yy: 1.9552e-02
    zz: 2.8323e-02
    xy: 7.7960e-03
    xz: -1.3320e-03
    yz: 8.6410e-03

link5:
  origin:
    xyz: -1.1953e-02 4.1065e-02 -3.8437e-02
    rpy: 0 0 0
  mass: 1.225946
  inertia:
    xx: 3.5549e-02
    yy: 2.9474e-02
    zz: 8.6270e-03
    xy: -2.1170e-03
    xz: -4.0370e-03
    yz: 2.2900e-04

link6:
  origin:
    xyz: 6.0149e-02 -1.4117e-02 -1.0517e-02
    rpy: 0 0 0
  mass: 1.666555
  inertia:
    xx: 1.9640e-03
    yy: 4.3540e-03
    zz: 5.4330e-03
    xy: 1.0900e-04
    xz: -1.1580e-03
    yz: 3.4100e-04

link7:
  origin:
    xyz: 1.0517e-02 -4.252e-03 6.1597e-02
    rpy: 0 0 0
  mass: 7.35522e-01
  inertia:
    xx: 1.2516e-02
    yy: 1.0027e-02
    zz: 4.8150e-03
    xy: -4.2800e-04
    xz: -1.1960e-03
    yz: -7.4100e-04

hand:
  origin:
    xyz: -0.01 0 0.03
    rpy: 0 0 0
  mass: 0.73
  inertia:
    xx: 0.001
    yy: 0.0025
    zz: 0.0017
    xy: 0
    xz: 0
    yz: 0

leftfinger: &finger
  origin:
    xyz: 0 0 0
    rpy: 0 0 0
  mass: 0.015
  inertia:
    xx: 2.3749999999999997e-06
    yy: 2.3749999999999997e-06
    zz: 7.5e-07
    xy: 0
    xz: 0
    yz: 0
rightfinger: *finger

 

FER(Panda)同样适用:

xacro $(rospack find franka_description)/robots/panda/panda.urdf.axcro gazebo:=true
<?xml version='1.0' encoding='utf-8'?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="panda">

  <xacro:include filename="$(find franka_description)/robots/common/franka_robot.xacro"/>

  <!-- Name for this robot -->
  <xacro:arg name="arm_id" default="panda" />

  <!-- Should a franka_gripper be mounted at the flange?" -->
  <xacro:arg name="hand" default="false" />
  <!-- Positional offset between $(arm_id)_hand -> $(arm_id)_hand_tcp [m]. Only used when hand:=true -->
  <xacro:arg name="tcp_xyz" default="0 0 0.1034" />
  <!-- Rotational offset between $(arm_id)_hand -> $(arm_id)_hand_tcp [rad]. Only used when hand:=true -->
  <xacro:arg name="tcp_rpy" default="0 0 0" />

  <!-- Is the robot being simulated in gazebo?" -->
  <xacro:arg name="gazebo" default="false" />
  <!-- If `gazebo` arg is set, to which frame shall $(arm_id)_link0 be parented. Empty string for not fixing at all -->
  <xacro:arg name="parent" default="world" />
  <!-- If `gazebo` arg is set and `parent` not empty, what position offset between `parent` & $(arm_id)_link0 -->
  <xacro:arg name="xyz" default="0 0 0" />
  <!-- If `gazebo` arg is set and `parent` not empty, what rotation offset between `parent` & $(arm_id)_link0 -->
  <xacro:arg name="rpy" default="0 0 0" />

  <xacro:franka_robot arm_id="$(arg arm_id)"
                      joint_limits="${xacro.load_yaml('$(find franka_description)/robots/panda/joint_limits.yaml')}"
                      hand="$(arg hand)"
                      tcp_xyz="$(arg tcp_xyz)"
                      tcp_rpy="$(arg tcp_rpy)"
                      gazebo="$(arg gazebo)"
                      parent="$(arg parent)"
                      xyz="$(arg xyz)"
                      rpy="$(arg rpy)">
  </xacro:franka_robot>

</robot>

 

 

体积碰撞

 URDF定义了两种类型的碰撞类型:

  • 精细:这些碰撞体积由凸网格构成,这些凸网格是每个链接的视觉网格 (.dae) 的近似版本,并且经过了大幅简化。精细体积应用于在Gazebo中模拟机器人碰撞

  • 粗略:这些碰撞体积只是胶囊(带有两个半球形端盖的圆柱体),附在每个连杆上,并充气一定的安全距离。这些体积计算起来更高效,并在机器人内部用于自我碰撞避免。当您计划运动时(例如使用MoveIt ) ,请使用这些几何体。

 

 

 

您可以通过 XACRO 参数控制将哪个碰撞模型加载到 URDF 中gazebo

  • xacro ... panda.urdf.xacro gazebo:=false:这将使用精细和粗糙碰撞模型。如果您完全省略参数,这也是默认设置。当您想要使用 MoveIt 时,请使用此选项

  • xacro ... panda.urdf.xacro gazebo:=true:这将使用精细碰撞模型。当您想要可模拟的 URDF(例如 Gazebo)时,请使用此选项。当使用粗略碰撞模型时,机器人当然会与下一个链接的胶囊不断发生碰撞。

 

franka_gripper

此包实现了franka_gripper_node从 ROS 连接夹钳的功能。节点发布夹钳的状态并提供以下操作服务
     franka_gripper::MoveAction(width, speed)width:移动到具有定义的 目标speed。
  • franka_gripper::MoveAction(width, speed):以定义的速度移动到目标宽度。
  • franka_gripper::GraspAction(width, epsilon_inner, epsilon_outer, speed, force):尝试以给定的速度和所需的力在目标宽度处抓取。当夹爪指间的距离在 epsilon_inner 和 epsilon_outer 之间时,操作成功。
  • franka_gripper::HomingAction():复位夹爪并根据安装的指头更新最大宽度。
  • franka_gripper::StopAction():中止正在运行的动作。可以在抓取后用来停止施加力量。
  • control_msgs::GripperCommandAction(width, max_effort):一个由 MoveIt! 识别的标准夹爪动作。如果参数 max_effort 大于零,夹爪将尝试以所需的宽度抓取物体。另一方面,如果 max_effort 为零,夹爪将移动到所需的宽度。

          注意: 仅在抓取物体时使用参数 max_effort,否则夹爪将会闭合而忽略宽度参数。

您可以使用以下franka_gripper_node方式启动:
roslaunch franka_gripper franka_gripper.launch robot_ip:=<fci-ip>

注意: franka_ros0.6.0 开始,指定load_gripper:=true 将启动。 

roslaunch franka_control franka_control.launch

franka_hw

此包包含基于 API 的 ROS 控制框架的机器人硬件抽象libfranka此包中实现了硬件类franka_hw::FrankaHW为控制器提供了以下接口:

接口 功能 资源句柄名称
hardware_interface::JointStateInterface 读取关节状态。 "<arm_id>_joint1" 至 "<arm_id>_joint7"
hardware_interface::VelocityJointInterface 控制关节速度,并读取关节状态。 "<arm_id>_joint1" 至 "<arm_id>_joint7"
hardware_interface::PositionJointInterface 控制关节位置并读取关节状态。 "<arm_id>_joint1" 至 "<arm_id>_joint7"
hardware_interface::EffortJointInterface 控制关节扭矩并读取关节状态。 "<arm_id>_joint1" 至 "<arm_id>_joint7"
franka_hw::FrankaStateInterface 读取机器人完整状。 “<arm_id>_robot”
franka_hw::FrankaPoseCartesianInterface 控制笛卡尔位姿并读取机器人完整状态。 “<arm_id>_robot”
franka_hw::FrankaVelocityCartesianInterface 控制笛卡尔速度并读取机器人完整状态。 “<arm_id>_robot”
franka_hw::FrankaModelInterface 读取机器人的运动学和动力学模型。 “<arm_id>_robot”

要使用 ROS 控制接口,您必须通过名称检索资源句柄。

默认情况下,<arm_id> 设置为“panda”。

该类franka_hw::FrankaHW还实现控制器的启动,停止和切换。

FrankaHW 类也作为 FrankaCombinableHW 的基类,后者是一种可以与其他硬件类组合以从单个控制器控制多个机器人的硬件类。基于 FrankaCombinableHW 的 ROS 控制框架中任意数量的 Panda 机器人(数量由参数配置)的组合在 FrankaCombinedHW 中实现。FrankaHW 和 FrankaCombinedHW 之间的主要区别在于后者仅支持力矩控制。

FrankaCombinableHW 类从 0.7.0 版本开始提供,并且仅支持力矩/力控制。

Ros参数服务器被用来决定运行时加载了哪些机器人,有关如何在相应的硬件节点中配置 FrankaCombinedHW 的示例,请参见 franka_control。

FrankaHW的方法是控制单个机器人的最佳方法。因此,我们建议仅在控制多个机器人时使用FrankaCombinableHW/FrankaCombinedHW类。

FrankaCombinableHW/FrankaCombinedHW提供的接口如下:

接口 功能
hardware_interface::EffortJointInterface 关节级别扭矩控制,并读取关节状态。
hardware_interface::JointStateInterface 读取关节状态。
franka_hw::FrankaStateInterface 读取机器人整体状态。
franka_hw::FrankaModelInterface 读取机器人运动学和动力学模型。

 

唯一允许的命令接口声明是 EffortJointInterface,它可以与任何一组只读接口(FrankaModelInterface、JointStateInterface、FrankaStateInterface)结合使用。所有接口提供的资源句柄按名称声明,并遵循与 FrankaHW 相同的命名约定。每个 FrankaCombinableHW 实例都提供完整的服务和动作接口集(参见 franka_control)。

FrankaCombinedHW 类在控制节点命名空间中提供了一个额外的动作服务器,用于恢复所有机器人。如果任何机器人发生反射或错误,所有机器人的控制循环将停止,直到它们被恢复。

 Important

FrankaHW 使用 ROS joint_limits_interface 来强制执行位置、速度和力的安全限制。使用的接口如下所示:

  • joint_limits_interface::PositionJointSoftLimitsInterface
  • joint_limits_interface::VelocityJointSoftLimitsInterface
  • joint_limits_interface::EffortJointSoftLimitsInterface

接近限制将导致命令的(未通知的)修改。

franka_control:

ROS节点franka_control_node和franka_combined_control_node 是用于ROS控制的硬件节点, 使用franka_hw中相应硬件类。他们提供各种ROS服务, 以libfranka在ROS生态系统中公开完整的API。 提供以下服务:

  • franka_msgs::SetJointImpedance 指定内部控制器的关节刚度(阻尼自动从刚度得出)。

  • franka_msgs::SetCartesianImpedance指定内部控制器的笛卡尔刚度(阻尼自动从刚度得出)。

  • franka_msgs::SetEEFrame 指定从 <arm_id>_EE(末端执行器)到 <arm_id>_NE(名义末端执行器)框架的转换。从法兰到末端执行器框架的转换分为两个转换:<arm_id>_EE 到 <arm_id>_NE 框架和 <arm_id>_NE 到 <arm_id>_link8 框架。从 <arm_id>_NE 到 <arm_id>_link8 框架的转换只能通过管理员界面进行设置

  • franka_msgs::SetKFrame 指定从 <arm_id>_K 到 <arm_id>_EE 坐标的转换。

  • franka_msgs::SetForceTorqueCollisionBehavior 设置外部笛卡尔的外力阈值来配置碰撞反射。

  • franka_msgs::SetFullCollisionBehavior设置笛卡尔和关节层面的外力阈值来配置碰撞反射。

  • franka_msgs::SetLoad设置外部负载来补偿(例如,抓住的物体)。

  • std_srvs::Trigger服务允许连接和断开硬件节点(从 0.8.0 开始可用)。当没有活动(命令)控制器运行时,您可以断开硬件节点,释放相应的机器人以用于非 fci 应用程序,例如基于Desk的操作。一旦您想要恢复 fci 操作,您可以调用 connect 并再次启动基于 ros_control 的控制器。

重要的
<arm_id>_EE 框架表示可配置末端执行器坐标的一部分,可在运行时通过franka_ros进行调整。<arm_id>_K 坐标标记内部笛卡尔阻抗的中心。它还可用作外力的参考坐标。<arm_id>_EE 和 <arm_id>_K 都不包含在 URDF 中,因为它们可以在运行时更改。默认情况下,<arm_id> 设置为“panda”。

 

要在机器人处于反射模式时从错误和反射中恢复,可以利用 franka_msgs::ErrorRecoveryAction。这可以通过使用动作客户端或发布动作目标主题来实现。

具体来说:

  1. 使用动作客户端:

    • 创建一个动作客户端来调用 franka_msgs::ErrorRecoveryAction
    • 发送目标请求来恢复错误和反射状态。
    • 等待动作服务器完成并获取结果。
  2. 发布到动作目标主题:

    • 发布一条 franka_msgs::ErrorRecoveryActionGoal 消息到 /franka_control/error_recovery/goal 主题。
    • 这将触发错误恢复流程,使机器人从反射模式中恢复过来。
rostopic pub -1 /franka_control/error_recovery/goal franka_msgs/ErrorRecoveryActionGoal "{}"

恢复后,franka_control_node将重新启动正在运行的控制器。这是可能的,因为当触发机器人反射或发生错误时节点不会死亡。所有这些功能均由 franka_control_node 提供,可以使用以下命令启动:

roslaunch franka_control franka_control.launch \
robot_ip:=<fci-ip> # mandatory \
load_gripper:=<true|false> # default: true \
robot:=<panda|fr3> # default: panda

除了加载franka_control_node, 启动文件还启动了一个franka_control::FrankaStateController, 用来读取和发布机器人状态, 包括外部力矩, 可配置变换,和rviz可视化所需要的关节状态。 为了可视化目的,一个robot_state_publisher节点被启动。

该包还实现了基于类的franka_combined_control_node硬件节点。加载的机器人集通过 ROS 参数服务器配置。这些参数必须位于硬件节点的命名空间中(请参阅franka_combined_control_node.yaml 作为参考)并如下所示: 

robot_hardware:
  - panda_1
  - panda_2
  # (...)

panda_1:
  type: franka_hw/FrankaCombinableHW
  arm_id: panda_1
  joint_names:
    - panda_1_joint1
    - panda_1_joint2
    - panda_1_joint3
    - panda_1_joint4
    - panda_1_joint5
    - panda_1_joint6
    - panda_1_joint7
  # Configure the threshold angle for printing joint limit warnings.
  joint_limit_warning_threshold: 0.1 # [rad]
  # Activate rate limiter? [true|false]
  rate_limiting: true
  # Cutoff frequency of the low-pass filter. Set to >= 1000 to deactivate.
  cutoff_frequency: 1000
  # Internal controller for motion generators [joint_impedance|cartesian_impedance]
  internal_controller: joint_impedance
  # Configure the initial defaults for the collision behavior reflexes.
  collision_config:
    lower_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    lower_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]

panda_2:
  type: franka_hw/FrankaCombinableHW
  arm_id: panda_2
  joint_names:
    - panda_2_joint1
    - panda_2_joint2
    - panda_2_joint3
    - panda_2_joint4
    - panda_2_joint5
    - panda_2_joint6
    - panda_2_joint7
  # Configure the threshold angle for printing joint limit warnings.
  joint_limit_warning_threshold: 0.1 # [rad]
  # Activate rate limiter? [true|false]
  rate_limiting: true
  # Cutoff frequency of the low-pass filter. Set to >= 1000 to deactivate.
  cutoff_frequency: 1000
  # Internal controller for motion generators [joint_impedance|cartesian_impedance]
  internal_controller: joint_impedance
  # Configure the initial defaults for the collision behavior reflexes.
  collision_config:
    lower_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    lower_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]

# (+ more robots ...)

确保选择唯一且一致的arm_id参数。ID 必须与关节名称中的前缀匹配,并且应符合加载到控制节点命名空间的机器人描述。

有关基于参数加载硬件类的更多信息,请参阅https://github.com/ros-controls/ros_controlcombined_robot_hw::CombinedRobotHW的 官方文档

第二个重要参数文件(请参阅 franka_ros/franka_control/config/default_combined_controllers.yaml 作为参考)配置了一组可随硬件节点启动的默认控制器。控制器必须与启动的硬件匹配。提供的默认参数化(此处针对 2 个机器人)如下所示:

panda_1_state_controller:
  type: franka_control/FrankaStateController
  arm_id: panda_1
  joint_names:
    - panda_1_joint1
    - panda_1_joint2
    - panda_1_joint3
    - panda_1_joint4
    - panda_1_joint5
    - panda_1_joint6
    - panda_1_joint7
  publish_rate: 30  # [Hz]

panda_2_state_controller:
  type: franka_control/FrankaStateController
  arm_id: panda_2
  joint_names:
    - panda_2_joint1
    - panda_2_joint2
    - panda_2_joint3
    - panda_2_joint4
    - panda_2_joint5
    - panda_2_joint6
    - panda_2_joint7
  publish_rate: 30  # [Hz]

# (+ more controllers ...)

我们提供了一个启动文件来运行franka_combined_control_node用户指定的硬件和控制器配置文件,这些配置文件默认为 2 个机器人的配置。使用以下命令启动它:

roslaunch franka_control franka_combined_control.launch \
    robot_ips:=<your_robot_ips_as_a_map>                 # mandatory
    robot:=<path_to_your_robot_description> \
    args:=<xacro_args_passed_to_the_robot_description> \ # if needed
    robot_id:=<name_of_your_multi_robot_setup> \
    hw_config_file:=<path_to_your_hw_config_file>\       # includes the robot ips!
    controllers_file:=<path_to_your_default_controller_parameterization>\
    controllers_to_start:=<list_of_default_controllers_to_start>\
    joint_states_source_list:=<list_of_sources_to_fuse_a_complete_joint_states_topic>

此启动文件可以参数化以运行任意数量的机器人。为此,只需以 franka_control/config/franka_combined_control_node.yaml 和 franka_ros/franka_control/config/default_combined_controllers.yaml 的样式编写您自己的配置文件。

确保将机器人的正确 IP作为映射传递给franka_combined_control.launch 。这看起来像: {<arm_id_1>/robot_ip: <my_ip_1>, <arm_id_2>/robot_ip: <my_ip_2>, …}

franka_visualization

此软件包包含连接到机器人并发布机器人和夹持器关节状态以便在 RViz 中可视化的发布器。要运行此软件包,请启动:

roslaunch franka_visualization franka_visualization.launch robot_ip:=<fci-ip> \
  load_gripper:=<true|false> robot:=<panda|fr3>

仿真机器人请执行以下命令:

roslaunch franka_gazebo fr3/panda.launch
roslaunch franka_visualization franka_visualization.launch robot_ip:=fake_robot \
  load_gripper:=<true|false> robot:=<panda|fr3>

 

这纯粹是为了可视化 - 没有向机器人发送任何命令。它可以用来检查与机器人的连接。

 

 

 只能有一个 franka::Robot 实例可以连接到机器人。这意味着,例如 franka_joint_state_publisher 不能与 franka_control_node 并行运行。这也意味着你不能在运行控制器的单独程序的同时执行可视化示例。

franka_example_controllers

此包中实现了一组用于通过ROS控制机器人的示例控制器。 控制器描述了franka_hw::FrankaHW类提供的各种接口及其相应用途。 每个示例都附带了一个单独的独立启动文件, 用于启动机器人上的控制器并将其可视化。

要启动关节阻抗运动示例, 请执行以下命令:

roslaunch franka_example_controllers joint_impedance_example_controller.launch \
  robot_ip:=<fci-ip> load_gripper:=<true|false> robot:=<panda|fr3>

仿真机器人请执行以下命令:

roslaunch franka_example_controllers joint_impedance_example_controller.launch \
  robot_ip:=fake_robot load_gripper:=<true|false> robot:=<panda|fr3>

其他单个Panda示例以同样的方式启动。

展示了如何使用一个实时控制器dual_arm_cartesian_impedance_example_controller通过基于阻抗的控制方法完成笛卡尔任务来控制两个 Panda 机器人FrankaCombinedHW。示例控制器可以通过以下方式启动:

roslaunch franka_example_controllers \
    dual_arm_cartesian_impedance_example_controller.launch \
    robot_id:=<name_of_the_2_arm_setup> \
    robot_ips:=<your_robot_ips_as_a_map> \
    rviz:=<true/false> rqt:=<true/false>

该示例假设机器人配置符合dual_panda_example.urdf.xacro,其中两个 Panda 安装在一个箱子顶部,相距 1 米。您可以随意用与您的设置相匹配的机器人描述替换此机器人描述。选项rviz允许选择是否应启动可视化。使用rqt,用户可以选择启动 rqt-gui,它允许在运行时通过动态重新配置在线调整渲染的末端执行器阻抗。

franka_gazebo

此软件包允许您在Gazebo中模拟我们的机器人。这是可能的,因为 Gazebo 能够使用 gazebo_ros软件包集成到 ROS 控制框架中。

注 : 此软件包从 0.8.0 开始可用.

拾取和放置示例

让我们深入模拟将一块石头从 A 运送到 B。运行以下命令,使用 Panda 和示例世界启动 Gazebo。

roslaunch franka_gazebo panda.launch x:=-0.5 \
    world:=$(rospack find franka_gazebo)/world/stone.sdf \
    controller:=cartesian_impedance_example_controller \
    rviz:=true

这将打开 Gazebo GUI,您可以在其中看到带有石头和 RViz 的环境,您可以使用它们来控制机器人的末端执行器姿势。

 

要打开夹持器,只需向move动作发送一个目标,类似于真实franka_gripper 工作方式。让我们将夹持器手指之间宽度移动到8𝑐𝑚,速度10cm/s

rostopic pub --once /franka_gripper/move/goal franka_gripper/MoveActionGoal "goal: { width: 0.08, speed: 0.1 }"

 由于我们使用来自franka_example_controllers的笛卡尔阻抗控制器启动了机器人 ,因此我们可以使用 RViz 中的交互式标记小工具移动末端执行器,就像在现实中一样。移动机器人,使白色石头位于夹持器的手指之间,随时可以被拾起。

 如果机器人用肘部做出奇怪的动作,这是因为笛卡尔阻抗示例控制器的默认零空间刚度设置为低。启动动态重新配置 并根据需要进行panda调整。

cartesian_impedance_example_controller nullspace_stiffness

为了拿起物体,我们grasp这次使用了动作,因为我们想在抓握后施加一个力,以免物体掉落。石头在3𝑐𝑚宽阔和50𝑔沉重。让我们抓住它5𝑁

rostopic pub --once /franka_gripper/grasp/goal \
             franka_gripper/GraspActionGoal \
             "goal: { width: 0.03, epsilon:{ inner: 0.005, outer: 0.005 }, speed: 0.1, force: 5.0}"

 

 

在 Gazebo 的顶部菜单中,转到“View”->Contacts, 以可视化接触点和力。

如果抓取成功,手指现在会将石头固定在原位。如果没有,可能是目标公差(内和外 epsilon)太小,导致操作失败。现在将物体轻轻移到红色落下区域。

 stop将其轻轻地放在红色垫上后,通过夹持器的动作停止抓取:

rostopic pub --once /franka_gripper/stop/goal franka_gripper/StopActionGoal {}

注意,由于不再施加力,接触力现在消失了。或者,您也可以使用动作move

 

posted @ 2024-07-11 22:53  lvdongjie-avatarx  阅读(16)  评论(0编辑  收藏  举报