解魔方的机器人攻略21 – 读取魔方颜色

之前已经介绍了萝卜头转魔方的各个分解动作,今天介绍如何用颜色传感器读取魔方的颜色。这一部分可以分成三部曲:
1,依次扫描魔方的6*9=54个色块
2,用蓝牙连接把数据发送到电脑
3,通过颜色分组函数,从读数分辨出不同的颜色

这里先说明一下:虽然乐高的颜色传感器以RGB的形式返回颜色值,但是并不是想象中的那样,红色返回(255,0,0),蓝色(0,0,255)这么轻松。事实上这个数值受环境光线强度影响非常大,即使相同的环境下,读数仍然会有跳动。例如下面几个读数:

[0,1,2]=>RGB=(23,0,0),RawRGB={45,1,8}  //红色
[0,2,2]=>RGB=(30,0,0),RawRGB={60,1,5}  //红色
[2,1,2]=>RGB=(28,0,0),RawRGB={55,12,8}  //橙色
[2,2,1]=>RGB=(29,0,0),RawRGB={57,14,14}  //橙色

如果你仅想从RGB来分辨颜色的话,将会“很受伤”。不过今天我只介绍第一步(扫描),在PC端程序部分再介绍如何识别颜色。

因为颜色传感器一次只能读一个点,所以要扫描魔方的话,必须把54个点都扫到。我们以扫描其中一个面为例,看看两个电机怎么配合扫描到所有的9个点。首先,颜色传感器的电机中心位置,应该在2,4两个点的中心延长线上。这样在魔方位置不动的情况下,就可以扫描到中心和四个角了。(相关文章:颜色传感器的安装

扫描魔方中心和魔方的角

扫描魔方中心和魔方的角

然后,让底座旋转一定的角度,同时传感器电机也稍微调整,这样就可以扫到4个棱的颜色。

扫描魔方的棱

扫描魔方的棱

以这种方式扫描一圈,就可以把魔方的一个面读完了。最后使用魔方操作的分解动作,把魔方翻过来倒过去,直到把六个面依次扫描出来。有一件非常麻烦的事情是,在魔方翻来翻去的过程中,数组并不是每次都以0为左上角,它是不停的变换的(相关文章:魔方坐标系)。我用了下面这个map表,用来标记读数的顺序,这可是牺牲了数百个脑细胞换来的,其中idx数组是每个面内的依次读取顺序,idex2数组是不同的面的读取顺序:

int[][] idx={
	{4,6,7,8,5,2,1,0,3},
	{4,0,3,6,7,8,5,2,1},
	{4,2,1,0,3,6,7,8,5},
	{4,8,5,2,1,0,3,6,7},
	{4,2,1,0,3,6,7,8,5},
	{4,2,1,0,3,6,7,8,5}};
int[] idx2={5,1,4,3,2,0};

我们以上一次的程序为基础,添加以下变量和函数:

	//add offset positions for color sensor motor
	static int ColorMotorOffset1 = 33;
	static int ColorMotorOffset2 = 9;
	static int ColorMotorOffset3 = 18;
	static int ColorReadPostion1 = 162;
	static int ColorReadPostion2 = 154;

	//Read each side colors of the cube
	public static void ReadAllSide()
	{ }

	//Read one side by the index
	public static void ReadOneSide(int nSideIndex)
	{ }

最后加一个测试入口,当按下Enter键时,开始扫描魔方。相信看过前面文章的朋友,这里不需要说明了。点此查看具体的代码吧。

补充个小小的说明:我在代码里面统一用英文加了注释,不是在装酷,主要是因为上班的时候是这样强制要求的,以至于自己做东西也养成这种习惯了。



对 “解魔方的机器人攻略21 – 读取魔方颜色” 的 7 条 评论

  1. dot 说:

    又一次沙发

  2. dead_lee 说:

    不錯, 持續關注中

  3. inshua 说:

    應該用 HSL 中的某個分量按段來辨認顏色?

发表评论

可以使用下列 XHTML 标签:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>