书接上回,看看API中几个比较酷的东西。
我们这回真需要弄一个小车子来测试我们的高级API了,我参考这本书《The LEGO MINDSTORMS EV3 Discovery Book》做了这么一个小车,见下图:
1,同时操作两个轮子的方法 Synchronization
前面我们说的都是让一个马达转起来的方法,但小车有两个轮子,如何做到同步?请参看如下代码
Motor.A.setSpeed(Motor.A.getMaxSpeed()*0.6f);
Motor.B.setSpeed(Motor.B.getMaxSpeed()*0.6f);
Motor.A.setAcceleration(600);
Motor.B.setAcceleration(600);
//绑定需要同步的几个马达
Motor.A.synchronizeWith(new RegulatedMotor[]{Motor.B});
//从startSynchronization/endSynchronization之间的代码将会同步执行
Motor.A.startSynchronization();
Motor.A.rotate(3*360);
Motor.B.rotate(3*360);
Motor.A.endSynchronization();
//必须的,否则不动,说明前面只是定义,这儿才真正执行
Motor.A.waitComplete();
如我注释中说的,我们需要将对多个马达的操作放到 startSynchroniztion/endSynchronization代码块中间,然后我们再使用waitComplete启动它们。
你可以稍修改一下代码,看看如果不把它们放在synchronization块中,是不是一个一个被执行了?
2,更复杂的导航器 Pilot
直到现在我们一直在研读lejos.hardware.motor包里的东西,其实Lejos已经帮我们实现了很多高级的马达操作,比如在lejos.robotics.navigation包里的那几个pilot类。
- DifferentialPilot ,使用两个马达驱动,可以前进后退转弯。
- CompassPilot,从DifferentialPilot派生而来,利用方向感应来行动,需要陀螺仪,这个类应该已经deprecated了。
- OmniPilot,基于万向轮的驱动,需要三个马达,无需转向,就可以向任意方向移动。
SteeringPilot ,两个马达,一个驱动,一个控制,类似那个机器蛇的移动。
我们来看看这里面最简单的DifferentialPilot吧,代码如下:
//轮子直径2.1,小道宽度4.4,由马达A和B组成,前进
DifferentialPilot pilot = new DifferentialPilot(2.1f, 4.4f, Motor.A, Motor.B, false);
pilot.setAcceleration(600);
pilot.setTravelSpeed(10);
pilot.setRotateSpeed(10);
//几个动作
pilot.travel(50);
pilot.rotate(-90);
pilot.travel(-50,true);
while(pilot.isMoving())
Thread.yield();
pilot.rotate(-90);
pilot.steer(-50,180,true);
pilot.steer(100);
Delay.msDelay(1000);
pilot.stop();
}
大概说明一下,构造时需要提供的参数包括:轮子直径、道路宽度以及两个马达。而pilot几个主要动作有:
- 基本的直线动作,持续进行,直到你停止它。
void backward() //一直后退.
void forward() //一直前进.
void stop() //停止.
- 弧线动作,指定半径和角度。
void arc(double radius, double angle) //根据指定的半径,转到指定角度停止。
void arc(double radius, double angle, boolean immediateReturn)
void arcBackward(double radius) // 指定转向半径,一直转
void arcForward(double radius) // 指定转向半径,一直反着转
- 移动指定距离,可以直线弧线。
void travel(double distance) //以直线移动指定的距离,如果distance为负表示后退
void travel(double distance, boolean immediateReturn)
void travelArc(double radius, double distance) //走弧线,根据指定的半径和距离
void travelArc(double radius, double distance, boolean immediateReturn)
- 转向,根据指定的角度,可以直接左转右转。
void rotate(double angle) //指定角度
void rotate(double angle, boolean immediateReturn)
void rotateLeft()
void rotateRight()
- 精细控制
void steer(double turnRate) //turnRate是两个轮子的转速差,取值从-200到+200
void steer(double turnRate, double angle) //移动到指定角度停止
void steer(double turnRate, double angle, boolean immediateReturn)
void steerBackward(double turnRate)
这一些函数的turnRate有说法,可以理解为两个轮子的速度比,ratio = 100 - abs(turnRate)。steer(0)表示同样转速,肯定直行;steer(100)表示内轮停车,外轮全速;steer(200)表示内轮反向全速,导致原地打转(漂移)。如果为负,内外反过来理解就对了。