Skip to content

Latest commit

 

History

History
95 lines (56 loc) · 9.39 KB

readme.md

File metadata and controls

95 lines (56 loc) · 9.39 KB

Brief

此仓库仅作为本人在RoboMaster创梦之翼的工作记录,包含能量机关的识别和预测,本套代码理论上应在创梦之翼自瞄的基础上运行,但由于自瞄代码属于战队内部资源,不应该在个人仓库中公开,因此本套代码不保证能运行,仅作记录。

整体逻辑

务必认真阅读完规则手册后再阅读以下内容

架构

不含自瞄

画板

代码中的约定

  1. 扇叶:代码中描述扇叶的变量名一般为fanblade,如下图蓝色框框选处,共五片。

  1. R 型标:代码中描述R型标的变量名一般为R,如下图,一般位于能量机关装置的中心凸起处。

  1. 流水灯:代码中描述流水灯的结构体名为WaterfallLight,如下图黄色箭头所指处。

  1. 月牙形框:代码中描述月牙形框架的结构体名为MoonFrame,如下图蓝色框圈出的区域所示;其中月牙形框又分为outside_mooninside_moon,顾名思义外月牙就是距离 R 标远的,内月牙就是距离 R 标近的,下图所示上蓝框为外月牙、下蓝框为内月牙。(注:历史原因,在调试图像上,Moon 即为 outside_moon,T 即为 inside_moon)

基本信息

坐标系定义

坐标系定义

自定义消息

Fanblade.msg

std_msgs/Header header

geometry_msgs/Pose fanblade_center //扇叶中心坐标

geometry_msgs/Pose r_center //能量机关中心R型标坐标

geometry_msgs/Pose quaternion

float64[3] t_vec

uint8 rotation 0 //能量机关转向,默认为零,1顺2逆

Target.msg

std_msgs/Header header

geometry_msgs/Pose pose //待击打目标点位姿

float64 angle //当前扇叶角度

bool is_tracked

TrackedRune.msg

std_msgs/Header header

TargetState target_state

bool is_tracked

各节点职能

  • recognition-node:接受从相机节点中发来的/camera/front/capture/camera/front/camera_info进行图像处理识别,经过一系列函数preprocessfindWaterfallLightfindMoonFramematchFanBladesolvepnp,构建 Fanblade消息以 /rune/fanblade发送出去
  • transform-node:将接收到的相机系下的坐标转换为惯性系下
  • prediction-node:进行大小符预测,解算出惯性系下待击打目标点,构建 Target消息发送出去
  • tracker-node:将待击打的目标点套一层匀速卡尔曼滤波,使其更加平滑,减少云台抖动。该节点滤波器部分主要是@花譜所写

识别逻辑

只做概述,细节见代码

整体识别逻辑代码中较为清晰,此处不做赘述,但有几处判断逻辑需要额外说明一下:

  1. 颜色判断:取流水灯区域为 ROI,进行通道分离,根据红蓝通道均值大小判断颜色,红色通道均值大于蓝的为红,反之为蓝,详见代码;
  2. 内外月牙框的判断:遍历所有月牙形框,取与流水灯在一条直线上的两个框,距离流水灯近者为内月牙框,远的则为外月牙形框,详见代码;
  3. 能量机关转向的判断:记录前后两帧内外月牙框中心坐标,记内月牙框中心到外月牙框中心的向量为v,利用前后两帧向量的叉乘的正负判断顺逆时针旋转,详见代码;
  4. pnp 取点逻辑:计算方法使用cv::SOLVEPNP_IPPE,图像上的四点位置及顺序见下图。具体的选点方法也是根据向量叉乘结果的正负号判断的,代码已足够清楚,这里不再赘述。

需要注意的是识别使用了两套参数reco_config.yamlreco_home_test.yaml,前者为赛场光照环境下识别官方能量机关的参数,后者为家里场地光照环境下识别参数,在launch中可以切换。

预测逻辑

只做概述,细节见代码

预测部分除模型外唯一需要说明的就是模型求解之前的数据处理,由于两帧之间的时间差过于小,直接算角速度就会有较大的误差,因为这里的时间数量级很小,一个微小的误差会被无限放大,导致解算出的角速度误差很大,为避免这种情况,代码中直接使用角度时间这两个自变量求解模型。代码中的数据处理部分目标在于创建一个从零开始的、具有目标长度的序列,利用这两个序列求解模型。代码已足够明了。

对于模型部分,代码实现了GD(梯度下降法)、Ceres(google的一个开源 C++ 库,用于建模和解决大型、复杂的优化问题)以及高斯牛顿法。具体步骤可参考链接,不过实测下来Ceres和高斯牛顿法效果不佳,建议换更好的模型,可以参考一下这个GitHub - FaterYU/rm_buff: RoboMaster buff detect and predict,感觉不错。

识别调试方法

识别添加了在调试图像中的错误参数显示,在轮廓面积参数通过的情况下,对于错误识别的物体会以白色将其轮廓画出,并将参数错误值标注在轮廓旁边,具体如下图所示(这里显示的是未通过的MoonFrameasp参数实际值,画出的白色轮廓有些不明显,但放大还是可以看到的),然后根据显示的实际值调整相关参数,参考下面的调试视频(软件为 Foxglove,可以与ROS2联动,实现实时调参、实时更改)。

目前存在问题

  1. 预测模型收敛准确度不高,赛场上临时改用了一种极为狗屎的方法,详见代码。建议直接换模型;
  2. tracker节点匀速模型滤波有问题:滤波出的坐标与实际坐标有微小偏移,如图,这导致实际击打时需要给予 yaw, pitch 一定量的偏移,在自瞄firecontrol节点中专门加了关于能量机关的偏移补偿。

未来改进方向

  1. 预测模型改进:高斯牛顿法和梯度下降法收敛速度较慢且预测准确度不高,可以尝试对能量机关使用拓展卡尔曼滤波进行整体建模,参考GitHub - FaterYU/rm_buff: RoboMaster buff detect and predict
  2. tracker节点滤波器改进:目前tracker中采用的匀速模型卡尔曼滤波不太可靠,需要探索出更适合能量机关的、专用的模型;
  3. 自动击打:目前小符的命中率接近100%,可以尝试改用自动击打。大符在保证手动击打具有较高准确率的情况下,也可以尝试自动击打;
  4. 神经网络识别:预测准确度较高、击打效果较好的情况下,可以考虑将识别换成神经网络。
  5. 一些建议:强烈建议优先优化预测模型和滤波器。如果官方不对能量机关整体形状做大的改变的话,识别可以不用改动,把更多的时间放在预测模型的优化上;在保证预测准确度较高的情况下再尝试神经网络识别。

可用资源

  • 调试视频也已上传至语雀视觉组资源处,在 ROSbag 文件夹中