问题
相机坐标系世界坐标到机械臂坐标的标定
解决方案设计
传统九点指针标注
- 传统的九点指针标注为标定板上固定九点田字,按照固定顺序(Z字)依次记录各个目标点在相机转化的世界坐标系下的坐标坐标
- 在机械臂上安装指针控制其移动并依次按上述顺序接触各个标定点获取对应的机械臂基座下的世界坐标系。
- 将两坐标系按顺序存储在两矩阵进行仿射获得补偿参数
优化方案
- 采用机械臂固定移动指定九个点,并采用指针进行物理世界中位置的定位
- 将准备好的标定目标移动至对应的位置。
- 软件内部对目标进行识别并识别一段时间后锁定记录对应坐标
- 将两坐标系按顺序计算对应矩阵的仿射变换获得补偿参数
具体操作
设定机械臂初始9个定点的坐标依次点击下一步进入下一个坐标节点,机械臂移动至指定位置移动标定目标到对应的指针下方重复上述过程依次得到九个点的图像坐标进行仿射变换
节点的特征提取
采用颜色筛选的方法进行过滤
转换到HSV空间筛选红色制作对应的蒙版针对蒙版提取轮廓并进行平滑处理根据目标轮廓图像的矩计算中心点的坐标- 累计计时确保目标明确后记录当前节点
问题1 机械臂坐标系到世界坐标系的转化
设计实验时考虑不周全忽略了随着机械臂移动相机自身的世界坐标系也随之发生运动进而导致坐标系补偿和实际存在较大偏差。
设计初
固定的相机世界坐标系
固定的机械臂坐标系
实际
随机械臂运动的世界坐标系
固定的机械坐标系
解决
暴力解决法
保持原有思路,首先移动机械臂确定落点位置,然后复位获得落点坐标,重复上述过程。
相对坐标法
在原有基础上记录一个相对坐标偏差,我们不妨假定机械臂坐标系足够精准,不存在X Y方向上的放缩偏差
首先以复位位置为基准点,机械臂坐标系下旧点的坐标为(x,y),新点的坐标为(x1,y1)
$$
x_{0}^1 = x_{0} + T_{x_{0}} \
y_{0}^1 = y_{0} + T_{y_{0}}
$$
在相机坐标系下
$$
x_{1}^1 = x_{1}+T_{x_{1}} \
y_{1}^1 = y_{1}+T_{y_{1}}
$$
由于相机和机械臂是刚性连接固定所以有
$$
T_{x_{0}} = T_{x_{1}} \
T_{y_{0}} = T_{y_{1}}
$$
进而我们在基准点的基础上对当前图像坐标系下获得的世界坐标添加参考机械臂坐标基于原点的相对移动即可解算出在基于基准点世界坐标系下各个标定的世界坐标。
问题2 记录当前节点的坐标存在问题
直接获取的节点为图像中的位置,而涉及坐标转换我们需要具体的世界坐标系下的位置,因而不能直接采取图像中的节点位置。
问题3 基于计算方法对标定点间距的考虑
附录
原始数据
直接读取相机坐标系,参考系随机械臂移动
RobotX | RobotY | WorldX | WorldY |
---|---|---|---|
310 | 10 | -32 | 21 |
310 | 0 | -31 | 22 |
310 | -10 | -32 | 24 |
300 | -10 | -31 | 24 |
300 | 0 | -31 | 23 |
300 | 10 | -31 | 20 |
290 | 10 | -31 | 20 |
290 | 0 | -31 | 22 |
290 | -10 | -32 | 22 |
相对移动修正后的坐标系坐标
RobotX | RobotY | WorldX | WorldY |
---|---|---|---|
310 | 10 | -11 | 23 |
310 | 0 | -11.86 | 15 |
310 | -10 | -12 | 4.8 |
300 | -10 | -21 | 5 |
300 | 0 | -21 | 12 |
300 | 10 | -21 | 22 |
290 | 10 | -31 | 22 |
290 | 0 | -30 | 14 |
290 | -10 | -30 | 5 |
变换矩阵
1 | 1.72 0.55 321.91 |
推测存在稳定误差的原因在与坐标点位于机械臂圆盘中心而标定处位于盘的边缘中间存在固定约为1.8cm左右的误差
控制逻辑
在夹取目标物体移动至指定位置并释放的过程中发现,在IO控制夹子后,后续无法通过控制机械臂进行移动目前原因不明。
为定位问题,我从以下几点尝试:
- debug观察receiveData的数值判断实际机械臂的状态。
- 在操作间增加休眠时间
经测试发现下位机发送的部分命令存在bug,命令应该按理来说是 命令-%-命令-% 的形式但是部分出现了命令打印和%处在同一返回值中。
UI数据绑定
初始设计和现在出现了一定冲突,在设计之初为了实现多设备共同管理采用了ObservableCollection
1 | PositionList.ItemsSource = Controller.Instance.DetectorModels; |
则会将每一台设备认为是一个ItemSouce,其如果以列表进行显示则无法将DetectorModel中的List列表数据进行显示,其将显示当前当前这个设备中的成员List,以一个集合的形式进行显示。
想到一个可行的思路,由于实际为单实例监控,所以可以创建一个List容器进行存储,等待9个数据表定存储后,通过按键或者监控进行触发参数的传递。及进一步的话可以采用但List对应多台设备,通过select进行选择后传入标定参数。
相机的数据,参数的内容都需要绑定到对应的Model,而List点的内容需要进行保存到当前XMAL类的LIst,进而XMAL不同内容需要分别采取对应的对象进行绑定。现在的问题是如何实现内部的List和Model之间的传参。
容器存储数据- DetectorModel和List参数自动传递
ObserveCollection绑定UI List 绑定UI通过绑定的对象实现参数的传递
经过研究发现原来Detector内部可以访问 Controller.Instance 内部成员,即可以在Controller.Instance 定义List列表,同时当更改时进行通知UI进行显示。
按键监听
再XAML注册按键函数后即可实现按键监听,但是由于初始设计的原因,按键监听被分割成了Window和标定Page两个界面。如果直接根据左侧菜单切换到标定界面,此时focus焦点仍然存在整个MainWindows如果此时监听键盘的话,需要再MainWindows注册
当点击当前page任意控件后,focus切换到当前页面,此时之前的监听已经失效,需要重新注册一个新的键盘监听事件。一个比较自然的解决方案是设置开始标定按钮将焦点主动且强制地切换当前page
按键事件和内部程序建立关联
按键可以触发全局controller但是具体内部类的串口内容绑定和发送仍有待实现。
更新日志
2021.10.28 增加棋盘格放置模式,预留行、列和释放目标旋转角度接口,默认采用1*1的作为固定角度,但角度无响应无法进行进一步测试
2021.11.10 获得角度控制指令采用G20 开头,重构状态控制,采用队列的方式进行任务创建,重新论证标定方式,发现该方法实际有效数据仅有一个采集点不具有鲁棒性后期添加采用键盘控制的方式进行标定,新增机械臂速度更新,解决之前指令不稳定失效的原因——指令间缺少换行符,对串口初始状态判断能否开启(尚未测试)可能需要进一步测试。采用新的线程管理任务,分离采集进程和工作进程
2022.1.13 完成队列模拟测试和标定设计,完成测试UI和数据绑定。
2022.1.16 完成标定视窗和后台处理。
Todo
采用队列管理状态的切换状态切换动作时延控制控制对正确性进行验证
对参数接口增加检查保证安全性
重构坐标变换模块
重构机械臂配置模块
UI界面重构
对检测器和机械臂参数进行分离于不同板块
串口在保存参数下默认开启由于占用或缺失导致程序崩溃
- 对正确性进行验证
对Detector模块内容精简去除冗余事件和委托
检查多次委托调用的情况,可能和序列化和INSTALL 造成的重复委托有关
模板制作过程中,框选目标后点击ESC仍然会进行模板的制作的bug
开启检测状态后无法对机械臂进行复位
增加状态重置模块清除当前state,laststate,计时计数变脸
机械臂角度无法旋转的bug机械臂下落点坐标
机械臂操作指令失灵的原因键盘操作控制机械臂移动进行九点标定
数据绑定算法验证新增模块添加键盘控制逻辑修改总流程控制逻辑- 核验九点标定流程
强制说明文档指明安装相机的位置和朝向