function [L_Cartesian_theta,R_Cartesian_theta] = Cartesian_Planning(L_p1, L_p2, L_p3,L_pose,L_StepSize,R_p1, R_p2, R_p3,R_pose,R_StepSize)
%% 进行直线插补、圆弧插补、抛物线插补判断
L_pos = Interpolation(L_p1, L_p2, L_p3,L_StepSize); %pos为3x(step+1)的矩阵
L_T=L_pos'; %求转置,T为(step+1)x3的矩阵
L_Q=zeros(L_StepSize+1,6); %用于保存逆解求的值,Q为(step+1)x6的矩阵
R_pos = Interpolation(R_p1, R_p2, R_p3,R_StepSize);
R_T=R_pos';
R_Q=zeros(R_StepSize+1,6);
%% 求逆解,并区其中关节角变化量最小的一组解
for i=1:L_StepSize+1
if i==1
% 第一次求解时与预设值作比较
% _ZY函数在逆解函数的基础上增加了角度判断,用于选出前后位置角度变化最小的一组解
% rpy的值为0,0,180,使末端始终向下。但逆解算法在90°的整数倍位置出会存在奇异问题,所以用179.9替代
L_Q(i,:)=I_Left_ZY([L_T(i,:),L_pose],[300,0,0,0,0,0]);
else
L_Q(i,:)=I_Left_ZY([L_T(i,:),L_pose],L_Q(i-1,:));
end
end
for i=1:R_StepSize+1
if i==1
% 第一次求解时与预设值作比较
% _ZY函数在逆解函数的基础上增加了角度判断,用于选出前后位置角度变化最小的一组解
% rpy的值为0,0,180,使末端始终向下。但逆解算法在90°的整数倍位置出会存在奇异问题,所以用179.9替代
R_Q(i,:)=I_Right_ZY([R_T(i,:),R_pose],[-300,0,0,0,0,0]);
else
R_Q(i,:)=I_Right_ZY([R_T(i,:),R_pose],R_Q(i-1,:));
end
end
L_Cartesian_theta = L_Q';
R_Cartesian_theta = R_Q';
end
clear;clc,close all;
%参数初始化
L_p1=[656,0,1];L_p2=[406,-350,200];L_p3=[656,0,-1];%位置
R_p1=[-656,0,1];R_p2=[-406,-350,200];R_p3=[-656,0,-1];
L_StepSize = 20; %规划点数量
R_StepSize = 15;
L_pose=[0,0,179.9]; %姿态
R_pose=[0,0,179.9];
[L_C_theta,R_C_theta]=Cartesian_Planning(L_p1, L_p2, L_p3,L_pose,L_StepSize,R_p1, R_p2, R_p3,R_pose,R_StepSize);
{
"tasks": [
{
"type": "shell",
"label": "C/C++: g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"${fileDirname}\\acos.cpp",
"${fileDirname}\\asin.cpp",
"${fileDirname}\\Cartesian_Planning.cpp",
"${fileDirname}\\Cartesian_Planning_data.cpp",
"${fileDirname}\\Cartesian_Planning_emxAPI.cpp",
"${fileDirname}\\Cartesian_Planning_emxutil.cpp",
"${fileDirname}\\Cartesian_Planning_initialize.cpp",
"${fileDirname}\\Cartesian_Planning_rtwutil.cpp",
"${fileDirname}\\Cartesian_Planning_terminate.cpp",
"${fileDirname}\\char.cpp",
"${fileDirname}\\cross.cpp",
"${fileDirname}\\dec2hex.cpp",
"${fileDirname}\\dot.cpp",
"${fileDirname}\\hex2dec.cpp",
"${fileDirname}\\I_Left_ZY.cpp",
"${fileDirname}\\I_Right_ZY.cpp",
"${fileDirname}\\ifWhileCond.cpp",
"${fileDirname}\\Interpolation.cpp",
"${fileDirname}\\inv.cpp",
"${fileDirname}\\isequal.cpp",
"${fileDirname}\\mrdivide_helper.cpp",
"${fileDirname}\\norm.cpp",
"${fileDirname}\\round.cpp",
"${fileDirname}\\rt_nonfinite.cpp",
"${fileDirname}\\rtGetInf.cpp",
"${fileDirname}\\rtGetNaN.cpp",
"${fileDirname}\\singleOrHelper.cpp",
"${fileDirname}\\sqrt.cpp",
"${fileDirname}\\xzgetrf.cpp",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"version": "2.0.0"
}
#include
#include "rt_nonfinite.h"
#include "Cartesian_Planning.h"
#include "main.h"
#include "Cartesian_Planning_terminate.h"
#include "Cartesian_Planning_emxAPI.h"
#include "Cartesian_Planning_initialize.h"
using namespace std;
//左右臂位置点
static double L_p1[3] = {656, 0, 1};
static double L_p2[3] = {406, -350, 200};
static double L_p3[3] = {656, 0, -1};
static double R_p1[3] = {-656, 0, 1};
static double R_p2[3] = {-406, -350, 200};
static double R_p3[3] = {-656, 0, -1};
//左右臂姿态
static double L_pose[3] = {0, 0, 179.9};
static double R_pose[3] = {0, 0, 179.9};
//需要规划的点数
static double L_StepSize = 5;
static double R_StepSize = 5;
//PVT点与点之间的时间差,单位秒
static double L_step_time = 0.25;
static double R_step_time = 0.25;
static void main_Cartesian_Planning()
{
emxArray_real_T *L_Cartesian_PVT;
emxArray_real_T *R_Cartesian_PVT;
emxInitArray_real_T(&L_Cartesian_PVT, 2);
emxInitArray_real_T(&R_Cartesian_PVT, 2);
//1-3:左臂三个空间位置点; 4:需要保持的姿态; 5:需要规划的点数; 6:点与点的时间差;
//7-9:右臂三个空间位置点;10:需要保持的姿态;11:需要规划的点数;12:点与点的时间差;
//13:左臂规划后的PVT报文;14:右臂规划后的PVT报文;
Cartesian_Planning(L_p1, L_p2, L_p3, L_pose, L_StepSize, L_step_time,
R_p1, R_p2, R_p3, R_pose, R_StepSize, R_step_time,
L_Cartesian_PVT, R_Cartesian_PVT);
/* 将计算的PVT报文(ascll类型)赋值给新变量L_PVT和R_PVT(char类型) */
//左臂
int L_row = L_Cartesian_PVT->size[0]; //行
int L_column = L_Cartesian_PVT->size[1]; //列
int num_L_Cartesian_PVT = 0;
char L_PVT[L_row][L_column];
for (int i = 0; i < L_column; ++i)
{
for (int j = 0; j < L_row; ++j)
{
L_PVT[j][i] = (char)(L_Cartesian_PVT->data[num_L_Cartesian_PVT]);
num_L_Cartesian_PVT++;
}
}
//打印
cout << "L_PVT:" << endl;
for (int i = 0; i < L_row; ++i)
{
for (int j = 0; j < L_column; ++j)
{
cout << L_PVT[i][j];
}
cout << endl;
}
//右臂
int R_row = R_Cartesian_PVT->size[0]; //行
int R_column = R_Cartesian_PVT->size[1]; //列
int num_R_Cartesian_PVT = 0;
char R_PVT[R_row][R_column];
for (int i = 0; i < R_column; ++i)
{
for (int j = 0; j < R_row; ++j)
{
R_PVT[j][i] = (char)(R_Cartesian_PVT->data[num_R_Cartesian_PVT]);
num_R_Cartesian_PVT++;
}
}
//打印
cout << "R_PVT:" << endl;
for (int i = 0; i < R_row; ++i)
{
for (int j = 0; j < R_column; ++j)
{
cout << R_PVT[i][j];
}
cout << endl;
}
//清除内存
emxDestroyArray_real_T(R_Cartesian_PVT);
emxDestroyArray_real_T(L_Cartesian_PVT);
}
int main(int, const char *const[])
{
// 初始化
Cartesian_Planning_initialize();
// PVT笛卡尔空间运动规划
main_Cartesian_Planning();
// 结束
Cartesian_Planning_terminate();
return 0;
}