亚博 Arduino智能小车
一. 程序安装准备
首先安装了Arduino板载USB转串口CH340驱动安装包,若上述程序安装成功,则可以在我的电脑中找到相应的端口
本机端口号为COM3
然后安装了Arduino开发软件arduino-1.0.5-windows。安装好后可以打开界面
对钩是编译程序,
向右的箭头是编译程序加烧录程序
烧录成功后会出现以下界面
右上角那项是在用超声波时检测精确数据时使用,
可以看到数据时分的精确
这里右下角应该选择9600baud注意:每一次烧录选择端口在tools中选择
与其他程序相同应该及一些简单的快捷键,如:
Ctrl+N 新建
Ctrl+S 存储
Ctrl+C 剪切
Ctrl+O 打开
等等。。。。。
为小车的制作在软件上做好了准备。其中要注意端口号的一一对应。
二. 小车硬件安装
根据小车安装视频教程依次完成了电机固定,电池盒固定,上电测试和电池使用说明,万向轮与拓展面包板固定
,开发板与小车底板的固定,舵机云台的安装。
后面还有液晶屏的安装以及红外探头的安装,完成上述工作小车的雏形已经完成,十分美观可爱。
电机固定
电机在安装时注意两个螺丝先不能拧的太紧,以免第二颗放不进去,等螺丝螺母都放好后拧紧,
以免小车在行走时晃动,电机电源根据卡扣方向插紧即可,电机不能晃动,要放稳
电池盒固定
电池盒在固定时,一定要使用平口螺丝,防止电池放不进去,插头根据卡扣方向插紧即可。
上电测试和电池使用说明:
电池在使用时防止过度放电,一定要在过度放电前给电池充电。注意保护电池,根据说明使用,
在没有给小车安装开关以前,烧录程序时应断开vcc接口,防止小车乱跑损坏小车
万向轮与拓展面包板固定
先安装面包版底座选择最短的铜柱,两块面包版的凸起都朝向外侧,凹侧对着凸起的螺丝,
看准之后贴下,只有一次机会,所以得相当小心,安万向轮时注意线路,将线路走好,
不能影响万向轮的正常转动。拧螺丝时注意另一侧芯片。
开发板与小车底板的固定
开发板的固定选择中号铜柱,按地板的提示方向安装,注意正反面,在开发板面上上螺丝时只需安装三枚,
以为其中一枚的位置很特殊安装不当,很容易损坏开发板,最后将剩下三枚螺丝拧紧。
舵机云台的安装
舵机在安装时小螺丝一定要拧到底部,调节位置,因为舵机是180度旋转,最好能将左右两边分配90度,
以便后续实验操作,前面的插口安装超声波探测,后面的四个后依次安装到vcc gnd p2.7 以及开发板,
舵机的电源线十分长要在铜柱上旋转之后安装,以免影响转动和美观,但也不可在铜柱上旋转过多,
最好是两圈,具体根据实际操作。
液晶屏的安装
液晶屏分为八线安装与四线安装,本次实验我们选择四线安装,分别用到3.4.5.6.7.12.13这七个接口,
安装时由于接口有限我们安装与教程材料稍有出处,最终选择视频中的安装方法,
安装过程比较繁琐也比较困难,一定要耐心安装。
红外探头的安装
在安装红外线时要讲红外线程序包放入开发软件中,将红外接收口放到面包版上,
一段接a4,另外两端接vcc gnd ,特别注意要将接收口放到显眼的位置,方便接收信号。
三. 软件编程与试运行
智能小车调试
黑白线识别模块调试
由W3(W4)电位器,L2(L3)信号指示灯左光电传感器组成。 L2(L3)信号灯没有接接收到红外信号时会不亮(输出高电平1),
当 接到到红外反馈信号后,指示灯亮起(输出低电平0)。
避障模块调试
由W1(W2)电位器,L4(L5)信号指示灯左(右)光电传感器组成。 当L4信号灯没有接收到红外信号时不亮(输出高电平1),
当接到红 外反馈信号后,指示灯亮起(输出低电平0)。
电机模块调试:
测试条件,把EN1/EN2接到5V 正电源上。 IN1接到VCC(正5V 电源)(右电机反转信号线,高电平有效) IN2接到VCC(正5V 电源)
(右电机正转信号线,高电平有效) EN1接到VCC(正5V 电源)(电机使能信号,高电平有效) EN2接到VCC(正5V 电源)
(电机使能信号,高电平有效) IN3接到VCC(正5V 电源)(左电机正转信号线,高电平有效) IN4接到VCC(正5V 电源)(左电机反转信号线,高电平有效)
2.智能小车电路图和L293D内部等效图(双H桥路简单讲解)
对小车电路图和L293D内部等效图进行了一些简单的学习。
3.智能小车前进实验
代码如下:
int Left_motor_back=8; //左电机后退(IN1)
int Left_motor_go=9; //左电机前进(IN2)
int Right_motor_go=10; // 右电机前进(IN3)
int Right_motor_back=11; // 右电机后退(IN4)
void setup()
{
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM)
pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
}
void run(int time) // 前进
{
digitalWrite(Right_motor_go,HIGH); // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH); // 左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
delay(time * 100); //执行时间,可以调整
}
void loop()
{
delay(500);
run(10); //前进
}
给小车电机的接口分别接在8.9.10.11
这里的时间指的是毫秒,所以要乘100 delay(time * 100);
高电平给电机通电前进,而且这里可以选择转速,调节速度,这里如果小车不能走直线可以将左轮或右轮的速度进行相应的调整,
完成小车可以直线行走
小车直行这个实验特别简单只需读懂一些简单的代码即可,注意调节转速,以免损坏小车,
一定注意在烧录例程的过程中一定要主要断开vcc。
4.智能小车前后左右综合实验
代码如下:
void left(int time) //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH); // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左轮不动
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
void spin_left(int time) //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH); // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,200);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
void right(int time) //右转(右轮不动,左轮前进)
{
digitalWrite(Right_motor_go,LOW); //右电机不动
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,200);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
void spin_right(int time) //右转(右轮后退,左轮前进)
{
digitalWrite(Right_motor_go,LOW); //右电机后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,200);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
void back(int time) //后退
{
digitalWrite(Right_motor_go,LOW); //右轮后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,150);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,150);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
增加了向左转和向右转,向左转主要是控制左轮不动,邮轮前进,而向右转则是右轮不动左轮前进,
后退则是给两个轮子后退高电平,注意不能同时给前进和后退高电平,这样会烧坏电机,
同样烧录例程时要断开vcc,以免小车乱跑影响实验。
5.智能小车指定花式动作
代码如下:
void spin_left(int time) //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH); // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,200);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
void spin_right(int time) //右转(右轮后退,左轮前进)
{
digitalWrite(Right_motor_go,LOW); //右电机后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,200);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100); //执行时间,可以调整
}
主要是加了一些花式玩法,比如原地左转或原地右转,再加上左转右转的一些组合,
完成了一套花式动作。切记烧录例程时应断开vcc。
6.智能小车按键启动和蜂鸣器报警
主要是对小车进行蜂鸣器和启动键的安装
安装开关是为了在烧录过程中及时不断开vcc,小车也不会乱跑,以后每次烧录都不必断开vcc。
int key=7;//定义按键 数字12 接口
int beep=12;//定义蜂鸣器 数字7 接口
void keysacn()
{
int val;
val=digitalRead(key);//读取数字7 口电平值赋给val
while(!digitalRead(key))//当按键没被按下时,一直循环
{
val=digitalRead(key);//此句可省略,可让循环跑空
}
while(digitalRead(key))//当按键被按下时
{
delay(10); //延时10ms
val=digitalRead(key);//读取数字7 口电平值赋给val
if(val==HIGH) //第二次判断按键是否被按下
{
digitalWrite(beep,HIGH); //蜂鸣器响
while(!digitalRead(key)) //判断按键是否被松开
digitalWrite(beep,LOW); //蜂鸣器停止
}
else
digitalWrite(beep,LOW);//蜂鸣器停止
}
}
I/O 口的意思即为INPUT
接口和OUTPUT 接口,到目前为止我们设计的小灯实验都还只是应用到Arduino
的I/O 口的输出功能,这个实验我们来尝试一下使用Arduino的I/O 口的输入功能即为读取外接设备的输出值,
我们用一个按键和一个LED 小灯完成一个输入输出结合使用的实验,让大家能简单了解I/O 的作用。
按键开关大家都应该比较了解,属于开关量(数字量)元件,按下时为闭合(导通)状态。
我们分析电路可知当按键按下时,数字7 接口可读出为高电平。这时我们使数字11 口输出高电平可使小灯亮起,
程序中我们判断数字7 口是否为低电平,要为低电平使数字11 口输出也为低电平小灯不亮,原理同上。
要注意一点就是蜂鸣器有正负极之分,下面实物图可看到蜂鸣器有正负标记。
7.智能小车黑线循迹实验
利用小车下端两个探头对光的不同反应来确定小车行驶路线,主要是当探测到白时小车行驶电机转动,
当左侧压到黑线及探测到黑时小车向左行驶,当右侧探头探测到黑时则向行驶,
只需在之前的程序上加一个判定的过程,十分简单
const int SensorRight = 3; //右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4; //左循迹红外传感器(P3.3 OUT2)
SR = digitalRead(SensorRight);//有信号表明在白色区域,车子底板上L3亮;没信号表明压在黑线上,车子底板上L3灭
SL = digitalRead(SensorLeft);//有信号表明在白色区域,车子底板上L2亮;没信号表明压在黑线上,车子底板上L2灭
if (SL == LOW&&SR==LOW)
run(); //调用前进函数
else if (SL == HIGH & SR == LOW)// 左循迹红外传感器,检测到信号,车子向右偏离轨道,向左转
left();
else if (SR == HIGH & SL == LOW) // 右循迹红外传感器,检测到信号,车子向左偏离轨道,向右转
right();
else // 都是白色, 停止
brake();
这里使用了与的语句,当左边高电平右边低电频时想左,当左边低电平右边高电平时向右,若都是高电平则停车
这里的if else语句也满足了小车在行驶时的各种情况
8.智能小车红外避障实验1&2&3(基础避障)
与黑线实验类似,只是将判定写到了红外探头中,当红外探头探测到障碍时小车停止或者转向或者跟随障碍物行驶指向哪里走到哪里。
遇到障碍物后退:
else // 都是有障碍物, 后退
back(3);这里是与其他两个程序不同的一点,遇到了障碍则后退
SR_2 = digitalRead(SensorRight_2);
SL_2 = digitalRead(SensorLeft_2);
if (SL_2 == HIGH&&SR_2==HIGH)
run(); //调用前进函数
else if (SL_2 == HIGH & SR_2 == LOW)// 右边探测到有障碍物,有信号返回,向左转
left();
else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向右转
right();
else // 都是有障碍物, 后退
back(3);
遇到障碍物跟随:
else if (SL_2 == HIGH & SR_2 == LOW)
left();
这里与上一个程序不同,是跟随障碍物
哪里有障碍物就向哪里走,这是与上一个程序不同的地方,
若前方没有障碍物则停车
可以在这句话中体现
else // 没有障碍物,停
brake();
SR_2 = digitalRead(SensorRight_2);
SL_2 = digitalRead(SensorLeft_2);
if (SL_2 == LOW&&SR_2==LOW)
run(); //调用前进函数
else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向左转
left();
else // 没有障碍物,停
brake();
遇到障碍物转向
这里遇上两个程序不同的是增加了一个自动寻路功能,遇到障碍物后可以自己调节方向
可以在下面这句话中体现:
else // 都是有障碍物, 后退
{
back(4.5);//后退
spin_right(4.5);//有旋转,调整方向
先停车,停车之后转向,使得小车十分灵活,规避障碍物
SR_2 = digitalRead(SensorRight_2);
SL_2 = digitalRead(SensorLeft_2);
if (SL_2 == HIGH&&SR_2==HIGH)
run(); //调用前进函数
else if (SL_2 == HIGH & SR_2 == LOW)// 右边探测到有障碍物,有信号返回,向左转
left();
else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向右转
right();
else // 都是有障碍物, 后退
{
back(4.5);//后退
spin_right(4.5);//有旋转,调整方向
9.智能小车超声波测距实验
给小车安装液晶板与声波探头,对距离进行测量
这里程序中大家可以看到Fdistance= Fdistance/58;
这里选择除以58后再输出是因为为什么除以58等于厘米, Y米=(X秒*344)/2,
X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
void Distance_test() // 量出前方距离
{
digitalWrite(Trig, LOW); // 给触发脚低电平2μs
delayMicroseconds(2);
digitalWrite(Trig, HIGH); // 给触发脚高电平10μs,这里至少是10μs
delayMicroseconds(10);
digitalWrite(Trig, LOW); // 持续给触发脚低电
float Fdistance = pulseIn(Echo, HIGH); // 读取高电平时间(单位:微秒)
Fdistance= Fdistance/58; //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
Serial.print("Distance:"); //输出距离(单位:厘米)
Serial.println(Fdistance); //显示距离
Distance = Fdistance;
}
10.智能小车超声波避障实验(无舵机)
这里只是比之前多了一个转向遇到障碍物可以转向躲避,并测出距离
这时的小车已经十分的灵活,可以根据距离选择行驶的模式
可以在下面这句话体现
while(Distance < 60)//再次判断是否有障碍物,若有则转动方向后,继续判断
{
right(1);//右转
brake(1);//停车
Distance_test();//测量前方距离
Distance_display();//液晶屏显示距离
}
遇到障碍物先停车后向右转向
Distance_test();//测量前方距离
Distance_display();//液晶屏显示距离
if(Distance < 60)//数值为碰到障碍物的距离,可以按实际情况设置
while(Distance < 60)//再次判断是否有障碍物,若有则转动方向后,继续判断
{
right(1);//右转
brake(1);//停车
Distance_test();//测量前方距离
Distance_display();//液晶屏显示距离
}
else
run();//无障碍物,直行
11.智能小车超声波避障实验(有舵机)
舵机是一种位置伺服的驱动器,主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。
其工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为20ms,
宽度为1.5ms 的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
经由电路板上的IC 判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,
同时由位置检测器送回信号,判断是否已经到达定位。适用于那些需要角度不断变化并可以保持的控制系统。
当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
一般舵机旋转的角度范围是0 度到180 度。
舵机有很多规格,但所有的舵机都有外接三根线,分别用棕、红、橙三种颜色进行区分,
由于舵机品牌不同,颜色也会有所差异,棕色为接地线,红色为电源正极线,橙色为信号线。
舵机的转动的角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的,标准PWM(脉冲宽度调制)
信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms 之间,但是,事实上脉宽可由0.5ms 到2.5ms 之间,
脉宽和舵机的转角0°~180°相对应。有一点值得注意的地方,由于舵机牌子不同,对于同一信号,不同牌子的舵机旋转的角度也会有所不同。
用Arduino 控制舵机的方法有两种,一种是通过Arduino 的普通数字传感器接口产生占空比不同的方波,
模拟产生PWM 信号进行舵机定位,第二种是直接利用Arduino 自带的Servo 函数进行舵机的控制,这种控制方法的优点在于程序编写,
缺点是只能控制2 路舵机,因为Arduino 自带函数只能利用数字9、10 接口。Arduino 的驱动能力有限,所以当需要控制1 个以上的舵机时需要外接电源。
在无舵机的试验中往往遇到小车被卡住,那是因为声波探头探测范围小而小车体积很大,
所以探测有盲区,加上一个舵机之后,小车行驶前会转动舵机对左右两边的距离进行测量,
若左右两边都为安全距离,则小车直行,若左边探测非安全距离而右侧在安全距离,比对后转向右侧,
反之同理。这里还对舵机的转速进行了定义,并且注意小车速度,防止损坏舵机,超声波探头以及液晶显示屏。
while(1)
{
front_detection();//测量前方距离
if(Front_Distance < 32)//当遇到障碍物时
{
back(2);//后退减速
brake(2);//停下来做测距
left_detection();//测量左边距障碍物距离
Distance_display(Left_Distance);//液晶屏显示距离
right_detection();//测量右边距障碍物距离
Distance_display(Right_Distance);//液晶屏显示距离
if((Left_Distance < 35 ) &&( Right_Distance < 35 ))//当左右两侧均有障碍物靠得比较近
spin_left(0.7);//旋转掉头
else if(Left_Distance > Right_Distance)//左边比右边空旷
{
left(3);//左转
brake(1);//刹车,稳定方向
}
else//右边比左边空旷
{
right(3);//右转
brake(1);//刹车,稳定方向
}
}
else
{
run(); //无障碍物,直行
12.智能小车红外遥控实验
红外遥控器发出的信号是一连串的二进制脉冲码。为了使其在无线传输过程中免受其他红外信号的干扰,
通常都是先将其调制在特定的载波频率上,然后再经红外发射二极管发射出去,而红外线接收装置则要滤除其他杂波,
叧接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调。
内置接收管将红外发射管发射出来的光信号转换为微弱的电信号,
此信号经由IC内部放大器进行放大,然后通过自动增益控制、带通滤波、解调变、
波形整形后还原为遥控器发射出的原始编码,经由接收头的信号输出脚输入到电器上的编码识别电路。
要想对某一遥控器进行解码必须要了解该遥控器的编码方式。本产品使用的遥控器的码方式为:NEC协议。下面就介绍一下NEC协议的特点:
(1)8位地址位,8位命令位
(2)为了可靠性地址位和命令位被传输两次
(3)脉冲位置调制
(4)载波频率38khz
(5)每一位的时间为1.125ms或2.25ms
VOUT接到模拟口,GND接到实验板上的GND,VCC接到实验板上的+5v。
将红外接收头按照上述方法接好,将VOUT接到数字11口引脚,将LED灯通过电阻接到数字引脚2,3,4,5,6,7。
unsigned long last = millis();/*应用millis函数可获取机器运行的时间长度,单位ms。
系统最长的记录时间为9小时22分,如果超出时间将从0开始。函数返回值为unsigned long型,无参数。
注意:
复制\2.例程代码\例程19-红外遥控里的库文件夹IRremote到Arduino的安装目录
:Arduino\libraries目录下,缺失库文件可能编译出错。
给小车安装红外探头,并给遥控器定义,即可完成控制过程
long run_car = 0x00FF18E7;//按键2
long back_car = 0x00FF4AB5;//按键8
long left_car = 0x00FF10EF;//按键4
long right_car = 0x00FF5AA5;//按键6
long stop_car = 0x00FF38C7;//按键5
long left_turn = 0x00ff30CF;//按键1
long right_turn = 0x00FF7A85;//按键3
if (millis() - last > 250) //确定接收到信号
{
on = !on;//标志位置反
digitalWrite(13, on ? HIGH : LOW);//板子上接收到信号闪烁一下led
dump(&results);//解码红外信号
}
if (results.value == run_car )//按键2
run();//前进
if (results.value == back_car )//按键8
back();//后退
if (results.value == left_car )//按键4
left();//左转
if (results.value == right_car )//按键6
right();//右转
if (results.value == stop_car )//按键5
brake();//停车
if (results.value == left_turn )//按键1
spin_left();//左旋转
if (results.value == right_turn )//按键3
spin_right();//右旋转
last = millis();
irrecv.resume(); // Receive the next value
13.智能小车黑线循迹&超声波避障综合实验
是对黑线实验和超声波实验的一个综合,具体可参照上文
四. 心得与不足
这次实验是一人完成,过程比较艰辛,主要是在安装液晶板时出现了问题,经历了两三个小时对液晶板反复的安装,
最终克服困难,线路繁琐,工具不够是主要困难,对编程有了新的认识。
五. 总结
这次完成智能小车是一个有趣的事,本以为自己根本无法完成,因为自己基础很差,但是经过努力,
经过自学最总完成小车,并且第一个完成,什么事没有不可能的,只要努力.