去年暑假的时候偶然在网上看到有人做的冰球机器人,感觉比较有趣,用来做人机对战再合适不过。其中国内有些公司做的人机对战桌上冰球机器人,相关内容大多是新闻几句话带过,资料几乎没有。国外也有人做过冰球机器人,在youtube上可以搜到很多相关视频,开源的资料不算太多,主要参考了国外大神JJulio的项目。
GitHub - JJulio/AHRobot: Air Hockey Robot Project https://github.com/JJulio/AHRobot
国外大神视频点击这里:
还能这样玩:将 3D 打印机改造成桌上冰球机器人
自己制作的视频点击这里:
冰球机器人整体
冰球机器人摄像头处理画面
本想自己做个球桌,但是太麻烦,直接某宝买了一个,长这个样子,比较小。接下来就是将所有机械部分组装上去。
用solidworks画出整体效果,类似于写字机。用光轴、直线轴承、同步轮、同步带、惰轮搭出一个xy运动平面,设计一些打印件作为连接件,使用步进电机控制冰球击球器做一个平面运动。
第一次使用的是h-bot结构,这种结构简单省材料,但做出来才发现在高速运动下由于xy轴是联动的,x轴做的越长扭矩误差越大,击球器在x轴速度一旦快的话直接会卡住。无奈改成了这种结构,xy轴是分开控制的,x轴单独一个电机控制,y轴左右两边各一个电机,两个电机运动完全同步,这样速度相对于h-bot结构比较快。
下位机控制采用的arduino maga2560+ramps 1.4扩展板,和diy 3d打印机常用的主控一样。
下位机arduino代码使用的vs2013编译,arduino官方ide实在是太难用。visual studio安装一个arduino插件后也可以编译下载arduino代码。下位机功能类似于grbl固件,控制击球器点对点移动。与grbl不同的是,使用grbl固件时,向下位机发送A点坐标,电机向A点运动,运动期间再发送B点坐标,电机要到达A点之后才会向B点运动。但冰球机器人运动轨迹是上位机来预测的,终点在不断变化,如果还按照grbl固件来的话会走很多多余路线,多走也就意味着电机速度必须更快才能及时处理,电机更容易丢步。因此冰球机器人是接收到新的坐标便放弃上次坐标,向新的坐标运动。比如在向A点移动过程中发送B点坐标,则电机放弃A点立即向B点移动。
上位机使用的是vs2013+opencv3.3.0,opencv是个开源的视觉处理库,很多图像处理函数可以直接拿来用,用来处理球桌画面,捕捉冰球和机器人节省很多开发时间。可以百度一下如何搭建opencv环境,找到对应版本的vs和opencv,搭建成功之后才可以修改编译代码,如果只是运行exe文件不修改代码的话可以不搭建(exe文件稍后上传)。
图像处理的策略是:通过hsv颜色阈值在画面中寻找到冰球和打击器坐标,通过帧差判断出冰球的运动速度和方向,当冰球朝着机器人运动时根据冰球的轨迹预测撞击点坐标(其中包括有反弹和无反弹的情况),将预测的终点坐标发送给下位机,下位机运动到终点视具体情况进行防御或主动进攻。
以下为主要代码段:
int main()
{
if (configRead())//读取配置文件。配置文件为一个config.txt文档,不必搭建opencv环境也可以修改参数。包含串口号,摄像头号,冰球和机器人颜色阈值等
return -1;
VideoCapture capture(camera_cap);//打开摄像头
serialPortInit(serial_port);//打开串口
cout << "open the camera:" << camera_cap << endl;
cout << "open the serial port:" << serial_port << endl;
capture.set(CV_CAP_PROP_FRAME_WIDTH, RESOLUTION_X);//设置分辨率x
capture.set(CV_CAP_PROP_FRAME_HEIGHT, RESOLUTION_Y);//设置分辨率y
capture.set(CV_CAP_PROP_FPS, FPS);//设定帧率,好像没什么用
namedWindow("冰球机器人", 1);//创建大小不可改变的串口,名称为"AIR HOCKEY"
firstTime = (double)cv::getTickCount();//记录首次时间
//记录首次时间
while (true)
{
realTime = ((double)cv::getTickCount() - firstTime) / cv::getTickFrequency();//计算开机时间
run_counter++;//记录循环次数
capture >> frame;//获取一帧图像
GaussianBlur(frame, imgHSV, Size(5, 5), 0, 0);//高斯滤波
//medianBlur(imgHSV, imgHSV, 7);//中值滤波,未加入,速度太慢
cvtColor(imgHSV, imgHSV, CV_BGR2HSV);//RGB格式转HSV格式,减少光线干扰
inRange(imgHSV, Scalar(minH, minS, minV), Scalar(maxH, maxS, maxV), imgThresh);//冰球HSV阈值
inRange(imgHSV, Scalar(RminH, RminS, RminV), Scalar(RmaxH, RmaxS, RmaxV), imgThresh2);//机器人HSV阈值
//应用过滤膨胀操作进行滤波,未加入
trackObjectPuck();//寻找冰球
trackObjectRobot();//寻找机器人
cameraProcess(33.33);//预测冰球轨迹
newDataStrategy();//给机器人一个策略
//printf("%.2f: %d,%d\n", realTime, puckCoordX,puckCoordY);
sendMessage();//串口发送数据
//cout << coordResult << endl;//控制台输出坐标,调试使用
//COUT <
以下是百度网盘链接:
三维图
提取码:gcm9
冰球机器人opencv3上位机
提取码:4ayw
冰球机器人 maga2560下位机
提取码:2hr2