智能小车设计实验指导书 联系客服

发布时间 : 星期三 文章智能小车设计实验指导书更新完毕开始阅读4925286f561252d380eb6ed7

{ bill_trans=20;

bill_rot=80; /*逆时针转*/ }

else if(ir==1) /*左侧有障碍,向右绕*/ { bill_trans=20;

bill_rot=-80; /*顺时针转*/ }

else if(ir==0) /*前方没有障碍,恢复直行*/ { bill_trans=80; bill_rot=0; }} wait(0.1); }}

56 }

void billiards_drive() { while(1)

{ running = bill_trans; /*能力风暴正在运动*/ drive(bill_trans,bill_rot); /*驱动电机*/ } }

void main() {

start_process(billiards_drive()); /*创建电机驱动进程*/ start_process(billiards_ir()); /*创建避障进程*/ start_process(billiards()); /*创建碰撞处理进程*/ }

改动以后的程序增加了避开侧面障碍物的行为。比较一下,增加的代码除了红外避障进 程外,就是用于进程之间的通讯。进程间的通讯和同步是多进程编程的难点,不解决好这个 问题,多进程程序可能会产生一些奇怪的行为。在这个程序里,由于碰撞处理进程和红外避 障进程都要修改设置电机速度的两个全局变量(bill_trans,bill_rot),这是进程间发生冲 突的根源。如果不加以限制,两个进程同时修改电机速度,必然会出现一片混乱,能力风暴 下一步的运动方向将无法预知。

本程序中把bmpr 改为全局变量,通过bmpr 来划分两个进程生效的时间。即发生碰撞时, 只有碰撞处理进程可以修改电机速度;在其他时间里碰撞处理进程只是在不断检测碰撞传感 器,只有红外避障进程才有可能修改电机速度。我们可以看到,在本程序里碰撞处理进程的 优先级高于红外避障进程。增加的另两个全局变量是出于红外避障行为逻辑的需要。全局变 量running 是能力风暴开始运动的标志,红外避障进程要等待这一事件发生后才能起作用。 forward 反映能力风暴当前运动方向,用于避免红外避障进程在后退时候处理前方障碍。

3、智能小车的行为控制

借助于多进程功能,可以方便实施目前处于研究前沿的行为控制方法。

行为控制的基本思想是建构行为能力,而非功能模块。首先把要设计机器人的行为特点描述下来,表达成基本的行为构成,如要做一只模拟机器飞蛾的智能小车,一边到处找食物,一边向较

- 15 -

强光飞去,同时撞上碰撞开关则向相反方向逃离,红外传感器发现障碍后避障。用行为控制来实现如下图所示。

四个基本行为结构很清晰,都是信号刺激→行为计算→执行。

由于执行机构(行走机能)只有一个,因此只有一个基本行为的输出能执行,这就需要优先仲裁机理。I1-I4 是优先极,I1 最高,谁的优先级高,运行谁的执行信号。

利用多进程程序设计方法,可以编写6个同时运行的进程,并通过全局变量实现进程之间的优先级与仲裁机制。

五、实验考核

编写一个智能小车漫步的行为控制程序,实现下列要求:

智能小车在默认状态下随机游走;当遇到强光时,便去追寻强光;当发现障碍物时,能够避开障碍物;如果碰到某个物体,则能够迅速向相反方向逃离该物体。

六、思考题

1、多进程编程比起单进程程序设计,有哪些优势?

2、在本次实验的程序编写中,是如何实现各个进程之间的优先级仲裁的?

- 16 -

附录: 库函数

1. 执行器输出

void stop() 关闭左右两个电机,停止运动;

void stop_motor(int m) 关闭电机m,0为所有电机,1为左电机, 2为右电机, 3为扩展电机; void motor(int m, int speed) 以功率级别speed(-100到100)启动电机m(1为左电机, 2为右电机, 3 为扩展电机);

void drive(int move, int turn) 同时设定两个电机的速度,move 为平移速度,turn 为旋转速度。

2. 传感器输入

int photo() 光敏传感器检测。photo(1)为检测左光敏, photo(2)为检测右光敏,返回值为0~ 255的数字量;

int microphone() 声音传感器检测。返回值为0~255的数字量;

int ir_detector() 红外传感器检测。返回值的意义:0=> 没有障碍, 1=>左边有障碍, 2=>右边有 障碍, 4=>前方有障碍;

int bumper() 碰撞传感器检测。返回值的意义:0=>无碰撞,1=>左前受碰,2=>右前受碰,4=> 左后受碰,8=>右后受碰。

int rotation(int index) 光电编码器脉冲累计读数,rotation(1)为检测左光电编码器,rotation(2)为 检测右光电编码器。

int digitalport(int channel)读数字口上传感器的值。channel的范围是0~7。返回值:从传感器数字硬 件读到的值为零伏或逻辑零时,返回1;否则返回0

int analogport(int channel) 读模拟口上传感器的值。channel的范围是0~7。返回值是0到255间的整数 值

int encoder(int index) 读取光电编码器的当前状态。0为低电平/1为高电平(分别对应光栅的通光缺口 /遮光齿)。

3. 时间

void wait(float sec) 延时等于或稍大于指定的sec时间(秒)后再执行后面的语句。sec是一个浮点数 void resettime() 将系统时间复位清零

float seconds() 以秒的形式返回系统时间,它是一个浮点数,精度为0.001秒

4. 声音

void beep() 产生一段0.3秒500赫兹的音频信号。发声结束后返回。

void tone(float frequency, float length) 产生一个length秒长音调为frequency赫兹的音频信号。

5. 电池

int battery() 检测电池电量,返回值为0~255的数字量;

116 6. 其他函数

void asosreset() 软件复位函数。与按下能力风暴的复位开关的效果一样,ASOS操作系统重启动, 程序停止运行。

int runbutton() 读运行键状态。运行键在能力风暴智能智能小车的头顶上,可以在程序中使用该 按钮。返回值:0没按,1按下 int abs(int val) 取整数val的绝对值 int max(int x, int y) 求两个整数的最大值 int min(int a, int b) 求两个整数的最小值 float rand() 返回0~1之间的随机浮点数

int random(int scale) 返回0~scale之间的随机整数

- 17 -