分享一次参加机甲大师校赛的经历和收获

分享一次参加机甲大师校赛的经历和收获

本文最后更新于1586天前,其中的信息可能已经有所发展或是发生改变。

在填坑之前,再夹带一点私货,最近参加了RoboMaster加机甲大师校赛(很初级的校赛,真正的大型RoboMaster比赛级别是很高的,像我这种没有从一开始打基础的就不用想了),想写篇文章记录一下经过和收获,分享一下学到的东西。

起源

实际上我参加这个比赛是一次偶然的机会。一开始,先是我的一个小学弟,他找到了跟我同级同部门的一位老学长。比赛分为两项,RoboSpeed(自动循迹小车)和RoboBall(遥控小车推球),因此需要两个程序来负责。于是他找到我,问我要不要参加。我的回答是“行,我再了解了解吧~”,因为不是很了解,不知道如何控制单片机小车,就像先推辞一下。结果,几分钟后,我被拉进了RoboMaster小组群......既来之则安之,那就好好了解一下吧。

成果分享

小车机械部分的组装不是我的强项,我基本只负责代码和程序。talk is cheap, show me the code,先放上注释详尽的代码,再分享一些我们遇到的坑。

我们选用的开发板是arduino uno开发板,它的语法跟C语言相近,并且可以很方便的从官网下载到IDE,并将写好的代码编译,一键烧录到开发板中。

先贴上战果稍微好一些的遥控小车的代码。遥控小车使用的是HC-05蓝牙模块,使用手机进行遥控。另外还有一种方案,使用PS2手柄进行遥控,但在实际表现上来看,使用手机+蓝牙模块的效果并不比PS2手柄的效果差,而价格却比PS2手柄+专用信号接收器低很多。

Code Here:

#include <Servo.h>
//定义控制信令
#define STOP      0
#define FORWARD   1
#define BACKWARD  2
#define TURNLEFT  3
#define TURNRIGHT 4
#define JIASU     5

//在开发板上的输入输出管脚
int Left_motor_back = 5;   //左电机后退(IN1)
int Left_motor_go = 3;   //左电机前进(IN2)

int Right_motor_go = 6;  // 右电机前进(IN3)
int Right_motor_back = 9;  // 右电机后退(IN4)

int cmd;//控制信令

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go, OUTPUT);
  pinMode(Left_motor_back, OUTPUT);
  pinMode(Right_motor_go, OUTPUT);
  pinMode(Right_motor_back, OUTPUT);
  Serial.begin(9600);
}

//小车的基本动作
void goStraight()     // 前进
{//转速是由输入和输出正负两极的电势差决定的
  analogWrite(Left_motor_go, 110); // 左电机int,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back, 0); //右电机out,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_go, 110); //右电机in,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back, 0); //右电机out,PWM比例0~255调速,左右轮差异略增减
}

void brake()         //刹车,停车
{
  analogWrite(Left_motor_go, 0); //电势差为0,停止
  analogWrite(Left_motor_back, 0); //电势差为0,停止
  analogWrite(Right_motor_go, 0); //电势差为0,停止
  analogWrite(Right_motor_back, 0); //电势差为0,停止
}

void left()         //左转(左轮不动,右轮前进)
{
  analogWrite(Left_motor_go, 0);  //左轮不动
  analogWrite(Left_motor_back, 0); //左轮不动
  analogWrite(Right_motor_go, 120); //右电机in,PWM比例0~255调速
  analogWrite(Right_motor_back, 0); //右电机out,PWM比例0~255调速,左右轮差异略增减

}

void right()        //右转(右轮不动,左轮前进)
{
  analogWrite(Left_motor_go, 120); //左轮不动
  analogWrite(Left_motor_back, 0); //左轮不动
  analogWrite(Right_motor_go, 0); //右电机in,PWM比例0~255调速
  analogWrite(Right_motor_back, 0); //右电机out,PWM比例0~255调速
}

void back()      //后退
{
  analogWrite(Left_motor_go, 0); //左电机in,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back, 110); //左电机out,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_go, 0); //右电机in,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back, 110);
}

void jiasu()  //加速前进
{
  analogWrite(Left_motor_go, 175); // 左电机in,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back, 0); // 左电机out,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_go, 175); //右电机in,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back, 0); //右电机out,PWM比例0~255调速,左右轮差异略增减
}

//循环运行代码
void loop()
{
  char cmd = Serial.read(); //读取蓝牙模块发送到串口的数据
  switch (cmd) { //switch判断
    case FORWARD: {
        goStraight();
        break;
      }
    case TURNLEFT: {
        left();
        break;
      }
    case BACKWARD: {
        back();
        break;
      }
    case TURNRIGHT: {
        right();
        break;
      }
    case STOP: {
      brake();
      break;
    }
    case JIASU: {
      jiasu();
      break;
    }
  }
}

IMG_20191221_153311.jpg

遇到的坑:

  1. 不要单纯的以为亚克力板多么结实。我们的小车车身材料和推球的铲子的材质为亚克力,结果在决赛中车身撞到墙上,把推球的铲子撞掉了,推球能力下降,不敌对方。进入了决赛,可以考虑用金属车身。
  2. 转弯时,不能让车绕车中心旋转来进行,否则无法推球。必须让一侧的轮子停下或减小转速转弯。
  3. 操控车辆时,不要操之过急,切记在靠近球门时高速运球,防止把进球区的球撞出,或者让球装上墙壁反弹出进球区。
  4. 烧录程序时,要把HC-05模块从开发板上拔下,否则蓝牙模块可能无法正常工作。

下面是循迹小车的代码。

循迹小车就...比较玄学。在测试场地上,红外传感器比较灵敏,灰度传感器基本没法使用;而比赛场地却恰恰相反。传感器的灵敏度调整也是个费时间的活,比赛前一定要提早调整到最佳状态。

这种小车的思路有很多,最终我们选择了这种三传感器方案:左右传感器检测到白色,中间是黑色时,正常前进;左中白,右边黑或者左白,右中黑则向右转;右中白,左边黑或者右白,左中黑则向右转;都是白色则说明前进的太多,向后后退;都是黑色说明到达终点,小车停止。

我们还遇到了奇怪的问题:相同的电机,相同的电势差,转速却不同,所以程序中进行了矫正,速度根据电机和电池的不同情况自行填写测试吧。

Code Here,部分注释见上面的代码:

#include <Servo.h>
int Left_motor_go = 3;   //左电机前进(IN2)
int Left_motor_back = 5;   //左电机后退(IN1)

int Right_motor_go = 9;  // 右电机前进(IN3)
int Right_motor_back = 6;  // 右电机后退(IN4)

const int SensorMiddle = 12;     //中循迹红外传感器
const int SensorLeft = 10;       //左循迹红外传感器
const int SensorRight = 11;     //右循迹红外传感器

int SL;    //左循迹红外传感器状态
int SR;    //右循迹红外传感器状态
int SM;    //中循迹红外传感器状态

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go, OUTPUT); // PIN  5(PWM)
  pinMode(Left_motor_back, OUTPUT); // PIN 6 (PWM)
  pinMode(Right_motor_go, OUTPUT); // PIN 9 (PWM)
  pinMode(Right_motor_back, OUTPUT); // PIN 10 (PWM)

  pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
  pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
  pinMode(SensorMiddle, INPUT); //定义中循迹红外传感器为输入
}

//小车的基本动作
void goStraight()     // 前进
{
  analogWrite(Left_motor_go, 45); // 左电机前进,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back, 0);
  analogWrite(Right_motor_go, 63); //右电机前进,PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back, 0);
  Serial.println("Go");
  delay(30);
}

void brake()         //刹车,停车
{
  analogWrite(Right_motor_go, 0);
  analogWrite(Right_motor_back, 0);
  analogWrite(Left_motor_go, 0);
  analogWrite(Left_motor_back, 0);
  Serial.println("stop");
}

void left()         //左转(左轮不动,右轮前进)
{
  digitalWrite(Left_motor_go, 0);  //左轮不动
  digitalWrite(Left_motor_back, 0);
  analogWrite(Right_motor_go, 85); //右电机前进,PWM比例0~255调速
  analogWrite(Right_motor_back, 0);
  Serial.println("left");
  delay(25);
}

void right()        //右转(右轮不动,左轮前进)
{
  analogWrite(Left_motor_go, 62);
  analogWrite(Left_motor_back, 0); //左电机前进,PWM比例0~255调速
  analogWrite(Right_motor_go, 0);  //右电机不动
  analogWrite(Right_motor_back, 0);
  Serial.println("right");
  delay(25);
}

void back() {
  analogWrite(Left_motor_go, 0);
  analogWrite(Left_motor_back, 42); //左电机前进,PWM比例0~255调速
  analogWrite(Right_motor_go, 0);  //右电机不动
  analogWrite(Right_motor_back, 58);
  Serial.println("back");
  delay(20);
}

//循环运行代码
void loop()
{
  //有信号为LOW/0  没有信号为HIGH/1
  SR = digitalRead(SensorRight);
  SL = digitalRead(SensorLeft);
  SM = digitalRead(SensorMiddle);
  if (SL == 0 & SM == 1 & SR == 0)
    goStraight();   //调用前进函数
  else if (SL == 1 & SM == 0 & SR == 0)
    right();
  else if (SL == 0 & SM == 0 & SR == 1)
    left();
  else if (SL == 0 & SM == 0 & SR == 0)
    back();
  else if (SL == 1 & SM == 1 & SR == 1)
    brake();
  else if (SL == 0 & SM == 1 & SR == 1)
    left();
  else if (SL == 1 & SM == 1 & SR == 0)
    right();
}

遇到的坑:

  1. 如果有财力,一定要买动力更好的减速电机。普通的TT电机,电压不够就无法启动,电压足够之后速度又太快,不好控制速度。电池使用两节18650足矣。
  2. 灰度传感器和红外传感器传回的黑白数据刚好相反,如果使用灰度传感器的话,在loop()函数中将0和1互换即可。

收获

这次参加的RoboMaster加机甲大师校赛还是有很多收获的,得到了学分,收获了arduino uno开发板相关的知识,加强了我们小团队之间的了解。趁着我目前还有些空余的时间,这样的活动还是要多多参加的好。

本文永久链接:https://blog.xmgspace.me/archives/robomaster-school-match.html
本文文章标题:分享一次参加机甲大师校赛的经历和收获
如无特殊说明,只要您标明转载自Xiaomage's Blog,就可自由转载本文。禁止CSDN/采集站采集转载。
授权协议:署名-非商业性使用-相同方式共享 4.0(CC BY-NC-SA 4.0)

评论

  1. Windows Chrome
    4 年前
    2020-1-04 23:39:48

    赞一个,小马哥贼溜

发送评论 编辑评论


				
上一篇
下一篇