Rose-Ros机械臂:机械臂夹角、ik_query.z

  • 为让TP总在爪子中心线,是通过两个操作。一是在state_distance阶段,会调用rotate_joint1_if_necessary,基本确保TP在爪子中心线。二是在state_claw前,会先进入state_align,在这状态会尽可能让TP对齐爪子中心线。

 

一、机械臂夹角

图1 机械臂夹角
  • 蓝色。相机夹角。相机测出的x、y。
  • 绿色。机械臂夹角。用于求机械臂夹角的x、y。
  • 橙色。机器人夹角。

在安装时,要确保机器人中心(base_footprint坐标系原点)、机械臂joint1坐标系原点、爪子中心,它们的y须在机器人y=0这条线上。相机原点y可以不在这条线,但不要偏移太多。让存在这个偏移,是出于这么个现实:相机坐标系原点不是在相机尺寸中心。对奥比中光相机DaBai DCL,同时接收RGB+深度时,相机原点是在RGB相机中心,而不是尺寸中心。安装时,为方便可能会把相机尺寸中心放在y=0这条线上。也就是说,机器人中心、机械臂joint1坐标系原点、爪子中心,相机中心(不是原点),它们的y会在机器人y=0这条线上。

参数RGB_diff_y指示相机原点到机器人y=0这条线的偏移。对DaBai DCL,这个值是1.1cm。

如果旋转的是机器人,要弥补的是机器人夹角(robot_theta),图1中橙色。如果旋转的是机械臂,要弥补的是机械臂夹角(moveit_theta),图1中绿色。对同一个TP,这两个夹角值不一样。计算这两个夹角时,y一样。对x,由于机械臂会放在底盘前半部,计算机器人夹角的x就要大于机械臂,所以同一时刻,机器人夹角要小于机械臂夹角。

机械臂原点取的是joint1坐标系,不是joint2。

实装时IMU时,会要求y尽可能在机器人y=0上,但不希望限定x。因而同一个TP,从它读出的yaw既不是机械臂夹角,也不是机器人夹角、相机夹角。因为x不确定,在操作机械臂时,全程不使用IMU的yaw。这就要求joint1转的角度和value得有一定的精准度。像转20度,误差不要超过1度。

 

1.1 计算机械臂夹角moveit_theta

const double RGB_diff_y = 0.011;
SDL_DPoint dcamera_origin{curr_fk.position.x + -1 * PRP.x, RGB_diff_y};
moveit_theta = atan2(dcamera_origin.y + TP.y, dcamera_origin.x + TP.x);

“RGB_diff_y = 0.011”针对的是DaBai DCL相机。

“curr_fk.position.x”是图1中的fk.x。由正向运行学方程fk算出。

PRP.x是PRP这个点在相机world坐标系中的坐标,值是和TP同一帧拍到的。

“TP”是TP这个点在相机world坐标系中的坐标。

 

1.2 moveit_theta精准度

什么因素影响moveit_theta的精确度?

  • 装配问题。joint1应该在y=0上,需保证爪子两瓣y=0对称。
  • 计算moveit_theta的x、y。这里有一个fk.x,是个机械臂fk算出的值,如果机械臂误差较大,那这个值会不准。

对如何提高fk.x精准度?——通过两次两次拍到的TP、PRP值,算出它们之间距离TP_PRP_diff.x,并计算连续两次的距离差值TP_PRP_diff_diff.x,弥补fk.x,是否能提高精度。——这方案估计不行,主要两个原因。

  1. 在操和过程中,TP是可能会变的。
  2. 在两次计算TP过程中,joint1可能会发生了旋转。这在目标物位置不变的情况下,

由于fk.x有误差,这算出的moveit_theta会有误差。

 

1.3 让TP总在爪子中心线上

为让TP总在爪子中心线,是通过两个操作。一是在state_distance阶段,会调用rotate_joint1_if_necessary,基本确保TP在爪子中心线。二是在state_claw前,会先进入state_align,在这状态会尽可能让TP对齐爪子中心线。

bool rotate_joint1_if_necessary(const std::string& scene, const double moveit_theta, std::string& msg)
@moveit_theta。机械臂夹角。图1中以机械臂原点为起点,绿色线指示的那个夹角。

在rotate_joint1_if_necessary,如果机械臂夹角在[-2, 2],不做调整,返回false。否则要旋转joint1,目的是使得旋转后的moveit_theta是0。

在handle_distance执行后,只要此次是找到有效RP、TP,那意味着已调用过rotate_joint1_if_necessary,这“确保”了TP在爪子中心线上。由于state_ik是要在handle_distance返回true后才会执行,意味着在set_ik前,TP已在爪子中心线上。但“确保”加了引号,原因是在中心线,有误差。

  1. rotate_joint1_if_necessary只是限定在范围[-2, 2]。
  2. fk.x存在误差。
  3. joint1的精度。认为joint1关节value值的物理意义就是关节旋转弧度,要弥补moveit_theta,就是让joint1直接旋转moveit_theat弧度,如果设的value-diff不是对应world世界旋转过的弧度,那会产生误差。

对state_distance或state_ik,能有这个“确保”,基本也够了。但是,对按按钮,是否TP是否在爪子中心线,这会极大影响操作精度。为此在state_claw前,会先进入state_align,在这阶段会尽可能让TP对齐爪子中心线。

在state_claw,会算相机夹角。一旦相机夹角超过0.8度,就会试着旋转joint1。

在每次旋转joint1前,会记住此刻的相机夹角,记在min_abs_dcamera_theta_y0。一旦下一次相机夹角大于min_abs_dcamera_theta_y0了,就不再旋转joint1,同时结束state_claw,避免死锁。

 

二、ik_query.z

ik_query是用要于求逆解的目标位姿,类型geometry_msgs::Pose,但由于求出的ik逆解,只是得到xyz平移部分,可认为它就是个xyz三维坐标。逆解针对的是“ik_arm”这个关节组,包括从了joint2到joint4。因而ik_query.z是joint4坐标系原点在joint1坐标系下的z坐标。

图2 ik_query.z

图2中紫色横线是ik_query.z。ik_query来自机械臂的joint1坐标系。正如图2绿线所示,ik_query.z=0就是joint1坐标系原点所在的z平面。

<joint
    name="joint1"
    type="revolute">
    <origin
      xyz="0.054476 0.00070272 0.156"
      rpy="0 0 0" />
    <parent
      link="base_link" />
    ...
</joint>

0.156是joint1坐标系原点在base_link坐标系下的z坐标。ik_query.z=0不包括0.156。。

要注意,ik_query.z不是TP.z点所在的平面。以图2为例,在斜夹时,由于爪子较长,目标物才3cmx3cmx3cm,那ik_query.z要位在TP.z上方的square_xz(9.5cm)处,即TP.z还要往上9.5m的那地方。

顺便说下,图2中的TP来自相机坐标系。

 

三、求出ik逆解ik_result后,要操作机械臂到达ik_result,如何设置joint4值

PRP_joint_value = DEG2RAD(-10); // -10(rad:-0.174444)

ik逆解用的是ik_arm关节组,包括joint2、joint3、joint4关节。ik逆解,算出的只是join4关节要到达的(x, y, z),至于旋转部分rpy是不确定的。joint4值不影响最后joint4要落在哪(x, y, z),但影响rpy。

joint4的axis.y=1,也就说将按着数学课教的角度值和时针转动关系。顺时针转时,joint4值变小;逆时针转时,joint4值变大。对俯仰角(pitch),朝向地面转的方向是逆时针。

到达ik_result后,joint4值要设为这多少。看下这值会产生哪些影响。

  1. joint4值过小,即过于朝向天。会使得相机支架碰到joint3关节。
  2. joint4值过大,即过于朝向地。当TP离地面较近时,在机械臂移动到目标点过程中,1)爪子可能会碰到地面。2)目标物体在物体2上,爪子可能会碰到物体2。

在设想使用场景时,总是假定目标物上面没东西了,为不碰到支撑目标物的地面或其它物体,那就让joint4尽可能朝向天,即一个尽可能小的值。但障于影响1,这个值不让能支架碰到joint3关节,目前取-10度。

全部评论: 0

    写评论: