目录
一. 透传简介
透传是指用户自己使用上位机进行轨迹规划,然后将各关节的角度直接下发给控制器,不经过控制器的处理,各关节直接运行。机械臂运行的效果直接依赖于用户轨迹规划的水平。
透传的主要应用场景有验证用户算法或者结合视觉,在非结构环境下做动态轨迹规划实现抓取或者避障。
本账号涉及的示例项目网盘链接如下:
链接:https://pan.baidu.com/s/1B_NBbbry_N-xUK83_ij5OA?pwd=exbr
提取码:exbr
二. 提供哪些透传接口
1. 角度透传
功能描述
movej_canfd:角度通过CANFD透传给机械臂,不需控制器规划。
功能备注
透传周期越快,控制效果越好、越平顺。基础系列WIFI和网口模式透传周期最快20ms,USB和RS485模式透传周期最快10ms。高速网口的透传周期最快也可到10ms,不过在使用该高速网口前,需要使用指令打开配置。另外I系列有线网口周期最快可达5ms。
JSON协议示例及说明
发送内容:{"command":"movej_canfd","joint":[1000,0,20000,30000,0,20000]}
说明:角度透传到CANFD,目标关节角度:[1°,0°,20°,30°,0,20°]
返回值格式:{s:s,s: [i,i,i,i,i,i],s:i}
返回值示例:{"state":"joint_state ","joint":[10,20,30,40,50,60], "arm_err":0}
arm_err:若为0,则代表系统正常,指令正常运行;若为其他错误,则反馈相应错误代码,指令不执行。
API接口说明及应用实例
/// \brief Movej_CANFD 角度不经规划,直接通过CANFD透传给机械臂
/// \param ArmSocket socket句柄
/// \param joint 关节1~7目标角度数组
/// \return 0-成功,失败返回:错误码, rm_define.h查询.
/// 只要控制器运行正常并且目标角度在可达范围内,机械臂立即返回成功指令,此时机械臂可能仍在运行;
/// 若有错误,立即返回失败指令。
RM_BASESHARED_EXPORT int Movej_CANFD(SOCKHANDLE ArmSocket, const float *joint);
C语言调用接口实例
此处为QT软件编写的示例(项目文件请参考网盘链接)
1.#include "mainwindow.h"
2.#include "ui_mainwindow.h"
3.#include <QDebug>
4.
5.MainWindow::MainWindow(QWidget *parent) :
6. QMainWindow(parent),
7. ui(new Ui::MainWindow)
8.{
9. ui->setupUi(this);
10.}
11.
12.MainWindow::~MainWindow()
13.{
14. delete ui;
15.}
16.
17.
18.void MainWindow::on_Disconnect_clicked()
19.{
20.
21. Arm_Socket_Close(m_sockhand);
22.
23.}
24.
25.void MCallback(CallbackData data)
26.{
27. qDebug() << "MCallback MCallback MCallback";
28. // 判断接口类型
29. switch(data.codeKey)
30. {
31. case MOVEJ_CANFD_CB: // 角度透传
32. qDebug() << "透传结果:" << data.errCode;
33. qDebug() << "当前角度:" << data.joint[0] << data.joint[1] << data.joint[2] << data.joint[3] << data.joint[4] << data.joint[5];
34. break;
35. case MOVEP_CANFD_CB: // 位姿透传
36. qDebug() << "透传结果:" << data.errCode;
37. qDebug() << "当前角度:" << data.joint[0] << data.joint[1] << data.joint[2] << data.joint[3] << data.joint[4] << data.joint[5];
38. qDebug() << "当前位姿:" << data.pose.px << data.pose.py << data.pose.pz << data.pose.rx << data.pose.ry << data.pose.rz;
39. break;
40. case FORCE_POSITION_MOVE_CB: // 力位混合透传
41. qDebug() << "透传结果:" << data.errCode;
42. break;
43. }
44.
45.}
46.void MainWindow::on_Test_MoveJ_clicked()
47.{
48. int ret = -1;
49.
50. float mJoint[7];
51. POSE mPose;
52. uint16_t mArmErr[7];
53. uint16_t mSysErr[7];
54. Get_Current_Arm_State(m_sockhand,mJoint, &mPose, mArmErr, mSysErr);
55. ui->textEdit->append(QString("POSE: px:[%1] py:[%2] pz:[%3] rx[%4] ry:[%5] rz:[%6]")
56. .arg(mPose.px).arg(mPose.py).arg(mPose.pz)
57. .arg(mPose.rx).arg(mPose.ry).arg(mPose.rz));
58.
59. for(int i = 1;i<=50;i++)
60. {
61. mJoint[5]+=1;
62. ret = Movej_CANFD(m_sockhand,mJoint);
63. Sleep(20);
64. }
65. ui->textEdit->append(QString(" Movej_CANFD: [%1]").arg(ret));
66.}
67.
68.
69.
70.void MainWindow::on_connect_Socket_clicked()
71.{
72. // 连接服务器 返回全局句柄
73. RM_API_Init(65,MCallback);
74. m_sockhand = Arm_Socket_Start((char *)"192.168.1.18", 8080, 5000);
75.
76.}
2. 位姿透传
功能描述
目标位姿透传给机械臂,不需控制器规划
功能备注
目标位姿透传到机械臂,控制器进行逆解后,若逆解存在并且逆解出的各角度与当前角度未有较大差值,则直接下发给关节执行,不再进行轨迹规划。适用于用户需要对位姿进行周期性调整的场景,如视觉伺服等。
透传周期越快,控制效果越好、越平顺。基础系列WIFI和网口模式透传周期最快20ms,USB和RS485模式透传周期最快10ms。高速网口的透传周期最快也可到10ms,不过在使用该高速网口前,需要使用指令打开配置。另外I系列有线网口周期最快可达5ms。
JSON协议示例及说明
发送内容:{"command":"movep_canfd","pose":[100000,200000,30000,400,500,600]}
说明:pose:目标位姿,位置精度:0.001mm,姿态精度:0.001rad
目标位置:x:0.1m,y:0.2m,z:0.03m
目标姿态:rx:0.4rad,ry:0.5rad,rz:0.6rad
目标位姿为当前工具在当前工作坐标系下的数值。
返回值格式:{s:s,s: [i,i,i,i,i,i],s: [i,i,i,i,i,i],s:i}
返回值示例:{"state":"pose_state","pose":[10,20,30,40,50,60],"joint":[10,20,30,40,50,60], "arm_err":0}
pose:当前位姿,位置精度:0.001mm,姿态精度:0.001rad;joint:当前关节角度,关节精度:0.001°;arm_err:若为 0,则代表系统正常,指令正常运行;若为其他错误,则反馈相应错误代码,指令不执行。
API接口说明及应用实例
1.///
2./// \brief Movep_CANFD 位姿不经规划,直接通过CANFD透传给机械臂
3./// \param ArmSocket socket句柄
4./// \param pose 位姿
5./// \return 0-成功,失败返回:错误码, rm_define.h查询
6.///
7.RM_BASESHARED_EXPORT int Movep_CANFD(SOCKHANDLE ArmSocket, POSE pose);
C语言调用接口实例
此处为QT软件编写的示例(项目文件请参考网盘链接)
1.#include "mainwindow.h"
2.#include "ui_mainwindow.h"
3.#include <QDebug>
4.
5.MainWindow::MainWindow(QWidget *parent) :
6. QMainWindow(parent),
7. ui(new Ui::MainWindow)
8.{
9. ui->setupUi(this);
10.}
11.
12.MainWindow::~MainWindow()
13.{
14. delete ui;
15.}
16.void MainWindow::on_Disconnect_clicked()
17.{
18. Arm_Socket_Close(m_sockhand);
19.}
20.void MCallback(CallbackData data)
21.{
22. qDebug() << "MCallback MCallback MCallback";
23. // 判断接口类型
24. switch(data.codeKey)
25. {
26. case MOVEJ_CANFD_CB: // 角度透传
27. qDebug() << "透传结果:" << data.errCode;
28. qDebug() << "当前角度:" << data.joint[0] << data.joint[1] << data.joint[2] << data.joint[3] << data.joint[4] << data.joint[5];
29. break;
30. case MOVEP_CANFD_CB: // 位姿透传
31. qDebug() << "透传结果:" << data.errCode;
32. qDebug() << "当前角度:" << data.joint[0] << data.joint[1] << data.joint[2] << data.joint[3] << data.joint[4] << data.joint[5];
33. qDebug() << "当前位姿:" << data.pose.px << data.pose.py << data.pose.pz << data.pose.rx << data.pose.ry << data.pose.rz;
34. break;
35. case FORCE_POSITION_MOVE_CB: // 力位混合透传
36. qDebug() << "透传结果:" << data.errCode;
37. break;
38. }
39.
40.}
41.void MainWindow::on_Test_MoveJ_clicked()
42.{
43. int ret = -1;
44. float mJoint[7];
45. POSE mPose;
46. uint16_t mArmErr[7];
47. uint16_t mSysErr[7];
48. Get_Current_Arm_State(m_sockhand,mJoint, &mPose, mArmErr, mSysErr);
49. ui->textEdit->append(QString("POSE: px:[%1] py:[%2] pz:[%3] rx[%4] ry:[%5] rz:[%6]")
50. .arg(mPose.px).arg(mPose.py).arg(mPose.pz)
51. .arg(mPose.rx).arg(mPose.ry).arg(mPose.rz));
52.
53. for(int i = 1;i<=50;i++)
54. {
55. mJoint[5]+=1;
56. ret = Movej_CANFD(m_sockhand,mJoint);
57. Sleep(20);
58. }
59. ui->textEdit->append(QString(" Movej_CANFD: [%1]").arg(ret));
60.}
61.void MainWindow::on_connect_Socket_clicked()
62.{
63. // 连接服务器 返回全局句柄
64. RM_API_Init(65,MCallback);
65. m_sockhand = Arm_Socket_Start((char *)"192.168.1.19", 8080, 5000);
66. ui->textEdit->append(QString(" 已连接"));
67.}
68.void MainWindow::on_pushButton_clicked()
69.{
70. int ret = -1;
71.
72. float mJoint[7];
73. POSE mPose;
74. uint16_t mArmErr[7];
75. uint16_t mSysErr[7];
76. Get_Current_Arm_State(m_sockhand,mJoint, &mPose, mArmErr, mSysErr);
77. ui->textEdit->append(QString("POSE: px:[%1] py:[%2] pz:[%3] rx[%4] ry:[%5] rz:[%6]")
78. .arg(mPose.px).arg(mPose.py).arg(mPose.pz)
79. .arg(mPose.rx).arg(mPose.ry).arg(mPose.rz));
80. for(int i = 1;i<=100;i++)
81. {
82. mPose.pz-=0.001;
83. ret = Movep_CANFD(m_sockhand,mPose);
84. Sleep(20);
85. }
86. ui->textEdit->append(QString("POSE: px:[%1] py:[%2] pz:[%3] rx[%4] ry:[%5] rz:[%6]")
87. .arg(mPose.px).arg(mPose.py).arg(mPose.pz)
88. .arg(mPose.rx).arg(mPose.ry).arg(mPose.rz));
89.}
由于机械臂相关软件版本不定期更新,如果你使用的机械臂软件接口或协议与本文有出入,请联系官方技术人员及时更新。