VersaAssistant 调试助手#
物理接口#
串口通信(支持传统串口和USB虚拟串口)
- 网络调试
Tcp Server(支持连接多个客户端)
Tcp Client
Udp Socket
USB调试(USB-HID)
小技巧
注意
部分USB虚拟串口的物理设备可能没有较好的处理数据发送和接收包长,在单次发送大于64、256等字节数据时,可能存在数据丢失问题,这个属于设备端问题,请优先排查设备端。
使用USB-HID设备时,需要考虑数据包长为64、256,来对协议数据的数据长度进行限制。
编码格式#
理论上支持以下编码格式(部分):UTF-8、ISO-8859-1、latin1、CP819、Big5、GBK、GB2312、EUC-KR、ISO-2022-JP、windows-1252、CP1252、KOI8-R 等,完整列表请参考运行环境所使用编码库文档。
通信协议#
仅支持本软件通信协议,不支持
printf等低效方式。协议显示窗口,可进行简单数据处理,将数据转换到一定范围,进行数据波动观察
波形显示#
支持基于通信协议的波形显示功能,最大支持28条波形显示。
波形绘制横坐标单位为秒。
危险
波形刷新时请勿进行波形数据导入/导出;操作前请先停止刷新(关闭通信或协议)。导入前请先清空波形。
模型加载#
支持加载自定义3D模型。
支持模型的六轴姿态显示。
支持机械臂的姿态解算,进行机械臂3D姿态显示。
设置模型后需要重启操作。
{
"ModelPath": [
"E:/projects/VersaAssistant/VersaAssistant/models/DJIMatrice30T.obj",
"E:/projects/VersaAssistant/VersaAssistant/models/dummy.obj"
],
"VersaRobot": {
"DJIMatrice30T.obj": {
"Matrice30T": {
"parent": "DJIMatrice30T.obj",
"action": "transform"
}
},
"dummy.obj": {
"robot-node1": {
"parent": "dummy.obj",
"action": "transform"
},
"robot-node2": {
"parent": "robot-node1",
"action": "rotation",
"rotation_coordinates": [
0.0,
0.0835,
0.0
],
"rotation_axis_enable": [
0.0,
1.0,
0.0
],
"rotation_limit_angle": [
-180.0,
180.0
]
},
"robot-node3": {
"parent": "robot-node2",
"action": "rotation",
"rotation_coordinates": [
0.035,
0.109,
0.0
],
"rotation_axis_enable": [
0.0,
0.0,
1.0
],
"rotation_limit_angle": [
-180.0,
180.0
]
},
"robot-node4": {
"parent": "robot-node3",
"action": "rotation",
"rotation_coordinates": [
0.035,
0.255,
0.0
],
"rotation_axis_enable": [
0.0,
0.0,
1.0
],
"rotation_limit_angle": [
-180.0,
180.0
]
},
"robot-node5": {
"parent": "robot-node4",
"action": "rotation",
"rotation_coordinates": [
0.023,
0.307,
0.0
],
"rotation_axis_enable": [
1.0,
0.0,
0.0
],
"rotation_limit_angle": [
-180.0,
180.0
]
},
"robot-node6": {
"parent": "robot-node5",
"action": "rotation",
"rotation_coordinates": [
0.150,
0.307,
0.0
],
"rotation_axis_enable": [
0.0,
0.0,
1.0
],
"rotation_limit_angle": [
-180.0,
180.0
]
}
}
}
}
参数说明#
模型加载配置#
参数 |
用途 |
|---|---|
ModelPath |
模型路径列表 |
VersaRobot |
机器人/模型节点配置 |
动作配置#
VersaRobot 下列举各模型文件名(如 DJIMatrice30T.obj、dummy.obj)。
DJIMatrice30T.obj:单节点Matrice30T,配置其父节点;action为transform表示六自由度(旋转+平移)。dummy.obj:六节点,每节点相对前一节点变换,节点一相对原点,用transform;其余可用rotation。action为rotation表示旋转,需设置rotation_coordinates``(相对原点位置 [x,y,z])和 ``rotation_limit_angle[angle1, angle2]。绕某轴旋转时,
rotation_coordinates中该轴以外分量须准确(姿态求解为先平移回原点再旋转再平移回)。rotation_limit_angle为保留项,软件未用 JSON 中的角度限制,实际固定为 [-180, 180]。
小技巧
调试机械臂时 rotation_coordinates 的正确设置很重要,可参考稚辉君的 dummy 模型。
模型为 Blender 导出的 .obj,其他平台未测试;不兼容时可经 Blender 重新导出。建议勿用层级过复杂的模型,可在 Blender 中合并节点,仅保留需控制的整体(如 dummy.obj),在 Blender 中查看节点结构。
导出#
变换过程
坐标变换的过程
/*!
* 姿态求解,更新为四元数
* @param pNode
*/
void VersaOpenGLWidget::updataTranslateMatrix(VersaNode *pNode)
{
// 平移矩阵
pNode->mTranslateMatrix.setToIdentity();
pNode->mTranslateMatrix.translate(pNode->mTranslate3D);
QQuaternion pitch, yaw, roll;
// 绕轴旋转矩阵
if (pNode->mRotation3DAxisEnable.x() != 0)
{
pitch = QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0),
pNode->mRotation3DAngle.x());
}
if (pNode->mRotation3DAxisEnable.y() != 0)
{
yaw = QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0),
pNode->mRotation3DAngle.y());
}
if (pNode->mRotation3DAxisEnable.z() != 0)
{
roll = QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 1),
pNode->mRotation3DAngle.z());
}
QQuaternion rotation = yaw * pitch * roll;
// 旋转矩阵
pNode->mRotationMatrix.setToIdentity();
pNode->mRotationMatrix.translate(pNode->mRotation3DCoordinates.x(),
pNode->mRotation3DCoordinates.y(),
pNode->mRotation3DCoordinates.z());
pNode->mRotationMatrix.rotate(rotation);
pNode->mRotationMatrix.translate(-pNode->mRotation3DCoordinates.x(),
-pNode->mRotation3DCoordinates.y(),
-pNode->mRotation3DCoordinates.z());
// 缩放矩阵
pNode->mScaleMatrix.setToIdentity();
pNode->mScaleMatrix.scale(pNode->mScale);
// 相对位置矩阵,控制中不操作,为模型加载时的相对位置
// mRelativeMatrix
// 最终的变换矩阵
pNode->mTransformMatrix =
pNode->mTranslateMatrix *
pNode->mRotationMatrix *
pNode->mScaleMatrix *
pNode->mRelativeMatrix;
}
模型绘制过程#
void VersaOpenGLWidget::drawNode(const VersaNode *pNode, QMatrix4x4 drawScaleMatrix)
{
// drawScaleMatrix可以理解为父节点变换矩阵
drawScaleMatrix *= pNode->mTransformMatrix;
QMatrix4x4 modelViewMatrix;
QMatrix3x3 normalMatrix;
QMatrix4x4 mvp;
// 先缩放,再旋转,再平移 。
modelViewMatrix = mCameraView * drawScaleMatrix;
normalMatrix = modelViewMatrix.normalMatrix();
mvp = mProjection * modelViewMatrix;
mShaderProgram.setUniformValue("MV", modelViewMatrix);
mShaderProgram.setUniformValue("N", normalMatrix);
mShaderProgram.setUniformValue("MVP", mvp);
for (int imeshes = 0; imeshes < pNode->mMeshes.size(); ++imeshes)
{
if (pNode->mMeshes[imeshes]->material->mName == QString("DefaultMaterial"))
{
setMaterialUniforms(&mMaterialInfo);
}
else
{
setMaterialUniforms(pNode->mMeshes[imeshes]->material.data());
}
{
mVao.bind();
glDrawElements(GL_TRIANGLES,
pNode->mMeshes[imeshes]->mIndexCount,
GL_UNSIGNED_INT,
(const void *) (pNode->mMeshes[imeshes]->mIndexOffset * sizeof(unsigned int)));
mVao.release();
}
}
// 递归绘制该节点的子节点
for (int inn = 0; inn < pNode->mNodes.size(); ++inn)
{
drawNode(&pNode->mNodes[inn], drawScaleMatrix);
}
}
主题颜色#
{
"theme-color": [
"#FFFFFF",
"#0066FF",
"#29A9FF",
"#91C6FF",
"#118DF0",
"#C70039",
"#FFC773"
]
}
依次为背景色、标题栏颜色、侧边栏颜色、滑块颜色、按钮悬停颜色、按钮按下颜色、菜单选项选中颜色。
支持保存工作区布局#
可以将工作区布局保存为单个文件,同时可以将部分数据和工作区一起保存。
可以选择配置文件以恢复工作区。
性能#
常规调试界面大量数据不卡顿。
实测 2M 波特率串口、每 ms 发送 28 个 float(约 256 字节)可长时间稳定。
大量波形绘制依赖设备性能,低配可能卡顿,可减小数据量。