任务1 基本巡航动作
图3-1定义了机器人的前、后、左、右四个方向:当机器人向前走时,它将走向本页纸的右边;当向后走时,会走向纸的左边;向左转会使其向纸的顶端移动;向右转它会朝着本页纸的底端移动。
图3-1 机器人及其前进方向的定义
向前巡航
按照图3-1前进方向的定义,机器人向前走时,从机器人的左边看,它向前走时轮子是逆时针旋转的;从右边看另一个轮子则是顺时针旋转的。
回忆一下第2讲的内容,发给单片机控制引脚的高电平持续时间决定了伺服电机旋转的速度和方向。for循环的参数控制了发送给电机的脉冲数量。由于每个脉冲的时间是相同的,因而for循环的参数也控制了伺服电机运行的时间。下面是使机器人向前走3s的程序实例。
例程:RobotForwardThreeSeconds.c
● 确保控制器和伺服电机都已接通电源;
● 输入、保存、编译、下载并运行程序RobotForwardThreeSeconds.c。
#include<BoeBot.h> #include<uart.h> int main(void) { int counter; uart_Init(); printf("Program Running!\n"); for(counter=0;counter<130;counter++)//运行3s { P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20); } while(1); }
RobotForwardThreeSeconds.c是如何工作的
理解该例程的运行你应该没什么问题:for循环体中前三行语句使左侧电机逆时针旋转,接着的三行语句使右侧电机顺时针旋转。因此两个轮子转向机器人的前端,使机器人向前运动。整个for循环执行130次大约需要3s,从而机器人也向前运动3s。
关于例程调试的一点说明
例程中使用printf函数是为了起提示作用。若你觉得串口线影响了机器人的运动,可以不用此函数。还有一个进行调试的方法:让机器人的前端悬空,让伺服电机空转。这样调试起来就方便了,机器人不会到处乱跑。后面的例程调试也是这样。
该你了——调节距离和速度
● 将for循环的循环次数调到65,可以使机器人运行时间减少到刚才的一半,运行距离也是一半;
● 以新的文件名保存程序RobotForwardThreeSeconds.c;
● 运行程序来验证运行的时间和距离是否为刚才的一半;
● 将for循环的循环次数调到260,重复这些步骤。
delay_nus函数的参数n为1700和1300,都使电机接近它们的最大速度旋转。把每个delay_nus函数的参数n设定得更接近让电机保持停止的值——1500,可以使机器人减速。
更改程序中相应的代码片段如下:
P1_1=1; delay_nus(1560); P1_1=0; P1_0=1; delay_nus(1440); P1_0=0; delay_nms(20);
运行程序,验证一下机器人运行速度是否减慢。
向后走,原地转弯和绕轴旋转
将delay_nus函数的参数n以不同的值组合就可以使机器人以其他的方式运行。例如,下面的程序片段可以使其向后走。
P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20);
下面的程序片段可以使机器人原地左转。
P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20);
下面的程序可以使机器人原地右转。
P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20);
你可以把上述命令组合到一个程序中让机器人向前走、左转、右转及向后走。
例程:ForwardLeftRightBackward.c
● 输入、保存并运行程序ForwardLeftRightBackward.c;
#include<BoeBot.h> #include<uart.h> int main(void) { int counter; uart_Init(); printf("Program Running!\n"); for(counter=1;counter<=65;counter++)//向前 { P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20); } for(counter=1;counter<=26;counter++)//向左转 { P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20); } for(counter=1;counter<=26;counter++)//向右转 { P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20); } for(counter=1;counter<=65;counter++)//向后 { P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20); } while(1); }
该你了——以一个轮子为支点旋转
你可以使机器人绕一个轮子旋转。诀窍是使一个轮子不动而另一个旋转。例如,保持左轮不动而右轮从前面顺时针旋转,机器人将以左轮为轴旋转。
P1_1=1; delay_nus(1500); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20);
如果想使它从前面向右旋转,很简单,停止右轮,左轮从前面逆时针旋转。
P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1500); P1_0=0; delay_nms(20);
这些命令使机器人从后面向右旋转。
P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1500); P1_0=0; delay_nms(20);
最后这些命令使机器人从后面向左旋转。
P1_1=1; delay_nus(1500); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20);
把ForwardLeftRightBackward.c另存为PivotTests.c。
用刚讨论过的代码片段替代前进、左转、右转和后退相应的代码片段,通过更改每个for循环的循环次数来调整每个动作的运行时间,更改注释来反映每个新的旋转动作。
运行更改后的程序,验证上述旋转运动是否不同。