|
恩~是这样的,第二个程序咯这个是我接触乐高以来的,因为学校里有德国交换生来了,所以学校布置下任务要求我想一个乐高项目来进行演示,于是我选择了迷宫机器人。迷宫是一系列泡沫板拼接起来的,就是最普通的迷宫,里面没有任何记号。我选用的是一个超声传感器用于判断距离,然后每走30cm或者遇到障壁时停下进行一次左右方向的探测,然后根据“十”字岔路先直走然后若不通则退回来时左转(相当于进入十字路时右转)不通则退回直走(此时相当于左转)还不通则退回左转(相当于原路退出这个十字路)丁字路则先左后右然后返回,其他路总是先直走不通时再退回探测。可是当实际行走的时候出现以下问题:
1、机器人的判断频率似乎很难调整好,30cm有些地方可能超声探头刚好伸到岔路(车身还在直路里)而由于超声此时判断有岔路,若选择转弯则会卡在迷宫墙上,或者是直走转弯时可能由于左/右距离不够导致转弯时卡住
2、机器人选用2个伺服电机(B、C)加同样电压(设置为30)同时开关,但是行走时发现总是向左偏离直线,若设置为B=30、C=28,则会向右偏离直线,若选择B=30、C=29则向左偏,如此导致经常卡住或者卡在墙角(L形墙角前左右都认为被挡住了原地180度转弯会卡住,然后就一直在哪里转探头)
3、通过游标卡尺测得的两轮间距D(即车宽)与车轮直径d,计算转弯角度a及每个轮子所需转动角度b间关系的算式:b= (D*a)/d时实际转动的角度总是会多出那么4~5度(是指整辆车,如果是每个轮子的话肯定不止这么几度)
由以上这么多问题导致机器人总是无法正常通过迷宫(有时候需要用手去调整它的位置比如转弯角度太大的时候)能通过也是滑着墙过去的,有时甚至在不该回溯的地方回溯(由于转弯问题和走歪问题)
天朝说要河蟹不可以歪的!
附上程序各部件,希望各位大牛帮忙找找问题(程序上的),由于今天时间仓促,明天我会附上机器人的照片(配尺)希望大家能帮我找找错误,谢谢吖!因为后天下午就要演示了!><学校催的紧吖><
maze_stack.h:
- #define max_depth 100 //the max depth of the cross roads in the maze(no more than 100)
- int maze[max_depth];
- int head,top;
- bool push(int record)
- {
- if (top >= max_depth)
- {
- return false;
- }else{
- if (top < head)
- {
- top = 0;
- }
- maze[top] = record;
- top++;
- return true;
- }
- }
- int pop()
- {
- int record;
- if (top < head)
- {
- return -1;
- }else{
- record = maze[top];
- top--;
- return record;
- }
- }
复制代码
maze_motor.h:
-
- /*=================================================/
- / /
- / The Header of maze.c /
- / Here includes some definations and functions /
- / Made by CAKURA /
- /=================================================*/
- #define NEAR 10
- #define Can_pass 30
- #define h_WheelBase 12.5
- #define d_Wheel 5.5
- #define Turn_Angle(alpha) ((h_WheelBase*alpha)/d_Wheel)
- #define Angle 90
- #define left 2 //2 = 0b10 shows the left way hasn't been explored
- #define right 1 //1 = 0b01 shows the right way hasn't been explored
- #define step_len 30 //this parameter sets how often the robot stop to check the way(20 means stop per 20cm)
- #define tire_len (d_Wheel*PI) //this parameter shows the circumference of the tire
- #define turn_left 8 //8 = 0b1000 tells that we are now exploring the left cross
- #define turn_right 4 //4 = 0b100 tells that we are now exploring the right cross
- #define power_motor_run 30
- #define power_turning_sensor power_motor_run
- #define power_backing_sensor power_motor_run
- #define unexplored 3 // 3 = 0b11 the low 2 digs records the ways that hasn't been explored
- #define turning 12 // turning = 0b1100 the records the turnning direction we need to turn
- #define T_road 16 // 16 = 0b10000 sets if it is the T cross road
- bool left_ok,right_ok;
- int angle;
- task run_B()
- {
- RotateMotorEx(OUT_B,power_motor_run,-Turn_Angle(angle),0,false,true);
- left_ok = true;
- }
- task run_C()
- {
- RotateMotorEx(OUT_C,power_motor_run,Turn_Angle(angle),0,false,true);
- right_ok = true;
- }
- bool explore_left()
- {
- if (!(MotorRotationCount(OUT_A) == 0))
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- }
- ResetRotationCount(OUT_A);
- RotateMotorEx(OUT_A,power_turning_sensor,Angle,0,false,true);
- if (SensorUS(IN_4) > Can_pass)
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- return true;
- }else
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- return false;
- }
- }
- bool explore_right()
- {
- if (!(MotorRotationCount(OUT_A) == 0))
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- }
- ResetRotationCount(OUT_A);
- RotateMotorEx(OUT_A,power_turning_sensor,-Angle,0,false,true);
- if (SensorUS(IN_4) > Can_pass)
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- return true;
- }else
- {
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- return false;
- }
- }
- int turn_the_way(int ways)
- {
- int new_way;
- switch (ways)
- {
- case 1:
- new_way = 2;
- break;
- case 2:
- new_way = 1;
- break;
- default:
- new_way = ways;
- break;
- }
- return new_way;
- }
- void wait_motor(bool is_back,bool is_left)
- {
- left_ok = false;
- right_ok = false;
- if (is_back)
- {
- angle = 180;
- }else
- {
- if (is_left)
- {
- angle = Angle;
- }else
- {
- angle = -Angle;
- }
- }
- if (is_left)
- {
- start run_C;
- start run_B;
- }else
- {
- start run_B;
- start run_C;
- }
- while (!(left_ok && right_ok));
- stop run_B;
- stop run_C;
- }
- void run_step()
- {
- int distance;
- ResetRotationCount(OUT_BC);
- distance = SensorUS(IN_4);
- OnFwd(OUT_BC,power_motor_run);
- while (((distance - SensorUS(IN_4)) < step_len) && (SensorUS(IN_4) > NEAR)) ;
- Off(OUT_BC);
- }
- int check_ways()
- {
- int ways;
- ways = 0;
- if (explore_left())
- {
- ways = ways | left;
- }
- if (explore_right())
- {
- ways = ways | right;
- }
- return ways;
- }
复制代码
maze.nxc:
- #include "NXCDefs.h"
- #include "maze_stack.h"
- #include "maze_motor.h"
- //There's something you must know before reading the Program
- //the formation of data used in the stack is set to like this
- //sample data : 10 ;10 = 0b01010 and the low two digs 10 means there's 2 directions still not be explored
- //and the higher two digs 10 means when backing to this cross,we will choose to turn left(left = 0b10,right = 0b01)
- //and the highest dig 0 means it is not a "T" corss (1 means Yes)
- void init()
- {
- head = 0;
- top = 0;
- maze[top] = 0;
-
- //Setup the UltraSonicSensor installed in Socked_4,and start it to work
- SetSensorLowspeed(IN_4);
-
- //Reset the Rotation Count of Motor_A and sets it to fornt
- RotateMotorEx(OUT_A,power_backing_sensor,-(MotorRotationCount(OUT_A)),0,false,true);
- ResetRotationCount(OUT_A);
- }
- task main()
- {
- int ways,temp;
- bool backing;
- init();
- backing = false;
- while (1)
- {
- //we run steply to make sure we won't miss any possible crosses
- run_step();
- ways = check_ways();
-
- if (!(backing))
- {
- //if we are not going back
- if (SensorUS(IN_4) > Can_pass)
- {
- // if there's a way in front,we check the ways found by UltraSonic Sensor
- switch (ways)
- {
- case (left | right) :{ // if left & right is both accessible,we identify it as a "+" cross
- push(ways-1);
- run_step();
- break;
- }
- case (left) :{
- push((ways-1) | turn_right);
- run_step();
- break;
- }
- case (right) :{
- push((ways) | turn_left);
- run_step();
- break;
- }
- default :break;
- }
- }else
- {
- switch (ways)
- {
- case (left | right) :{
- push(1 | turn_left | T_road);
- wait_motor(false,true);
- run_step();
- break;
- }
- case (left) :{
- wait_motor(false,true);
- break;
- }
- case (right) :{
- wait_motor(false,false);
- break;
- }
- default :{
- wait_motor(true,true);
- backing = true;
- break;
- }
- }
- }
- }else
- {
- temp = pop();
- if (SensorUS(IN_4) > Can_pass)
- {
- switch (ways)
- {
- case (left | right) :{
- switch(temp)
- {
- case (left):{
- wait_motor(false,true);
- run_step();
- push(temp-1);
- backing = false;
- break;
- }
- case (right):{
- run_step();
- backing = false;
- push(temp-1);
- break;
- }
- case 0:{
- wait_motor(false,false);
- run_step();
- break;
- }
- default :break;
- }
- break;
- }
- case (left) :{
- wait_motor(false,((temp & turning) == turn_left));
- run_step();
- if (!((temp & unexplored) == 0)) push(temp-1);
- backing = ((temp & unexplored) == 0);
- break;
- }
- case (right) :{
- if ((temp & T_road) != T_road)
- {
- wait_motor(false,((temp & turning) == turn_left));
- }else{
- temp = (temp & unexplored) | turn_left;
- }
- run_step();
- if (!((temp & unexplored) == 0)) push(temp-1);
- backing = ((temp & unexplored) == 0);
- break;
- }
- default : break;
- }
- }else
- {
- switch(ways)
- {
- case (left | right):{
- wait_motor(false,((temp & turning) == turn_left));
- run_step();
- break;
- }
- case (left):{
- wait_motor(false,true);
- break;
- }
- case (right):{
- wait_motor(false,false);
- break;
- }
- case 0: StopTask(main);
- }
- }
- }
- }
- }
复制代码
万分感谢吖!
|
|