海信杯全地形小车比赛指南

Posted by 匿名 on November 1, 2023

项目介绍

循迹小车是一种能够自动沿着预定路径行驶的智能车辆,主要依靠‌传感器和算法技术实现路径识别和导航。‌‌

循迹小车的工作原理基于传感器技术,通常使用‌红外传感器、光电传感器或超声波传感器等,这些传感器能够检测出预定轨迹的变化。预定的轨迹通常由黑色线条或磁性条带组成,传感器通过检测轨迹与背景的对比来确定小车的位置和方向。控制系统负责处理传感器传回的数据,并通过相应的算法进行路径规划和运动控制,常用的算法有‌PID控制算法,这种算法能够根据小车偏离轨迹的程度,动态调整其行驶方向和速度,以确保小车沿着预定轨迹行驶。

循迹小车的核心部件包括红外传感器、光电传感器或超声波传感器等,这些传感器能够检测出预定轨迹的变化。通常,预定轨迹是由黑色线条或磁性条带组成,传感器通过检测轨迹与背景的对比来确定小车的位置和方向。控制系统则负责处理传感器传回的数据,并通过相应的算法进行路径规划和运动控制。

循迹小车的应用领域非常广泛,包括‌无人驾驶、‌物流配送、‌地图勘测、‌安全监控等多个领域。随着人工智能和物联网技术的不断发展,循迹小车的前景愈发广阔,其商业化的实现方式包括定制服务、租赁服务、销售等,创业者可以根据市场需求灵活选择适合自己的商业模式,实现商业价值的最大化。此外,循迹小车的研发和应用不仅局限于陆地领域,还可以扩展到水下和空中,随着技术的进步,其应用领域将越来越广泛。

代码实现

// 左边电机引脚5-6,右边电机引脚9-10,必须是有PWM功能的端口
// 循迹引脚 11-12-13-14,从车头方向的最左边开始排序
#define LeftMotor1 3  //Arduino的3号引脚连接在D0端口,利用宏定义可以方便后期改端口
#define LeftMotor2 5 	//Arduino的5号引脚连接在D1端口
#define RightMotor1 6	//Arduino的6号引脚连接在接D2端口
#define RightMotor2 9	//Arduino的9号引脚连接在接D3端口
#define track1 10	//Arduino的10号引脚连接在最左边的循迹模块的D0口,以下同理
#define track2 11
#define track3 12
#define track4 13

int Sensor[4] = {0, 0, 0, 0}; //初始化循迹的值
int i = 0;//计数或计时

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); //串口初始化
  Track_Init(); //循迹模块初始化
  Motor_Init(); //电机引脚初始化
}

void loop() {
  // put your main code here, to run repeatedly:
  Sensor_Read();  //不断地读取循迹模块的高低电平
  xun_ji(); //循迹函数
  count();  //计数函数
  Print();  //打印循迹的高低电平
}

void Track_Init()
{
  //循迹模块D0引脚初始化,设置为输入模式
  pinMode(track1, INPUT);
  pinMode(track2, INPUT);
  pinMode(track3, INPUT);
  pinMode(track4, INPUT);
}
void Motor_Init()
{
  //电机引脚初始化,设置为输出模式
  pinMode(LeftMotor1, OUTPUT);
  pinMode(LeftMotor2, OUTPUT);
  pinMode(RightMotor1, OUTPUT);
  pinMode(RightMotor2, OUTPUT);
}
void Sensor_Read()
{
  Sensor [0] = digitalRead(track1); //检测到黑线为高电平(1),白线为低电平(0)
  Sensor [1] = digitalRead(track2);
  Sensor [2] = digitalRead(track3);
  Sensor [3] = digitalRead(track4);
}
void Motor_Speed(int Left1_Speed, int Left2_Speed, int Right1_Speed, int Right2_Speed)  //控制电机的速度
{
  analogWrite(LeftMotor1, Left1_Speed); 
  analogWrite(LeftMotor2, Left2_Speed);
  analogWrite(RightMotor1, Right1_Speed);
  analogWrite(RightMotor2, Right2_Speed);
}
void xun_ji() //小车的速度可根据实际地图进行调节
{
  if (Sensor [0] == 0 && Sensor [1] == 1 && Sensor [2] == 0 && Sensor [3] == 0)  //0-1-0-0 小左转
    Motor_Speed(50, 0, 150, 0); //左轮速度 50 右轮直走 150
  else if (Sensor [0] == 0 && Sensor [1] == 0 && Sensor [2] == 1 && Sensor [3] == 0)  //0-0-1-0 小右转
    Motor_Speed(150, 0, 50, 0); //左轮速度 150 右轮速度 50

  else if (Sensor [0] == 1 && Sensor [1] == 0 && Sensor [2] == 0 && Sensor [3] == 0)  //1-0-0-0 大左转
    Motor_Speed(0, 180, 180, 0); //左轮速度 -180 右轮直走 180
  else if (Sensor [0] == 0 && Sensor [1] == 0 && Sensor [2] == 0 && Sensor [3] == 1)  //0-0-0-1 大右转
    Motor_Speed(180, 0, 0, 180); //左轮直走 180 右轮速度 -180

  else if (Sensor [0] == 1 && Sensor [1] == 1 && Sensor [2] == 0 && Sensor [3] == 0)  //1-1-0-0 左急转弯
    Motor_Speed(0, 200, 200, 0); //左轮反转 -200 右轮直走 200
  else if (Sensor [0] == 0 && Sensor [1] == 0 && Sensor [2] == 1 && Sensor [3] == 1)  //0-0-1-1 右急转弯
    Motor_Speed(200, 0, 0, 200); //左轮直走 200 右轮反转 -200
  else  //除了左右转,就只剩下直走
    Motor_Speed(100, 0, 100, 0);
}
void count()	//计黑十字的函数封装
{
  if (i > 2)  //i的具体范围要根据地图的黑十字路口而定!
  {
    Motor_Speed(0, 0, 0, 0);  //如果到达终点,就停车
  }
  else if (Sensor [0] == 1 && Sensor [1] == 1 && Sensor [2] == 1 && Sensor [3] == 1) { //1-1-1-1 计数
    i++;
    delay(100); //延时可以防止i加的过快
  }
  else if (Sensor [0] == 0 && Sensor [1] == 1 && Sensor [2] == 1 && Sensor [3] == 0) { //0-1-1-0 计数
    i++;
    delay(100);
  }
  else if (Sensor [0] == 1 && Sensor [1] == 1 && Sensor [2] == 1 && Sensor [3] == 0) { //1-1-1-0  计数
    i++;
    delay(100);
  }
  else if (Sensor [0] == 0 && Sensor [1] == 1 && Sensor [2] == 1 && Sensor [3] == 1) { //0-1-1-1 计数
    i++;
    delay(100);
  }
}

void Print()	//在串口打印循迹的高低电平
{
  Serial.print(Sensor [0]);
  Serial.print("---");
  Serial.print(Sensor [1]);
  Serial.print("---");
  Serial.print(Sensor [2]);
  Serial.print("---");
  Serial.println(Sensor [3]);
}