控制带轮子的小车
|
感谢网友动力老男孩 的翻译
控制带轮子的小车
双轮小车是一种常见的机器人,两个轮子都由独立的马达控制。
这种设计的小车可以使用不同的转向控制方式来控制。
leJOS NXT有很多类可以用来控制这种小车。
Pilot类
Pilot类通过调节小车马达的转速和转动方向来控制小车。
为了实现对小车的控制,Pilot类必须先知道机器人的配线图,
例如:各个马达分别连接在哪些端口;如何驱动马达来使小车前进或后退。
此外还需要知道轮子的直径,以及轨迹的宽度(也就是两个轮子之间的距离)
Pilot类通过轮子的直径来计算小车走过的距离,通过距离的比例来计算小车转过的角度。
显然,所有的参数必须使用相同的长度单位,但是具体用什么长度单位都是可以的(例如厘米,寸等,都可以)
如果设置参数准确的话,小车行驶的距离和旋转的角度,计算误差可以控制在2%以内甚至更小。
这些参数是通过Pilot类的构造器来设置的。
构造器:
Pilot(float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor)
参数分别为:wheelDiameter 轮子直径;trackWidth 轨迹宽度; leftMotor 左轮的马达;rightMotor 右轮的马达。另外一个构造器函数是:
Pilot(float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor, boolean
reverse) 如果你是从反向控制小车的话,可以把reverse 参数设置为true。
沿直线的运动
要控制小车沿直线运动,可以使用下列函数:
要控制小车前进或后退的距离,可以使用下列函数:
void travel(float distance)
void travel(float distance, boolean immediateReturn)
distance 必须使用和直径相同的长度单位; 负数的distance值表示向后运动。
你可以使用下面这个函数来获取某个时刻小车已经运动的距离
int getTravelDistance(); - 这个函数将返回在最后一次调用resetTachoCount();之后,小车行驶过的距离
例子:
import lejos.nxt.*;
import lejos.navigation.Pilot;
/**
* 一个在行驶途中遇到障碍物,会自动停止的机器人示例
*/
public class TravelTest {
Pilot pilot;
TouchSensor bump = new TouchSensor(SensorPort.S1);
public void go() {
pilot.travel(20, true);
while (pilot.isMoving()) {
if (bump.isPressed()) pilot.stop();
}
System.out.println(" "+pilot.getTravelDistance());
Button.ewaitForPress();
}
public static void main(String[] args) {
TravelTest traveler = new TravelTest();
traveler.pilot = new Pilot(2.25f, 5.5f, Motor.A, Motor,C);
traveler.go();
}
}
你可以通过下面的方法,使机器人在原地旋转指定的角度:
编程练习:正方形行程
使用Pilot类的travel和rotate函数编写一段代码,让小车运动轨迹呈现一个正方形。
答案看这里
编程练习:正方形行程2
编写一段代码,让小车的轨迹形成两个正方形的形状,然后沿原路返回。修改上一个程序中的traceSquare方法,让它可以沿任一方向走出正方形轨迹,然后在这个程序中使用它。这是一个非常严格的测试,可以知道你在pilot类中指定的“直径”和“轮间距”常量是否准确。
答案看这里
沿曲线路径运动
pilot类可以让机器人原地转身,方法是让一个轮子正转,同时另一个轮子反转。这个功能使用的方法是:
void rotate(int angle)
void rotate(int angle, boolean immediateReturn )
如果angle 参数是正的,机器人会转向左边。immediateReturn
参数的作用和在 Motor类的方法中是一样的–允许调用这个方法的线程在机器人旋转的同时进行其他的工作。
Pilot类也可以控制机器人沿一条弧线运动,使用的方法如下:
void steer(int turnRate) – 沿一个圆弧线运动,直到另一个函数把它停止下来
void steer(int turnRate, int angle)
void steer(int turnRate, int angle, boolean immediateReturn)
其中的turnRate参数决定了曲线路径的半径。这个参数为正时,表示圆弧转向的方向是机器人的左边(也就是说,左侧的轮子运动在内侧)。相应的,这个参数为负数时,圆弧会偏向机器人的右边。这个参数的绝对值必须在0到200之间,这个值取决于内、外两侧轮子的速度比。其中外侧轮子的转速就是机器人设定的转速,内侧轮子的转速更低,这样就可以使机器人转弯了。如果turnRate参数是0,那么内外侧轮子的速度比是1:1,机器人会向前直行。如果参数是200,那么速度比值是1:-1,机器人会原地旋转。如果参数是100,那么速度比值是0,内侧的轮子会静止不动(外侧的轮子绕着它旋转)。所以使用的公式应该是:speedRatio=1-abs(turnRate)/100。
其中的angle参数,表示旋转多少角度之后才停止,如果这个参数是负值,那么机器人会沿着上面说的路径的反方向旋转。
编程练习:方向控制测试
编写一个程序,使用按钮来输入路径的角度(turn rate)参数和角度(angle)参数。然后调用steer()函数观察小车的运动轨迹。这个程序可以循环运行,这样你就可以尝试各种不同的参数来控制轨迹。
答案看这里
Pilot类的其他方法
void resetTachocount() 重置两个马达的参数。这个函数不会被任何其他方法调用,所以如果你想使用getTravelDistance()和getAngle()这两个方法的话,必须自己调用这个函数。
void regulateSpeed(Boolean yes) 如果你想使用自己的方向传感器,加上steer方法来控制小车的运动,你需要用这个方法把速度自动校正功能取消。
boolean isMoving() 只要有任意一个轮子在运动,这个函数就会返回True。当你使用了immediateReturn参数,并且希望知道当前运动任务是否完成的时候,这个方法就非常游泳了。
boolean stalled() 如果两个轮子的速度都是0,这个方法会返回True。请注意,速度是通过每100毫秒采样一次获得的,所以在这个函数在小车开始运动的前100毫秒,会返回True。
如果你非要单独控制左右两个轮子,你可以使用下面的方法:
Motor getLeft()
Motor getRight()
返回顶部
罗盘导航
CompassPilot类(罗盘导航类)是Pilot类的一个扩展。它和Pilot类提供了一样的方法和功能,但是它支持的是第三方公司生产的电子罗盘传感器(compass sensor)。通过调用这个类的方法,才能保证机器人的运动不会偏离正确的方向。
这种模式下,需要HiTechnic或Mindsensors公司生产的电子罗盘传感器(接在NXT的一个传感器接口上)。这个类的构造器和Pilot类几乎一样,只是多了一个接入端口的参数信息。
C构造器:
CompassPilot(SensorPort compassPort, float wheelDiameter,float trackWidth,Motor leftMotor, Motor rightMotor)
CompassPilot(SensorPort compassPort, float wheelDiameter,float trackWidth,Motor leftMotor, Motor rightMotor, boolean reverse)
CompassPilot类中,新增的功能:
代码练习:CompassPilot类的新功能:
编写一段代码,按一下步骤完成运动:
校正电子罗盘传感器
旋转机器人90度
重置角度基准方向为0,也就是以当前方向为基准
向前移动一段固定的距离
再向左旋转90度
按原路返回
在每个步骤结束时,显示电子罗盘旋转的角度,和轮子移动过的距离。
建议:在机器人移动的时候,用手轻轻推动它,看看是否能转回正确的方向。
答案看这里
返回顶部
转速器导航
在控制两轮小车类中,有三个抽象的层。这种结构可以使你很容易的得到你需要的层,而不被其他低层次的层干扰。
转速器导航执行导航接口,这些接口定义了基本导航工作的方法。导航保持追踪机器人的坐标(x,y)和它前进的角度(机器人所面对的方向)。它使用了直角坐标系,和度数的角度。0度时指x轴,90度时y轴的正向。因为转速器导航需要一个导引来控制小车,它完成了你需要使用的通用的导引运动命令。
构造器:
此外,你也可以使用一个构造器,从你提供的信息中创建导引。参数列表与导引构造器里的相同。
TachoNavigator(float wheelDiameter,,float trackWidth, Motor leftMotor, Motor rightMotor)
TachoNavigator(float wheelDiameter,,float trackWidth, Motor leftMotor Motor rightMotor,boolean reverse)
基础的导航方法
设置和得到机器人坐标和分向量的方法:
- void setPosition(float x, float y, float directionAngle)
float getX()
float getY()
float getAngle()
得到角度和到某点坐标为(x,y)的距离的方法
float angleTo(float x, float y)
float distanceTo(float x, float y)
更新机器人位置坐标(x,y,角度)
在一个平面上控制机器人的运动
对于Pilot类,导航运动的控制方法有两个版本。一个版本只有当运动完成,并且机器人的位置被更新后才返回值。另一个版本可以选择在运动开始就立即返回值。当你使用这个选项时,你必须确定在机器人再次开始运动前,它的位置背更新过。
这个方法会在返回前自动调用updatePosition()
void stop()
void travel(float distance)
void rotate(float angle)
void rotateTo(float angle)
goTo(float x, float y)
这个方法让机器人在某圆弧上运动.(它调用了pilot.steer()). 如果半径是负值,旋转的中心就在机器人的右边。如果角度是负值,机器人就向后走。
这个方法要求你当运动结束包括需要immediateReturn 设置为True时,调用最新的位置。
void travel(float distance, boolean immediateReturn)
void rotate(float angle, boolean immediateReturn)
void rotateTo(float angle, boolean immediateReturn)
goTo(float x, float y , boolean immediateReturn)
turn(float radius, float angle, boolean immediateReturn)
forward()
backward()
rotateLeft()
rotateRight()
编程练习:测试转速器导航
写一个程序完成如下步骤:
将速度设置为500,初始航线为90度(即指向y轴)
运动到点(-10,0)
运动到点(10,20)
在运动过程中,在新一行中,每半秒显示一次x,y坐标。
答案看这里
返回顶部
罗盘导航
罗盘导航是转速控制导航的一个子类,它能执行所有的转速控制导航方法。
构造器:
也可以使用一个能从你给的信息中创建导引的构造器。参数列表与罗盘引导构造器中的一样。
CompassNavigator(SensorPort compassPort ,float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor)
CompassNavigator(SensorPort compassPort ,float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor, boolean reverse)
其他方法
void calibrate() 这个方法仅仅是在罗盘导引上调用相同的方法。
void updateHeading() 读取罗盘,更新机器人的方向
编程练习: 测试罗盘导航
对罗盘导航写一个程序,使它能够实现与转速器导航相同的步骤
返回顶部
|