坐标求取目标角度
已知点的坐标(x,y,z),求机械臂的目标角度(,,),
利用三角公式,可得如下:
利用以上三个公式即可对三个关节的角进行求取
void gettheta(double *des,double *destheta){
double x = des[0] ;
double y = des[1] ;
double z = des[2] ;
destheta[0] = atan2(des[1],des[0]);
destheta[1] = acos((l2 * l2 + x * x + y * y + ( z - l1) * ( z - l1 ) - l3 *l3)/(2 * l2 * sqrt( x * x +y *y +(z - l1)*(z - l1)))) + atan2((z - l1),sqrt(x * x + y * y)) - pi / 2 ;
destheta[2] = acos((l2 * l2 + l3 * l3 - x * x -y * y - (z - l1)*(z - l1))/(2 * l2 *l3)) - pi/2 ;
}
贝塞尔曲线规划路径
通过设定的起始点与目标点,我们即可获得贝塞尔曲线的和,再通过自行添加(n-1)个沿途经过的点,即可获得n阶的贝塞尔曲线
具体公式如上
贝塞尔公式学习链接:
贝塞尔曲线实现:
//二项式系数求取
int c(int n , int k){
if( k == 0 || k == n)
return 1;
return c( n -1 , k -1 ) + c( n - 1 , k );
}
//路径规划
void gettrajectory(double des[t][3],double destrajectary[t0+1][3]){
double destheta[t][3];
double desposition[t0+1][3];
//求出路径上所有规划点坐标
for(int i = 0 ; i <= t0 ; i++){
double tc = (double(i) )/ t0 ;
desposition[i][0] = 0;
desposition[i][1] = 0;
desposition[i][2] = 0;
for(int j = 0 ; j < t ; j ++){
desposition[i][0] += (c( t - 1 ,j) * pow( 1- tc , t - j - 1) * pow( tc , j) * des[j][0]);
desposition[i][1] += (c( t - 1 ,j) * pow( 1- tc , t - j - 1) * pow( tc , j) * des[j][1]);
desposition[i][2] += (c( t - 1 ,j) * pow( 1- tc , t - j - 1) * pow( tc , j) * des[j][2]);
int a=c(t - 1 ,j);
}
}
//将规划点坐标转换为角度
for(int i = 0 ; i <= t0 ; i ++ ){
gettheta(desposition[i],destrajectary[i]);
}
}
moveit::planning_interface::MoveGroupInterface::Plan的使用
// 定义存放规划路径相关变量
moveit::planning_interface::MoveGroupInterface::Plan plan;
moveit_msgs::RobotTrajectory trajectory;
trajectory_msgs::JointTrajectoryPoint waypoint;
//存放关节名
trajectory.joint_trajectory.joint_names.push_back("joint_1");
trajectory.joint_trajectory.joint_names.push_back("joint_2");
trajectory.joint_trajectory.joint_names.push_back("joint_3");
trajectory.joint_trajectory.joint_names.push_back("joint_4");
trajectory.joint_trajectory.joint_names.push_back("joint_5");
trajectory.joint_trajectory.joint_names.push_back("joint_6");
//存放关节角
for(int i = 0 ; i <= t0 ; i++ ){
for(int j = 0 ; j < 3 ; j++){
waypoint.positions.push_back(destrajectary[i][j]);
}
for(int j = 0 ; j < 3 ; j++){
waypoint.positions.push_back(0.00);
}
//存放运行时间
waypoint.time_from_start = ros::Duration(0.12 * i);
trajectory.joint_trajectory.points.push_back(waypoint);
waypoint.positions.clear();
}
//存放路径
plan.trajectory_ = trajectory ;
如上,我们将算出的贝塞尔曲线的轨迹点通过waypoint.positions.push_back存放至waypoint中,再将期望的单段距离运行时间存放至waypoint.time_from_start中,之后再把整个waypoint通过trajectory.points.push_back存至trajectory中,最后再把trajectory存至plan.trajectory_中,至此就可完成贝塞尔曲线的存放,再利用arm.execute(plan),就可执行该轨迹