本帖最后由 xvholly 于 2016-8-21 16:34 编辑
要想让机器人完成解魔方的各种动作,我们先来分解每个马达的最基本的动作,然后通过这些基本的动作组合实现机器人更复杂的动作指令。根据马达的不同位置和作用,我们将EV3 MindCub3r的三个马达命名为:底座马达、手臂马达和探头马达。 底座马达基本动作底座马达负责转动底座,自身可以完成魔方的旋转、配合手臂可以完成拧魔方最底层、配合探头可以完成魔方各个色块的颜色扫描。因此,底座马达的基本动作可以总结为: - 顺时针旋转90度
- 逆时针旋转90度
- 顺时针旋转180度(也可以采用逆时针,这里使用顺时针)
- 顺时针旋转45度(也可以采用逆时针,区别在于色块扫描的顺序,这里使用顺时针)
第一个问题:如何让底座转90度?仔细观察搭建图不难发现,动力系统是通过安装在大型马达上的一个小齿轮,带动底座下面的一个大齿轮完成的,并不很复杂。两个齿轮的传动比为1:3,即小齿轮转动3圈相当于大齿轮转动1圈。因此如果要底座转动90度,马达应转动270度,LEGO EV3的大型马达转1圈相应的走360步、即1步等于1度。 第二个问题:如何表示马达的运行位置?EV3的马达属于伺服马达,这种马达的优势就是可以通过转动的步数精确计算马达的位置(position),无论马达处在停止还是运行状态都可以读取当前位置。对于位置可以这样理解:设想马达刚连接到EV3端口上,此时的位置为0;当顺时针转动一圈之后,此时的位置是360;再逆时针转一圈,位置又回到0;如果继续逆时针转动,位置就会变为相应的负数。如果持续的转动,位置的值也会持续的增加(或减少)。 对于马达运行位置的表示,EV3提供了两种方式:绝对位置、相对位置: - 绝对位置:采用这种表示方式,无论马达此时的位置值是多少,都会运行到设置的位置值。比如:此时马达的位置值是360,设置运行到绝对位置90,马达不会顺时针转动90步,而是逆时针转动270步,之后位置值变为90。
- 相对位置:采用这种表示方式,运行的位置只是相对马达当前位置的位移。比如:此时马达的位置值是360,设置运行到绝对位置90,马达将会顺时针转动90步,之后位置值变为450。
对于底座马达,我们需要采用相对位置的运行方式。 第三个问题:马达每次停止都有一些位移误差?显然,这种位移误差对于需要精准控制底座角度的需求是无法容忍的。要想解决这个问题,需要先了解EV3马达的停止模式。EV3马达有三种停止模式:coast、brake、hold: - coast模式:马达得到停止指令时,停止供电,随惯性再转会停止。
- brake模式:马达得到停止指令时,停止供电,立刻停止转动,制动距离较coast模式要短得多。
- hold模式:马达得到停止指令时,马达并不会停止供电,而是将马达稳稳的保持在停止时的位置,此时如果你用外力强制改变他的位置,马达会强有力的跟你较劲,还是会转回它的位置。
综上,使用hold模式能够更精准的控制马达所转动的角度,也不会使底座发生“变形”。 最后:马达的速度设置EV3马达的速度有两种表达方式:速度值、占空比: - 速度值:马达的速度值单位为:步/秒,由于EV3马达一圈正好360步,因此等同于:角度/秒。
- 占空比:使用占空比表达马达的速度,取值范围-100%到100%,100%为顺时针最大速度。
这两种方式对于底座马达都可以,通常如果对速度的精度需求不那么大的情况下,可以采用占空比的方式。
程序设计 程序在ev3dev系统下使用Python编写,由于我使用的系统版本较早,可能跟最新的系统在函数命名、使用上有一些差异,但基本原理都差不多。
- import ev3dev
- # 底座的EV3大型马达接入主控制器A口
- base = ev3dev.large_motor('outA')
- if base.connected == True:
- # 设置速度控制模式为占空比
- base.speed_regulation_enabled = 'off'
- # 设置马达停止模式为hold
- base.stop_command = 'hold'
- # 底座顺时针旋转90度,占空比75%
- def base_clockwise():
- base.run_to_rel_pos(position_sp=270, duty_cycle_sp=75)
- while 'holding' not in base.state: time.sleep(0.2)
- # 底座逆时针旋转90度,占空比75%
- def base_anticlockwise():
- base.run_to_rel_pos(position_sp=-270, duty_cycle_sp=75)
- while 'holding' not in base.state: time.sleep(0.2)
- # 底座顺时针旋转45度,占空比30%
- def base_step():
- base.run_to_rel_pos(position_sp=135, duty_cycle_sp=30)
- while 'holding' not in base.state: time.sleep(0.2)
复制代码
链接:http://www.pazhong.net/?p=389
|