MoveIt教程11 - 运动学C++ API:Robot Model 和 Robot State

MoveIt教程11 - 运动学C++ API:Robot Model 和 Robot State_第1张图片

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

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& joint_names = joint_model_group->getVariableNames()

获取关节数值

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

std::vector 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文件)到参数服务器

  
    
  

  
    
  

你可能感兴趣的:(MoveIt教程11 - 运动学C++ API:Robot Model 和 Robot State)