美文网首页
MoveIt教程11 - 运动学C++ API:Robot Mo

MoveIt教程11 - 运动学C++ API:Robot Mo

作者: Danny_a44d | 来源:发表于2019-07-26 17:40 被阅读0次

    RobotModelRobotState 是核心的两个接口类,用来访问机器人的运动学模型。

    RobotModel

    • 管理机器人link和joint的关系,从URDF中加载机器人描述,也包括了设置的joint限制。
    • 根据SRDF中的定义将link和joint按照规划组planning group分组

    RobotState

    • 管理机器人状态信息,记录机器人在某个时刻的关节状态 (包括位置,速度,加速度等)。
    • 提供用于设置位置和计算路径的辅助方法。

    以Panda机械臂为例:

    运行程序

    案例程序在 https://github.com/ros-planning/moveit_tutorials.git (branch: kinetic-devel )

    roslaunch moveit_tutorials robot_model_and_robot_state_tutorial.launch
    

    结果

    运行后可以看到以下结果,注:数值不一定相同,因为是随机的

    ros.moveit_tutorials: Model frame: /panda_link0
    ros.moveit_tutorials: Joint panda_joint1: 0.000000
    ros.moveit_tutorials: Joint panda_joint2: 0.000000
    ros.moveit_tutorials: Joint panda_joint3: 0.000000
    ros.moveit_tutorials: Joint panda_joint4: 0.000000
    ros.moveit_tutorials: Joint panda_joint5: 0.000000
    ros.moveit_tutorials: Joint panda_joint6: 0.000000
    ros.moveit_tutorials: Joint panda_joint7: 0.000000
    ros.moveit_tutorials: Current state is not valid
    ros.moveit_tutorials: Current state is valid
    ros.moveit_tutorials: Translation:
    -0.541498
    -0.592805
     0.400443
    
    ros.moveit_tutorials: Rotation:
    -0.395039  0.600666 -0.695086
     0.299981 -0.630807 -0.715607
    -0.868306 -0.491205 0.0690048
    
    ros.moveit_tutorials: Joint panda_joint1: -2.407308
    ros.moveit_tutorials: Joint panda_joint2: 1.555370
    ros.moveit_tutorials: Joint panda_joint3: -2.102171
    ros.moveit_tutorials: Joint panda_joint4: -0.011156
    ros.moveit_tutorials: Joint panda_joint5: 1.100545
    ros.moveit_tutorials: Joint panda_joint6: 3.230793
    ros.moveit_tutorials: Joint panda_joint7: -2.651568
    ros.moveit_tutorials: Jacobian:
        0.592805   -0.0500638    -0.036041     0.366761   -0.0334361     0.128712 -4.33681e-18
       -0.541498   -0.0451907    0.0417049    -0.231187    0.0403683   0.00288573  3.46945e-18
               0    -0.799172    0.0772022    -0.247151    0.0818336    0.0511662            0
               0     0.670056    -0.742222     0.349402    -0.748556    -0.344057    -0.695086
               0     -0.74231    -0.669976    -0.367232    -0.662737     0.415389    -0.715607
               1  4.89669e-12    0.0154256     0.862009     0.021077     0.842067    0.0690048
    

    完整代码

    创建对象

    通常不直接手动创建RobotModel对象,我们可以通过高层的封装类的接口得到RobotModel对象的指针。比如通过 RobotModelLoader 中的gerModel()

    创建RobotModelLoader对象时传入robot_description参数,会从ROS参数服务器上获取对应的机器人模型描述自动创建RobotModel对象。

    robot_model_loader::RobotModelLoader robot_model_loader("robot_description");
    robot_model::RobotModelPtr kinematic_model = robot_model_loader.getModel();
    ROS_INFO("Model frame: %s", kinematic_model->getModelFrame().c_str());
    

    用RobotModel创建RobotState对象,设置关节状态为默认值。

    robot_state::RobotStatePtr kinematic_state(new robot_state::RobotState(kinematic_model));
    kinematic_state->setToDefaultValues();
    

    调用RobotModel的getJointModelGroup(...)可以得到 JointModelGroup对象的指针。JointModelGroup是针对一个规划组的robot model。

    const robot_state::JointModelGroup* joint_model_group = kinematic_model->getJointModelGroup("panda_arm");
    
    const std::vector<std::string>& joint_names = joint_model_group->getVariableNames()
    

    获取关节数值

    通过RobotState的setJointGroupPositions(...)可以获取某个model的关节信息

    std::vector<double> joint_values;
    kinematic_state->copyJointGroupPositions(joint_model_group, joint_values);
    for (std::size_t i = 0; i < joint_names.size(); ++i)
    {
      ROS_INFO("Joint %s: %f", joint_names[i].c_str(), joint_values[i]);
    }
    

    设置关节位置及关节限制

    setJointGroupPositions(...)设置关节位置不会管是否满足joint limits,可以通过enforceBounds()迫使满足。

    /* Set one joint in the Panda arm outside its joint limit */
    joint_values[0] = 5.57;
    kinematic_state->setJointGroupPositions(joint_model_group, joint_values);
    
    /* Check whether any joint is outside its joint limits */
    ROS_INFO_STREAM("Current state is " << (kinematic_state->satisfiesBounds() ? "valid" : "not valid"));
    
    /* Enforce the joint limits for this state and check again*/
    kinematic_state->enforceBounds();
    ROS_INFO_STREAM("Current state is " << (kinematic_state->satisfiesBounds() ? "valid" : "not valid"));
    

    正运动学

    随机设置关节数值,计算panda_link8的姿态。

    kinematic_state->setToRandomPositions(joint_model_group);
    const Eigen::Affine3d& end_effector_state = kinematic_state->getGlobalLinkTransform("panda_link8");
    
    /* Print end-effector pose. Remember that this is in the model frame */
    ROS_INFO_STREAM("Translation: \n" << end_effector_state.translation() << "\n");
    ROS_INFO_STREAM("Rotation: \n" << end_effector_state.rotation() << "\n");
    

    逆运动学

    IK逆求解,传入上一步求出的末端执行器的姿态end_effector_state,设置尝试次数10,超时0.1s,求解成功会把结果存到joint_model_group参数中

    std::size_t attempts = 10;
    double timeout = 0.1;
    bool found_ik = kinematic_state->setFromIK(joint_model_group, end_effector_state, attempts, timeout);
    

    打印结果

    if (found_ik)
    {
      kinematic_state->copyJointGroupPositions(joint_model_group, joint_values);
      for (std::size_t i = 0; i < joint_names.size(); ++i)
      {
        ROS_INFO("Joint %s: %f", joint_names[i].c_str(), joint_values[i]);
      }
    }
    else
    {
      ROS_INFO("Did not find IK solution");
    }
    

    雅克比矩阵

    从RobotState中获取Jacobian

    Eigen::Vector3d reference_point_position(0.0, 0.0, 0.0);
    Eigen::MatrixXd jacobian;
    kinematic_state->getJacobian(joint_model_group,
                                 kinematic_state->getLinkModel(joint_model_group->getLinkModelNames().back()),
                                 reference_point_position, jacobian);
    ROS_INFO_STREAM("Jacobian: \n" << jacobian << "\n");
    

    launch文件

    launch文件中包含以下两步:

    • 加载URDF和SRDF文件到参数服务器
    • 加载运动学求解器kinematics_solver的配置参数(yaml文件)到参数服务器
    <launch>
      <include file="$(find panda_moveit_config)/launch/planning_context.launch">
        <arg name="load_robot_description" value="true"/>
      </include>
    
      <node name="robot_model_and_robot_state_tutorial"
            pkg="moveit_tutorials"
            type="robot_model_and_robot_state_tutorial"
            respawn="false" output="screen">
        <rosparam command="load"
                  file="$(find panda_moveit_config)/config/kinematics.yaml"/>
      </node>
    </launch>
    

    相关文章

      网友评论

          本文标题:MoveIt教程11 - 运动学C++ API:Robot Mo

          本文链接:https://www.haomeiwen.com/subject/qtallctx.html