AR机型专栏
AR臂的使用
前提说明
- AR机型主要包括两款,十字腕和SR类型的,分左右臂(L:左臂,R:右臂),一般客户会选择侧装的方式

- 版本说明
基于3.0的版本
控制版本:3.0.1.6.ARxxxx SDK版本:v0.5.1.ar_x
基于3.2的版本
控制版本:v3.2.1.C224.2026xxxx SDK版本:v0.7.1.ar_x
-
安装方式
左右臂一般会选择侧装的安装方式(基座左臂和世界坐标不重合),注意:左右臂的侧装参数不一样,如下是左臂:

Demo使用
目前客户大部分使用AR机型都是遥操作,灵巧手,夹东西的业务场景,客户对机器人实时控制的场景要求比较高,一般会基于笛卡尔位置和关节控制,规划轨迹特别重要,因此,在轨迹规划过程中需重点考虑运动平滑性与实时性,建议采用样条插值或梯形速度曲线进行路径优化。同时,结合AR机型的逆解求解特性,确保每一步目标点位于工作空间内,避免奇异位形。对于遥操作延迟问题,设置丢包网络阈值。对于机械臂响应慢的情况设置timeout的方式
实时模式-笛卡尔位置控制
以 v0.7.1.ar版本为例
// 第一个参数是机器人的IP,第二个参数是上位机的IP
rokae::ArRobot robot("192.168.2.160", "192.168.2.190");
回调接口实时更新笛卡尔位置,客户可以从外部传入,注意回调接口不要有任何的阻塞任务、耗时任务,比如socket通信,打印日志,写文件,只是单一的赋值、简要的计算即可,保证1ms可以执行完的任务
std::function<CartesianPosition(void)> callback =[&,rtCon]()->CartesianPosition{
time+=0.001;
output.pos = init_position;
output.pos[7] += delta_z;
std::array<double, 6> xyzabc;
print(std::cout,"位置:",xyzabc)
if(time > 0.01){
std::cout<<"运动结束:"<<deltaz<<std::endl;
output.setFinished();
stopManually.store(false);//loop为非阻塞,和主线程同步停止状态
return output;
}
}
代码流程
- 构造类
rokae::ArRobot
- 设置参数,自动模式,实时模式,上电
robot.setOperateMode(rokae::OperateMode::automatic,ec);
robot.setMotionControlMode(MotionControlMode::RtCommand, ec);
robot.setPowerState(true, ec);
- 如果用户末端安装了工具工件,也需要要设置工具工件坐标
具体参照接口
//设置手持工具坐标系,Rv旋转90
Toolsettoolset1:
toolset1.end.rpvl1l= MPt.2:
robot.setToolset(toolset1.ec)
- 移动到拖动姿态(客户可能不需要),AR的拖动姿态关节角需要修改
std::array<double,7> q_drag_xm7p = {0,M_PI/6,0,M_PI/3,0,0,0};
rtCon->MoveJ(0.5, robot.jointPos(ec), q_drag_xm7p);
- 如果客户使用过程中丢包比较多,需要设置网络阈值,一般建议20-30
robot.setRtNetworkTolerance(50, ec);
- 回调实现:保证回调里面实现的内容的单一性,不要加延迟任务,阻塞任务,耗时任务,否则影响控制器的调度,使机械臂调度慢,出现异响,运动延迟等不可预见的错误。
给的笛卡尔点是4*4的矩阵,是基于基坐标系的,如需转换请参照utility.h文件提供的接口实现
std::function<CartesianPosition(void)> callback = [&, rtCon]()->CartesianPosition{
time += 0.001;
constexpr double kRadius = 0.1;
double angle = M_PI / 4 * (1 - std::cos(M_PI / 2 * time));
double delta_z = kRadius * (std::cos(angle) - 1);
CartesianPosition output{};
output.pos = init_position;
output.pos[7] += delta_z;
if(time > 0.01){
std::cout << "运动结束:"<<delta_z <<std::endl;
output.setFinished();
stopManually.store(false); // loop为非阻塞,和主线程同步停止状态
}
return output;
};
- 启动实时模式
rtCon->setControlLoop(callback, 0, true);
//开始运动前先设置为笛卡尔空间位置控制
rtCon->startMove(RtControllerMode::cartesianPosition);
rtCon->startLoop(true);
实时模式-关节控制
参照demo:joint_position_control.cpp
- 前5个点参照上述的前五点
- 回调函数,赋值的是关节角,以弧度为单位,上位机坐规划的时候大部分是规划世界坐标系的笛卡尔点,所以使用utility.h定位的转换接口坐转换
std::function<JointPosition()> callback = [&, rtCon]() {
time += 0.001;
double delta_angle = M_PI / 20.0 * (1 - std::cos(M_PI / 2.5 * time));
JointPosition cmd = {{jntPos[0] + delta_angle, jntPos[1] + delta_angle, jntPos[2] - delta_angle,
jntPos[3] + delta_angle, jntPos[4] - delta_angle, jntPos[5] + delta_angle,
jntPos[6] - delta_angle}};
if (time > 60)
{
cmd.setFinished(); // 60秒后结束
}
return cmd;
};
- 启动实时模式:关节控制
// 设置回调函数
rtCon->setControlLoop(callback);
// 更新起始角度为当前角度
jntPos = robot.jointPos(ec);
// 开始轴空间位置控制
rtCon->startMove(RtControllerMode::jointPosition);
// 阻塞loop,开始运动
rtCon->startLoop(true);
正逆解
流程和代码说明,步骤和代码说明,为了防止奇异点算不出正逆解,验证的过程首先要在HMI示教点位,在HMI上通过MOVL或者movj能正常到达,sdk接口调用的时候就没问题
连接机器人
ArEobot robot("192.168.2.160", "192.168.2.110"); // 使用xMateErProRobot以匹配7轴
设置自动模式并上电
robot.setOperateMode(OperateMode::automatic, ec);
if (ec) {
cout << "设置自动模式失败: " << ec.message() << endl;
return -1;
}
robot.setPowerState(true, ec);
if (ec) {
cout << "上电失败: " << ec.message() << endl;
return -1;
}
设置工具工件坐标
如有必要,需要设置工具工件坐标
Toolset toolset1;
toolset1 = robot.toolset(ec);
print(std::cout, "从控制器读取的工具工件坐标系:", toolset1);
获取关节角
用于做正解计算
// 获取当前机器人关节角度
auto current_joints = robot.jointPos(ec);
if (ec) {
cout << "获取关节角度失败: " << ec.message() << endl;
return -1;
}
获取末端姿态
用于计算逆解,特别注意截图的参数,一般的情况下法兰是会安装工具的,如果没有安装的话这个值就是法兰的位姿
// 获取控制器报告的当前末端位姿
auto current_cartesian_from_robot = robot.cartPosture(CoordinateType::endInRef, ec);
if (ec) {
cout << "获取末端位姿失败: " << ec.message() << endl;
return -1;
}
设置不要轴配置参数计算逆解
这个值默认是不需要设置的,默认是关闭,有些客户直接使用SDK 的接口,没有通过HMI操作,所以最好设置
//设置不要轴配置参数计算逆解
robot.setDefaultConfOpt(false, ec);
计算正解
使用的值是步骤3里面获取的关节角
auto fk_cartesian = robot.model().calcFk(current_joints, toolset1, ec);
if (ec) {
cout << "正解算失败: " << ec.message() << endl;
}
查看打印的数据是否正确,并与HMI上的界面的数据做比较,如果一致,就是正确的
计算逆解
使用的是步骤5获取到的数据,如果计算失败可以采用正解的计算出来的位姿传入做计算
auto ik_joints_m1 = robot.model().calcIk(endPos, toolset1, ec);
2.3.2.4 基于模型库的正逆解
采用此方式,可以使逆解提速,满足实时控制计算需求。
-
初始化关节角
std::array<double, 7> zeros = {0, 0, 0, 0, 0, 0, 0},
//初始化关节角
jointPos_in = Utils::degToRad(array<double,7>({5, 46, -10, 91, 1, -105, 11})),
jointVel_in = {0.3, 0.2, 0.5, 0.4, 0.1, 0.1, 0.1},
jointAcc_in = {1.3, 3.1, 4.1, 1.5, 1.6, 4.1, 8.1},
jointInit = Utils::degToRad(array<double,7>({6, 45, -9, 92, 0, -103, 10})),
array1 {}, array2 {}, array3 {}, array4 {};
计算正解
/**
* @brief 获取笛卡尔空间位置
* @param[in] jntPos 需要计算笛卡尔位姿的关节角度
* @param[in] nr 指定坐标系, 缺省值为flange
* @return 向量化4x4位姿矩阵,行优先.
*/
std::array<double, 16> getCartPose(const std::array<double, DoF> &jntPos, SegmentFrame nr = SegmentFrame::flange);
auto pos = model.getCartPose(jointPos_in);
- 计算逆解
double psi = Utils::degToRad(-7.177);
double psi2 = Utils::degToRad(0);
array<int, 8> confData = {0, 0, 0, 0, 0, 0, 0,0};
gettimeofday(&start, NULL);
auto ret = model.getJointPos(pos, psi, jointInit, array1);
臂角遍历计算逆解 [已废弃]
在 v3.2.1 的AR版本上,已经废弃臂角的概念。三轴角度代替原来的臂角,更加直观。
下面是旧版本对于逆解臂角的说明
逆解接口中搜索臂角精度的设置,取值大于0即可
通用
请见 2.3.2.4 章节demo的实现
/**
* @brief 根据位姿计算逆解。并自动遍历臂角,搜索范围-PI-PI
* @param[in] posture 机器人末端位姿,相对于外部参考坐标系。参考的坐标系是通过setToolset()设置的
* @param[in] elb_accuracy 臂角精度 大于0即可,值越小,搜索精度越高,计算时间越长,建议值大于10,
* @param[out] ec 错误码
* @return 轴角度, 单位:弧度
*/
std::array<double, DoF> calcIk_SearchElbow(CartesianPosition posture, double elb_accuracy, error_code &ec) noexcept;
/**
* @brief 根据位姿计算给定工具工件坐标系下逆解。并自动遍历臂角,搜索范围-180-180°
* @param[in] posture 机器人末端位姿,相对于外部参考坐标系
* @param[in] tool_set 工具工件坐标系
* @param[in] elb_accuracy 臂角精度 大于0即可,值越小,搜索精度越高,计算时间越长
* @param[out] ec 错误码
* @return 轴角度, 单位:弧度
*/
std::array<double, DoF> calcIk_SearchElbow(CartesianPosition posture,const Toolset &tool_set, double elb_accuracy, error_code& ec) noexcept;
- 模型库逆解
增加了臂角的遍历,满足逆解提速的要求
/**
* @brief 目标比较从[-PI,PI]之间进行遍历,得到其中最近的逆解
* @param[in] cartPos 法兰笛卡尔空间位姿
* @param[in] psi_accuracy 臂角求解精度,单位度(例如1、10、20),值越小,精度越高,求解时间越长
* @param[in] elbow 臂角 接口扩展使用,暂时无用
* @param[in] jntInit 初始关节角度
* @param[out] jntPos 关节空间位置
* @return 计算逆解结果 -
* 1) -1, -2, -3: 无解,原因是cartPos超出机器人工作空间或无解
* 2) -4, -5: jntPos与jntInit相差较大,一般认为jntInit代表机器人当前位置,jntPos与jntInit之差可以等效为电机转速。
* 若超过机器人轴额定转速,则返回-4或-5;
* 3) -6, -7: jntPos超过软限位;
* 4) -8: 机器人奇异;
*/
int getJointPosSearchPsi(const std::array<double, 16> &cartPos, const double& psi_accuracy, double elbow, const std::array<double, DoF> &q_init, std::array<double, DoF> &q);
实时模式下AR臂常见问题
左右臂运动不一致,一个快一个慢
如果是同版本,同配置的情况下,两个臂运动不一致,查看HMI上如下开关是否开启

求正逆解失败
-
在HMI上确认如下参数是否关闭

-
调用接口关闭conf
设置不要轴配置参数计算逆解
robot.setDefaultConfOpt(false, ec);