# Raspberry Chess 项目报告
## 项目介绍
Raspberry Chess是基于树莓派平台的自动下棋机器人。
整个项目有大约600行Python代码,利用机器视觉和开源象棋引擎,控制机械臂,从而完成与用户对弈的功能。
项目主要分为三个模块:
* 视觉:识别棋盘和棋子的位置和类别
* 行棋逻辑:分析用户走法,计算最佳走法
* 机械臂控制:操作机械臂移动棋子
代码开源在[Github](https://github.com/YizhePKU/Raspberry-Chess)。
报告的第二部分是方案设计,例如在几个可能的方案中,我是如何做出选择的。
报告的第三部分是代码的详细文档,以及如何搭建这个项目的经验。
## 方案设计
### 器材的选用
我第一个考虑的问题是,如何让机械臂稳定地抓取和移动棋子?
与中国象棋扁平的棋子不同,国际象棋的棋子大都是立体的,并且顶面并不平整。
我使用的机械臂(越疆魔术师)有两种抓取模式,钩爪和吸盘,但对于形状不规整的棋子来说,这两种模式都不能很好地抓取棋子。
此外,机械臂的另一个问题是臂展相对较短,伸缩幅度只有25cm左右。这就意味着棋盘不能太大。
这两个问题意味着,市面上常见的国际象棋棋盘不能满足项目的需要。
几个可能的解决方案:
1. 对常见的棋盘加以改造,例如在棋子顶端黏贴硬纸板,以方便吸盘吸取。但这并不能解决机械臂臂展不足的问题。
2. 定制棋盘,例如自己设计棋子和棋盘,然后3d打印。缺点是比较麻烦。
最终的解决方法比较幸运:我恰好在淘宝上发现了合适的棋盘([商品链接][1])。
这种棋盘的棋子是平面的,而且棋盘较小,很适合机械臂的操作。
[1]: https://item.taobao.com/item.htm?spm=a1z09.2.0.0.69b52e8dbms51T&id=532708644440&_u=s2u449ftcb3f
### 棋盘位置的识别
对棋盘进行图像处理的第一步,就是找出棋盘四个角在图片中的位置,用透视变换把这四个角放到图片的四个角上去。
OpenCV提供一个函数:`findChessboardCorners()`。
这个函数会识别一个黑白棋盘的内部格点。例如,一个8x8的棋盘会识别出7x7个内部格点。
对这些内部格点做一个线性外插,应该就能得到棋盘四个角对应的位置。
我在这个方案上花了两节课时间,试图让`findChessboardCorners()`能够工作。
但是这个函数也有不少问题。
1. `findChessboardCorners()`的设计初衷是用于摄像头的矫正,而不是识别一个实际的象棋棋盘。因此在棋盘上有棋子时,识别正确率会大大降低。
2. 运算量很大,在树莓派上运行速度很慢(调用一次需要1~2秒)。
3. 无法分辨哪个是棋盘的“左上角”,哪个是“右下角”等等。
最终我放弃了这个方案。
新方案是,在棋盘的四个角贴上四种颜色的贴纸,利用颜色识别四个角。
这个方案的优点是简单方便,运行速度快,准确率高。
但缺点是,四块贴纸的中心与棋盘的四个角并不是完全重合的,需要在代码里手动矫正(比较hacky,第三部分会提到)。
### 棋子类型的识别
有了棋盘的图片,下面只需要把图片切割成8x8的小方格,然后分别识别棋子的类型即可。
这里有个小技巧:我们其实只需要识别棋子的颜色(白子,黑子,空格),而不需要识别棋子的类型(车,象,王,后)。
这是因为,国际象棋的每一步走法都可以用(棋子的出发地,棋子的目的地)这个二元组合唯一地表示。
例如,如果我们知道一步走法的出发点是e2,目的地是e4,那么我们就能判断出,白方的兵从e2走到了e4。
我们将这个状态保存起来,下次再遇见e4的时候,我们就知道这里肯定是一个白兵,不需要通过图像处理的手段识别棋子类型了。
有一个例外,就是兵的升变。国际象棋的规则是,兵在走到底线后,可以变成(后,车,象,马)中的任何一个棋子。
实际的对弈中大部分棋手都会选择变后(因为后最强大),但也有极少数情况,变后不是最佳选择。
不过对我们来说,在出现兵升变的情况时,默认变后已经足够了。
识别棋子类型的算法在第三部分会详细解释。
### 用户着法的分析,最佳着法的获取
在发现棋盘有变动之后,我们就可以通过对比棋盘前后哪些方格有变化,分析出用户的着法。
之后,将着法历史转换为代数记谱法(例如 ["e2e4", "d7d5", "e4d5"]),传给开源象棋引擎Stockfish。Stockfish会计算出机械臂的下一步最佳着法。
我利用了`python-chess`的一些封装,简化调用Stockfish的过程。
此外,从`python-chess`和Stockfish获取的最佳着法只包含了简要的走子信息(例如“f3上的马吃e5的兵”),
我们还需要将其转化为机械臂的实际操作流程(例如“先将e5上的棋子移出棋盘,再将f3上的棋子移到e5”)
### 机械臂的定位和校准
至此,最后一步就是让机械臂执行具体的操作指令(例如“将f3上的棋子移到e5”)。
如何定位呢?
最理想的方法是反馈控制,即用摄像头拍摄的实时画面,对机械臂的位置进行微调。但这个方式实现起来太过麻烦。
因此我采用了开环控制,在棋局开始时,让用户将机械臂放置在棋盘中央,之后的定位都按照相对这个中央的位置进行移动。
显然,这个做法会导致误差累积,偶尔会有定位偏差导致吸盘没能抓起棋子。此时我会稍微移动一下棋盘,手动纠正误差。
如果要实现真正的反馈控制,那么图像处理那方面就会更加复杂了。
## 代码文档与搭建经验
## 搭建准备
需要的硬件:
* 树莓派开发板
* 越疆魔术师机械臂(配吸盘)
* 摄像头
* 用于固定摄像头的支架
* 国际象棋棋盘
在树莓派上安装依赖:
* OpenCV-python,版本3(树莓派不支持版本4)
* `python3 -m pip install pydobot python-chess`
* `apt-get install stockfish`
然后如图搭建。下面是几个注意事项:
1. 棋盘的左上角的贴纸应该是红色。“外黑内白”的棋子是白子,应该放在用户一侧。“外白内黑”的棋子是黑子,应该放在机械臂一侧。
2. 棋盘稍微垫高一点,因为机械臂的臂展与操作的高度有关。
3. 棋盘如果不是正常的开局(例如少了几个棋子)需要在代码中设定(main.py)。目前版本的代码对应的就是如图的棋盘布局。
4. 摄像头固定得越高越好,可以减少因为画面扭曲造成的失真。
5. 机械臂开机后,长按Key键五秒后松开,可以重置机械臂,有利于提高定位精度。
<img src="images/setup.jpg" alt="搭建范例" width="400"/>
### 视觉模块:arm.py
`SquareType`表示一个方格的类型。
`SquareType.empty`表示这个方格上没有棋子。
`SquareType.white`表示这个方格上有一个白子。
`SquareType.black`表示这个方格上有一个黑子。
视觉模块提供了下面几个函数:
* `find_corners(image)` 从摄像头拍摄的图片中提取棋盘四个角的坐标。
* `transform(image, corners)` 对图片进行透视变换。
* `detect_square_type(image)` 识别(已经切割好的)一块图片是黑子还是白子。
* `get_position_from_image(image)` 上面三个函数的合并,从摄像头拍摄的图片中获取棋盘所有方格是黑子还是白子。
`find_corners(image)` 利用`cv2.inRange()`和`cv2.find_contour()`识别棋盘上贴的四张彩色贴纸。
识别颜色时用到的`masks`对于光线和摄像头很敏感。如果不能正常识别色块,可能需要调整`masks`中对应的hsv色彩范围�
阿齐Archie
- 粉丝: 4w+
- 资源: 2474
最新资源
- 信捷XC PLC与力士乐VFC-x610变频器通讯程序原创可直接用于生产的程序,程序带注释,并附送触摸屏程序,有接线方式和设置,通讯地址说明等 程序采用轮询,可靠稳定 器件:信捷XC3的PLC,博世
- CMIP6 变量详细表格
- KF2EDGK系列5.08接线端子,带3D封装
- 信捷XC PLC与3台力士乐VFC-x610变频器通讯通讯 原创可直接用于生产的程序,程序带注释,并附送触摸屏程序,有接线方式和设置,通讯地址说明等 程序采用轮询,可靠稳定 器件:信捷XC3的PLC
- org.xmind.ui.mindmap-3.6.1.jar
- 16台搅拌机定时控制程序16台搅拌机定时控制,使用三菱FX系列PLC,威伦通触摸屏,具备完善的控制功能
- 微网双层优化模型matlab 采用yalmip编写三个微网的分层优化模型,考虑电价的负荷响应,综合配电网运营商收益和用户购电成本,程序运行稳定
- rv1126交叉编译工具链gcc-arm-8.3-2019.02-x86-64-arm-linux-gnueabihf.tar.xz和安装步骤
- 1960-2023年世界各国国民总收入数据
- 风储深度调峰模型matlab 考虑风储的调峰模型,采用cplex作为求解器,实现不同主体出力优化控制,程序运行稳定,有参考资料,
- 计算机系统安全性与性能评估:IOMMU在Linux环境下的性能研究及其优化策略
- 电动汽车蒙特卡洛分析matlab 通过matlab程序编写电动汽车蒙特卡洛模型,得到汽车行驶里程的概率分布曲线和充电功率曲线,程序运行可靠,有参考资料
- 考虑交通流量的电动汽车充电站规划matlab 程序采用matlab编制,采用粒子群算法,结合交通网络流量,得到最终充电站规划方案,程序运行可靠
- rustdesk-1.3.6-x86-64.msi
- 电动汽车优化模型matlab 狼群算法
- 你还在为伺服驱动器 FPGA架构苦恼吗,本方案FPGA代码实现电流环 速度环 位置环 SVPWM 坐标变 测速 分频 滤波器等,程序方便移植不同的平台,具有很高的研究价值
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈