欢迎大家来到"探索号"火星车发布会的现场!

美国有NASA,我们有MARSA,这是它的英文名字Mars Assistance,火星探索辅助设备。


火星情况

要想去到遥远的火星去执行任务,我们当然要先弄清楚火星上面的基本情况是什么样的。通过查找资料,尤其是《火星救援》这部电影给了我们启发很多。

我们了解到火星,火星表面的平均大气压强不足地球上的1%,所以它时不时就会来一场席卷整颗行星大风暴。因此风化严重,火星上遍布撞击坑、峡谷、沙丘和砾石。另外,2014年科学家发现在火星内部存在庞大的水资源,酷似巨型“地下水库”。俗话说水是生命之源,我们有理由怀疑火星上会不会真的有生命,或者说是外星人呢。

日落下的火星山脉

有了这个怀疑,我们想要做的就是火星生命的探测。


探索号特点与功能

"探索号"火星车,它有以下几个特点和功能。

外观

首先外观上,大家可以看出我们使用了履带的设计。刚才我们讲到火星多风沙,那么履带的设计大大增强了火星车的稳定性;在坑洼地段履带比轮胎的脱困能力也会好很多;因为履带和地面的接触面积更大,所以对地面压强就很小,在沙地泥地里更不容易陷进去。

履带式设计

超声波避障功能

另外,为了应对比较恶劣的地质环境,我们还加入了超声波避障功能。

由于环境复杂多样,我们设计了两种避障策略。

  • 面对比较矮小的障碍物,火星车会利用自身的机械臂将自身撑起来而实现翻越障碍物;
  • 如果障碍物比较高大,火星车就会骂骂咧咧的走开,重新规划路线。

多级变速功能

为了使火星车前进的更加稳定,我们使用了姿态传感器,通过对欧拉角的判断实现了上坡加速,下坡减速。

智能检测功能

我们关注多学科交叉融合,坚持产学研一体化,刚才我们是火星车的任务是探测生命,于是我们调整我们之前做的大创项目,使用YOLO目标检测算法,通过火星车上的摄像头将视频流传回上位机进行检测。我们的算法可检测类别八十余种。

红外寻迹功能

难道外星人真的好找吗,不一定。我们火星车还实现了寻迹功能,可以外星生命的痕迹主动探索。


实现原理

超声波避障

障碍物类型的判断方法:当超声波检测障碍物距离小于阈值时,机械臂触地将火星车支撑起来,超声波持续检测,如果还能检测到障碍物则说明是高大障碍物,否则判断为矮小障碍物。

对于低矮障碍物,因为机械臂可使火星车直接翻越,因此火星车将慢速前进并收回机械臂;对于高大障碍物,火星车将后退并右转重新寻路。

避障流程图

技术细节:通过Get_distance函数获取超声波传感器检测前方障碍物的距离值,通过不断调试,我们将阈值调整到15。Angle[0]、Angle[1]、Angle[3]分别对应0、1、3号舵机负责调整机械臂姿态。

通过MOTOR_GO_FORWARD、MOTOR_GO_STOP、MOTOR_GO_RIGHT函数直接控制火星车的行进方向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void shangpo()
{
MOTOR_GO_STOP;
//停车
Angle[0]=0;
Angle[1]=70;
Angle[3]=0;
Delay_ms(500);
float distance = Get_distance(); //获取超声波传感器距离值
if((15<distance)||(distance<=0)) //判断超声波传感器距离值大于15小于等于0
{
MOTOR_GO_FORWARD;
Delay_ms(300);
MOTOR_GO_STOP;
Angle[0]=180;
Angle[3]=0;
Delay_ms(500);
Angle[1]=0;
Delay_ms(50);
MOTOR_GO_FORWARD;
Delay_ms(500);
return;
//forward(adjust,500);
Delay_ms(500);
}
else
{
Angle[0]=180;
Angle[1]=0;
Angle[3]=0;
Delay_ms(500);
MOTOR_GO_BACK;
Delay_ms(500);
MOTOR_GO_RIGHT;
Delay_ms(250);
MOTOR_GO_STOP;
}
return;
}

多级变速

变速策略为当火星车通过姿态传感器判断处于上坡状态或下坡状态。当处于上坡状态时,火星车加速前进,当处于下坡状态时,火星车减速前进。

变速原理

本功能的解码模块如图所示,其主要部分参考姿态传感器官方文档的帧设定。当传入数据帧头为0x53时,传递的是姿态信息。通过官方给的变换公式,我们便可以得到三个角度的姿态信息和一个温度信息。

1
2
3
4
5
6
7
8
9
10
11
void Communication Decode3(){
if(Communication_Decode_flag3){
Communication_Decode_flag3=0;
if(buffer3[0]==0x53){
ro11x=(buffer:3[2]<<8)|buffer3[1])/32768.0*180;
pitchy=(buffer3[4]<8)|buffer:3[3])/32768.0*180;
yawz=(buffer3[6]<<8)|buffer3[5])/32768.0*180;
temperature=((buffer3[8]<<8)buffer3[7])/100.0;
}
}
}

再通过其中的pitchy来判断上下坡信息并调整速度,并且上坡的度数越大,速度越快。下坡的读书越大,速度越慢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 int speed=3;
float s_up=1;
float s_down=3;

void main(void)
{
/* 设置系统时钟为72M ;*/
SystemInit();



SysTick_Configuration(); //SysTick中断配置,主要用来定时

//LCD_12864_init();//液晶屏初始化

GPIO_ALL_Config(); //GPIO初始化

//Init_LED(); //流水灯等延时38秒等待WIFI模块启动

//Init_Steer(); //舵机角度初始化

//TIM2_PWM_Init(); //定时器2(舵机PWM初始化)

TIM4_Init(); //定时器4(计时)

TIM5_PWM_Init(); //定时器5(电机速度PWM初始化)

USART1_Config(); //串口初始化

ifstop=0; //用来计数多长时间没有检测到黑线
USART3_Config();


Set_Right_Speed(500);
Set_Left_Speed(500);
while (1)
{
if(ifstop<150000){
TrackLine();
}
if(pitchy>190){
Set_Right_Speed((u16)(speed+(pitchy-180)*s_up));
Set_Left_Speed((u16)(speed+(pitchy-180)*s_up));
}
else if(pitchy<170){
Set_Right_Speed((u16)(speed+(180-pitchy)*s_down));
Set_Left_Speed((u16)(speed+(180-pitchy)*s_down));
}
else{
Set_Right_Speed(speed);
Set_Left_Speed(speed);
}
}
}

智能检测

yolov5智能检测的原理如图4-11所示。对于Yolov5,这是基于YOLOv3(一种轻量级检测网络)改进的。YOLOv5网络结构由四部分组成:输入侧,骨干,颈部和预测。输入端采用Mosaic数据增强,并针对不同数据集获得自适应锚帧计算和自适应图像缩放。骨干网络采用集中结构,同时设计两种CSP结构,一种应用于骨干网,另一种应用于Neck;颈部部分是FPN和PAN结构, 相比YOLOv4,YOLOv5不同之处在于颈部结构采用了从CSPnet设计中借鉴的CSP2结构,增强了网络特征融合的能力;输出端采用边界框损耗函数,实现更快更好的收敛效果。

YOLO检测

事实上,对于yolov5智能检测流程,未来我们还会进行进一步优化,具体如下:火星车在火星上进行搜寻,摄像系统将视频流传给火星基地,然后火星基地依靠强大的计算能力,分析得出相关结果,对小车下发指令,指导小车进行运动。下面是我们预期的工作流程图:

智能检测优化

红外循迹

此功能通过两个红外传感模块实现。其基本原理为检测红外线的反射,而黑线能够吸收红外线,因此黑线不会反射红外线,也就检测不到。通过这个原理,就可以判断当前车辆相对于黑线的位置。当两边都能检测到反射时,说明黑线在两个传感器中间,车辆前进。当左边或者右边检测不到反射时,说明车辆偏向一边,此时应该左转或右转。当两边都检测不到反射时,说明车辆到达终点,应该停下来。

寻迹原理

通过TR_L和TR_R分别接收红外传感器传来的数据,其中检测到值为1,没有检测到值为0。结合方向控制函数根据我们的基本逻辑即可实现红外循迹。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void line()
{
if((TR_L==0)&&(TR_R==0))//两边同时都没有探测到黑线
{
MOTOR_GO_FORWARD;
return;
}

else if((TR_L == 1)&&(TR_R== 0))//右侧遇到障碍
{
MOTOR_GO_LEFT;
return;
}

else if((TR_L == 0)&&(TR_R == 1))//左侧遇到障碍
{
MOTOR_GO_RIGHT;
return;
}

else if((TR_L == 1)&&(TR_R == 1))//左右都检测到黑线,就如视频中的那样遇到一道横的胶带
{
MOTOR_GO_STOP;
return;
}
}

问题与解决

超声波模块间歇失控

  • 问题描述:超声波模块有时距离障碍物很远时就启动机械臂,有时撞上障碍物时也没有反应。
  • 解决思路:我们首先怀疑是不是超声波模块有问题,我们换了几个模块还是有问题。然后我们觉得是不是模块缓冲区的问题,是不是上一次检测到障碍物时还未将结果存入缓冲区,再次启动时才将缓冲区读取出来,这样就可以解释“撞上障碍物时也没有反应,后面再次启动时又会立刻有反应”这一现象了。
  • 解决方法:最后我们发现是因为主代码中有一段中断程序,过了一段时间程序就会进入该中断而不再执行我们的代码,删掉中断程序后即可正常运行。

火星车行进偏移

  • 问题描述:火星车前进路线不直,上到跷跷板后会掉下来。
  • 解决方法:因为每个电机的生产情况不尽相同,因此相同的PWM信号也会使电机的旋转情况不同。需要自己手动补偿速度差异。

姿态传感器无效

  • 问题描述:在最初进行这个功能的调试过程中,我们发现火星车无法通过串口接收姿态传感器传递的内容
  • 解决思路:最开始我们以为是自身算法没有写好,但经过层层排查之后,我们发现用串口助手也无法接收到姿态传感器的内容,于是考虑是姿态传感器的问题,最终在更换姿态传感器后解决。

姿态传感器数据不准确

  • 问题描述:姿态传感器的角度信息不准确,当处于平地的时候会认为处于上坡。
  • 解决思路:通过多次实验发现姿态传感器的角度数据有一个固定的偏差,通过对接收到的角度数据做一个固定的调零后可以解决这个问题。

火星车的wifi模块的不稳定

  • 问题描述:火星车的wifi模块和电脑的连接经常会出现断连,重连的现象。
  • 解决方法:经过检查和分析,是火星车的STM32主板给wifi模块供电的电压不足。

火星车和WiFi模块的上位机通信

  • 问题描述:上位机(电脑或者手机)接入火星车的wifi之后,便仅能接收到视频,而不能给火星车下放指令。
  • 原因推断:在wifi开启之后,38秒流水灯还没有走完的情况之下,电脑就接入wifi,会打断STM32主板里面的相关指令接收模块的初始化。因为接入会给主板发送一个信号,相当于一个指令。

红外传感器灵敏度不足

  • 问题描述:红外传感器无法准确探测黑线,灵敏度不足。
  • 解决方法:通过手动使用螺丝刀调节红外传感器的灵敏度,可以调整红外循迹的流畅度,从而更好地实现循迹。

鸣谢:勇勇子、奇奇子