首页/作品列表/自动倒桩入库小车
自动倒桩入库小车
16240 0
主要内容

项目目标


自动驾驶是未来的热门科技,也是各大科技圈dalao研究的技术。目前市面上的自动泊车不能做到“全自动”,还需要靠用户来协助完成,我们希望用一种比较简单的方式来实现全自动泊车。在第一个版本中,红外遥控十分不稳定,我们目前利用蓝牙和语音控制的方式远程操控小车,并且给小车加上避障绕行的功能,做成一辆简易的自动驾驶的小车。

项目原理

硬件组装

Tips:二轮小车一共有3个轮,前面有个万向轮,由于万向轮的不稳定性会导致小车不能走直线,建议固定。

根据源代码可以得到所有硬件的接口位置,另外注意超声波模块接法,具体参考老师写的WIKI。还有就是旁边两个超声波模块安装的位置要平行于车的边缘,新的版本两个超声波不再同一水平线上,需要计算误差在调用时补偿,两个模块安装要水平。蓝牙使用的是硬串口,语音识别模块使用的自定义的软串口。

程序调试

1.算法设计: 将整个程序分为6个部分,period123456,其中period5定义为手动控制模式(红外、蓝牙、语音),period6定义为避障前进模式,前4个为自动控制部分。 基本调用函数:
 灯:
//-----------------------灯
void liangdeng(int r,int g,int b,int mark)
{
if(mark==0)
{ strip.setPixelColor(0, strip.Color(r,g,b));
strip.show();
}
if(mark==1)
{
strip.setPixelColor(1,strip.Color(r,g,b));
strip.show();
}
if(mark==2)
{
strip.setPixelColor(0, strip.Color(r,g,b));
strip.show();
strip.setPixelColor(1, strip.Color(r,g,b));
strip.show();
}
}
超声波测距(部分):

//-----------------------------------------测距
float Distance_test1()//主
{
digitalWrite(TrigPin1, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin1, LOW);
distance1 = pulseIn(EchoPin1, HIGH) / 58.00;
return (distance1);
}
蓝牙控制:
void bluetooth()
{
while(Serial1.available()>0)
{
cmd+= char(Serial1.read());
delay(2);
}
if(cmd=="head")
{
liangdeng(255,255,255,2);
head();
Serial.println("HEAD");
}
if(cmd=="back")
{
liangdeng(255,215,0,2);
back();
Serial.println("BACK");
}
if(cmd=="left")
{
liangdeng(255,192,203,0);
left();
delay(350);
liangdeng(0,0,0,0);
STOP();
Serial.println("LEFT");
}
if(cmd=="right")
{
liangdeng(255,192,203,1);
right();
delay(350);
liangdeng(0,0,0,0);
STOP();
Serial.println("RIGHT");
}
if(cmd=="stop")
{
STOP();
Serial.println("RIGHT");
liangdeng(0,0,0,2);
}
if(cmd=="daoche")
{
period=1;//自动倒车
}
if(cmd=="auto drive")
{
period=6;//自动驾驶
}
cmd="";//执行后清空
}
阶段1:调整车子姿态,使其与路面平行
void period1()//---------------调整姿态
{
Serial.println("auto drive");
float t2,t3;
t2=Distance_test2();
t3=Distance_test3();
while((fabs(t2-t3))>0.5)//----------跳出条件
{
Serial.print("t2=");Serial.print(t2);
Serial.print("t3=");Serial.print(t3);
Serial.println(" ");
if (t2>t3&&(t2-t3)>10)//----------差距大用大调整
{
right();
delay(50);
STOP();
delay(250);
t2=Distance_test2();
t3=Distance_test3();
Serial.println("right");
}
if (t210)
{
left();
delay(50);
STOP();
delay(250);
t2=Distance_test2();
t3=Distance_test3();
Serial.println("LEFT");
}
if (t2>t3&&fabs(t2-t3)<=10)//----------差距小用小调整
{
right();
delay(30);
STOP();
delay(250);
t2=Distance_test2();
t3=Distance_test3();
Serial.println("right");
}
if (t2
{
left();
delay(30);
STOP();
delay(250);
t2=Distance_test2();
t3=Distance_test3();
Serial.println("LEFT");
}
// Serial.print(t2-t3); //---------串口监视器查看
// Serial.print("cm");
// Serial.println();

}
t2=Distance_test2();
t3=Distance_test3();

Serial.print("t2=");Serial.print(t2);
Serial.print("t3=");Serial.print(t3);
Serial.println(" ");
period=2;
}
阶段2:车子笔直前进直至到达停车位置
float t2,t3;
t2=Distance_test2();
t3=Distance_test3();

head();
//delay(100);
while(t2<20 && t3<20)
{
Serial.println("-----------------------------------------");
Serial.print("x=");Serial.println(t2);
Serial.print("y=");Serial.println(t3);
Serial.println("-----------------------------------------");
t2=Distance_test2();
t3=Distance_test3();

}
delay(300);//让车尾通过
STOP();


Serial.println("Period2 COMPLETE");
//STOP();
period=3;
}
阶段3:将车子原地旋转90度,将车尾对准停车口
void period3()//转弯
{
digitalWrite(OUT1A, HIGH);
digitalWrite(OUT1B, LOW);
digitalWrite(OUT2A, HIGH);
digitalWrite(OUT2B, LOW);
delay(600);//------------------此处需要实验 原410,该阶段不完美,仅是用实验来得出这个数值
STOP();// 跟地面光滑程度有很大关系,以后会改进方法,增加传感器,做到精确转弯
period=4;
Serial.println("Period3 COMPLETE");
}
阶段4:车子倒退,当车位靠近停车位末端时停车,自动停车完成
oid period4()//----倒车
{
float t1;
t1=Distance_test1();
back();
while(t1>5)
{

t1=Distance_test1();
}

//delay(50);
STOP();

Serial.println("COMPLETE");
period=5;

}
阶段5:手动控制模式
void period5()//遥控(语音蓝牙红外)
{
if(myserial.available())
{
val = myserial.read();//val的值事先在语音模块中设定,对应各个中文关键字
delay(50);

if (val==1)
{
liangdeng(255,255,255,2);
head();
delay(300);
STOP();
liangdeng(0,0,0,2);
Serial.println(val);

}
if (val==2)
{
liangdeng(255,215,0,2);
back();
delay(300);
STOP();
liangdeng(0,0,0,2);
Serial.println(val);
}
if (val==15)
{
liangdeng(255,192,203,0);
left();
delay(300);
STOP();
liangdeng(0,0,0,0);
Serial.println(val);
}
if (val==6)
{
liangdeng(255,192,203,1);
right();
delay(300);
STOP();
liangdeng(0,0,0,1);
Serial.println(val);
}
if (val==10)
{
STOP();
Serial.println(val);
}
if(val==19)
{
period=6;
}
}


if (irrecv.decode(&results)){
Serial.println(results.value,DEC);
switch(results.value)
{

case irhead:
liangdeng(255,255,255,2);
head();
Serial.println("HEAD");
delay(300);
STOP();
liangdeng(0,0,0,2);
break;

case irback:
liangdeng(255,215,0,2);
back();
Serial.println("BACK");
delay(300);
STOP();
liangdeng(0,0,0,2);
break;

case irleft:
liangdeng(255,192,203,0);
left();
Serial.println("LEFT");
delay(300);
STOP();
liangdeng(0,0,0,0);
break;

case irright:
liangdeng(255,192,203,1);
right();
Serial.println("RIGHT");
delay(300);
STOP();
liangdeng(0,0,0,1);
break;

case dianyuan:
period=1;
break;

}
irrecv.resume();

}
else if(Serial1.available())
{
bluetooth();
}
}
阶段6:避障前进模式
void period6()
{
float t1,t2,t3;
String break_cmd;
myservo.write(90);//初始化
//delay(500);
t1= Distance_test1();

Serial.print("middleDistance=");
Serial.println(t1);
// ---------------------满足条件一直前进
head();
while(t1>10)//一直到出现障碍物为止
{
t1 = Distance_test1();
delay(2);
if (Serial1.available())//蓝牙中断机制
{
while(Serial1.available()>0)
{
break_cmd+=char(Serial1.read());
delay(2);
}
if (break_cmd==break_value)
{
period=5;
break;
}
}
}
STOP();
//t1 = Distance_test1();
//------------------------
if(t1<=10)//前方出现障碍物
{
STOP();
delay(500);
myservo.write(0);
delay(1000);
t2 = Distance_test1();
Serial.print("rightDistance=");
Serial.println(t2);
delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
t3 = Distance_test1();//检查左右情况
Serial.print("leftDistance=");
Serial.println(t3);

delay(500);
myservo.write(90);
delay(1000);
if(t2>t3&&t2>20) //右边有路
{
turnright90();
delay(400);//暂停防止打滑

myservo.write(180);
delay(1000);
head();
while(t3 <20)
{
t3 = Distance_test1();
delay(2);
}
delay(500);//让车尾通过
STOP();
delay(500);
turnleft90();//进入右侧道路
delay(500);//防止打滑
myservo.write(90);
delay(500);
head();

}
else if(t220)//左边有路
{
turnleft90();
delay(400);
myservo.write(0);
delay(1000);
head();
while(t2 <20)
{
t2 = Distance_test1();
delay(2);
}
delay(500);//让车尾通过
STOP();
delay(500);
turnright90();//进入左侧道路
delay(500);//防止打滑
myservo.write(90);
delay(500);
head();
}
else
{
back();
delay(300);//没路
STOP();
period=5;//没路切换回手动控制
}
}
// period=5;

}
2.实现功能 手动模式:红外:按下遥控器上的方向键即可控制前进,后退,左旋转,右旋转;蓝牙:通过手机发送字符串命令实现,蓝牙控制(蓝牙能实现的控制距离较长较稳定) ;语音控制,分为近距离与远距离,近距离就是语音模块直接识别了,远距离通过微信来控制,即使人与小车相处几千米,理论上有网络的地方就能控制小车 自动模式:按下绿色电源键,开始进行自动倒车,目前还没设计出中断机制,该过程进行时不能进行手动操作。

视频演示




代码展示

1. 小车倒库

编程语言: C/C++(Arduino)

软件工具:Arduino IDE 1.6.9


附件下载
  • 资料展示
  • auto_reverse-master.zip
0
大牛,别默默的看了,快登录帮我点评一下吧!

立即注册