Firmware for UT Robotex 2018 basketball robot

Dependencies:   mbed USBDevice

Committer:
Reiko
Date:
Thu Oct 11 21:26:53 2018 +0000
Revision:
1:a286bf92d291
Parent:
0:ef6268629f0b
Child:
2:7affec1c81cb
Add thrower servo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Reiko 0:ef6268629f0b 1 #include "mbed.h"
Reiko 0:ef6268629f0b 2 #include "pins.h"
Reiko 0:ef6268629f0b 3 #include "motor.h"
Reiko 0:ef6268629f0b 4 #include "USBSerial.h"
Reiko 0:ef6268629f0b 5 #include "RFManager.h"
Reiko 0:ef6268629f0b 6
Reiko 0:ef6268629f0b 7 USBSerial serial;
Reiko 0:ef6268629f0b 8
Reiko 0:ef6268629f0b 9 Serial pc(USBTX, USBRX);
Reiko 0:ef6268629f0b 10
Reiko 0:ef6268629f0b 11 DigitalOut led1(LED_1);
Reiko 0:ef6268629f0b 12 DigitalOut led2(LED_2);
Reiko 0:ef6268629f0b 13 DigitalOut led3(LED_3);
Reiko 0:ef6268629f0b 14
Reiko 0:ef6268629f0b 15 static const int NUMBER_OF_MOTORS = 3;
Reiko 0:ef6268629f0b 16
Reiko 0:ef6268629f0b 17 PwmOut m3(M3_PWM);
Reiko 1:a286bf92d291 18 DigitalOut servo(ISO_PWM5);
Reiko 0:ef6268629f0b 19
Reiko 0:ef6268629f0b 20 Motor motor0(M0_PWM, M0_DIR1, M0_DIR2, M0_ENCA, M0_ENCB);
Reiko 0:ef6268629f0b 21 Motor motor1(M1_PWM, M1_DIR1, M1_DIR2, M1_ENCA, M1_ENCB);
Reiko 0:ef6268629f0b 22 Motor motor2(M2_PWM, M2_DIR1, M2_DIR2, M2_ENCA, M2_ENCB);
Reiko 0:ef6268629f0b 23 //Motor motor3(M3_PWM, M3_DIR1, M3_DIR2, M3_ENCA, M3_ENCB);
Reiko 0:ef6268629f0b 24
Reiko 0:ef6268629f0b 25 Motor * motors[NUMBER_OF_MOTORS] = {
Reiko 0:ef6268629f0b 26 &motor0, &motor1, &motor2
Reiko 0:ef6268629f0b 27 };
Reiko 0:ef6268629f0b 28
Reiko 0:ef6268629f0b 29 RFManager rfModule(COM1_TX, COM1_RX);
Reiko 0:ef6268629f0b 30
Reiko 0:ef6268629f0b 31 void serialInterrupt();
Reiko 0:ef6268629f0b 32 void parseCommand(char *command);
Reiko 0:ef6268629f0b 33
Reiko 0:ef6268629f0b 34 Ticker pidTicker;
Reiko 0:ef6268629f0b 35 unsigned int pidTickerCount = 0;
Reiko 0:ef6268629f0b 36 static const float PID_FREQ = 60;
Reiko 0:ef6268629f0b 37
Reiko 0:ef6268629f0b 38 char buf[32];
Reiko 0:ef6268629f0b 39 int serialCount = 0;
Reiko 0:ef6268629f0b 40 bool serialData = false;
Reiko 0:ef6268629f0b 41
Reiko 0:ef6268629f0b 42 bool failSafeEnabled = true;
Reiko 0:ef6268629f0b 43 int failSafeCount = 0;
Reiko 0:ef6268629f0b 44 int failSafeLimit = 60;
Reiko 0:ef6268629f0b 45
Reiko 1:a286bf92d291 46 Ticker softPWMTicker;
Reiko 1:a286bf92d291 47 Timeout softPWMTimeout;
Reiko 1:a286bf92d291 48 int currentServoPosition = 0;
Reiko 1:a286bf92d291 49
Reiko 0:ef6268629f0b 50 void pidTick() {
Reiko 0:ef6268629f0b 51 for (int i = 0; i < NUMBER_OF_MOTORS; i++) {
Reiko 0:ef6268629f0b 52 motors[i]->pid();
Reiko 0:ef6268629f0b 53 }
Reiko 0:ef6268629f0b 54
Reiko 0:ef6268629f0b 55 if (pidTickerCount++ % 60 == 0) {
Reiko 0:ef6268629f0b 56 led1 = !led1;
Reiko 0:ef6268629f0b 57 }
Reiko 0:ef6268629f0b 58
Reiko 0:ef6268629f0b 59 failSafeCount++;
Reiko 0:ef6268629f0b 60
Reiko 0:ef6268629f0b 61 if (failSafeCount == failSafeLimit) {
Reiko 0:ef6268629f0b 62 failSafeCount = 0;
Reiko 0:ef6268629f0b 63
Reiko 0:ef6268629f0b 64 if (failSafeEnabled) {
Reiko 0:ef6268629f0b 65 for (int i = 0; i < NUMBER_OF_MOTORS; ++i) {
Reiko 0:ef6268629f0b 66 motors[i]->setSpeed(0);
Reiko 0:ef6268629f0b 67 }
Reiko 0:ef6268629f0b 68
Reiko 0:ef6268629f0b 69 m3.pulsewidth_us(800);
Reiko 0:ef6268629f0b 70 }
Reiko 0:ef6268629f0b 71 }
Reiko 0:ef6268629f0b 72 }
Reiko 0:ef6268629f0b 73
Reiko 1:a286bf92d291 74 void softPWMEndPulse() {
Reiko 1:a286bf92d291 75 servo = 0;
Reiko 1:a286bf92d291 76 }
Reiko 1:a286bf92d291 77
Reiko 1:a286bf92d291 78 void softPWMTick() {
Reiko 1:a286bf92d291 79 if(currentServoPosition <= 0) {
Reiko 1:a286bf92d291 80 servo = 0 ;
Reiko 1:a286bf92d291 81 } else {
Reiko 1:a286bf92d291 82 servo = 1;
Reiko 1:a286bf92d291 83 softPWMTimeout.attach_us(softPWMEndPulse, currentServoPosition);
Reiko 1:a286bf92d291 84 }
Reiko 1:a286bf92d291 85 }
Reiko 1:a286bf92d291 86
Reiko 0:ef6268629f0b 87 int main() {
Reiko 0:ef6268629f0b 88 pidTicker.attach(pidTick, 1 / PID_FREQ);
Reiko 0:ef6268629f0b 89 //serial.attach(&serialInterrupt);
Reiko 0:ef6268629f0b 90
Reiko 1:a286bf92d291 91 //servo.period_us(20000);
Reiko 1:a286bf92d291 92
Reiko 0:ef6268629f0b 93 m3.pulsewidth_us(800);
Reiko 1:a286bf92d291 94 //servo.pulsewidth_us(0);
Reiko 1:a286bf92d291 95
Reiko 1:a286bf92d291 96 // TGY-180D (KC2462 controller) has problems with higher frequency PWM.
Reiko 1:a286bf92d291 97 // 50Hz works, but would like to use higher frequency for motors.
Reiko 1:a286bf92d291 98 // Software PWM seems to be good enough.
Reiko 1:a286bf92d291 99
Reiko 1:a286bf92d291 100 softPWMTicker.attach_us(softPWMTick, 20000);
Reiko 0:ef6268629f0b 101
Reiko 0:ef6268629f0b 102 while (1) {
Reiko 0:ef6268629f0b 103 if (rfModule.readable()) {
Reiko 0:ef6268629f0b 104 serial.printf("<ref:%s>\n", rfModule.read());
Reiko 0:ef6268629f0b 105 }
Reiko 0:ef6268629f0b 106
Reiko 0:ef6268629f0b 107 rfModule.update();
Reiko 0:ef6268629f0b 108
Reiko 0:ef6268629f0b 109 if (serial.readable()) {
Reiko 0:ef6268629f0b 110 buf[serialCount] = serial.getc();
Reiko 0:ef6268629f0b 111
Reiko 0:ef6268629f0b 112 if (buf[serialCount] == '\n') {
Reiko 0:ef6268629f0b 113 parseCommand(buf);
Reiko 0:ef6268629f0b 114 serialCount = 0;
Reiko 0:ef6268629f0b 115 memset(buf, 0, 32);
Reiko 0:ef6268629f0b 116 } else {
Reiko 0:ef6268629f0b 117 serialCount++;
Reiko 0:ef6268629f0b 118 }
Reiko 0:ef6268629f0b 119 }
Reiko 0:ef6268629f0b 120 }
Reiko 0:ef6268629f0b 121 }
Reiko 0:ef6268629f0b 122
Reiko 0:ef6268629f0b 123 void parseCommand(char *buffer) {
Reiko 0:ef6268629f0b 124 failSafeCount = 0;
Reiko 0:ef6268629f0b 125
Reiko 0:ef6268629f0b 126 char *cmd = strtok(buffer, ":");
Reiko 0:ef6268629f0b 127
Reiko 0:ef6268629f0b 128 // buffer == "sd:14:16:10:30"
Reiko 0:ef6268629f0b 129 if (strncmp(cmd, "sd", 2) == 0) {
Reiko 0:ef6268629f0b 130 for (int i = 0; i < NUMBER_OF_MOTORS; ++i) {
Reiko 0:ef6268629f0b 131 motors[i]->setSpeed(atoi(strtok(NULL, ":")));
Reiko 0:ef6268629f0b 132 }
Reiko 0:ef6268629f0b 133
Reiko 0:ef6268629f0b 134 serial.printf("<gs:%d:%d:%d>\n",
Reiko 0:ef6268629f0b 135 motors[0]->getSpeed(),
Reiko 0:ef6268629f0b 136 motors[1]->getSpeed(),
Reiko 0:ef6268629f0b 137 motors[2]->getSpeed()
Reiko 0:ef6268629f0b 138 );
Reiko 1:a286bf92d291 139
Reiko 1:a286bf92d291 140 } else if (strncmp(cmd, "d", 1) == 0) {
Reiko 0:ef6268629f0b 141 int pulsewidth = atoi(buffer + 2);
Reiko 0:ef6268629f0b 142
Reiko 0:ef6268629f0b 143 if (pulsewidth < 800) {
Reiko 0:ef6268629f0b 144 pulsewidth = 800;
Reiko 0:ef6268629f0b 145 } else if (pulsewidth > 2100) {
Reiko 1:a286bf92d291 146 pulsewidth = 2100;
Reiko 0:ef6268629f0b 147 }
Reiko 0:ef6268629f0b 148
Reiko 1:a286bf92d291 149 m3.pulsewidth_us(pulsewidth);
Reiko 1:a286bf92d291 150
Reiko 1:a286bf92d291 151 } else if (strncmp(cmd, "sv", 2) == 0) {
Reiko 1:a286bf92d291 152 currentServoPosition = atoi(buffer + 3);
Reiko 1:a286bf92d291 153
Reiko 1:a286bf92d291 154 if (currentServoPosition < 700) {
Reiko 1:a286bf92d291 155 currentServoPosition = 0;
Reiko 1:a286bf92d291 156 } else if (currentServoPosition > 2300) {
Reiko 1:a286bf92d291 157 currentServoPosition = 2300;
Reiko 1:a286bf92d291 158 }
Reiko 1:a286bf92d291 159
Reiko 1:a286bf92d291 160 //servo.pulsewidth_us(currentServoPosition);
Reiko 1:a286bf92d291 161
Reiko 1:a286bf92d291 162 } else if (strncmp(cmd, "gs", 2) == 0) {
Reiko 0:ef6268629f0b 163 serial.printf("<gs:%d:%d:%d>\n",
Reiko 0:ef6268629f0b 164 motors[0]->getSpeed(),
Reiko 0:ef6268629f0b 165 motors[1]->getSpeed(),
Reiko 0:ef6268629f0b 166 motors[2]->getSpeed()
Reiko 0:ef6268629f0b 167 );
Reiko 1:a286bf92d291 168 } else if (strncmp(cmd, "rf", 2) == 0) {
Reiko 0:ef6268629f0b 169 rfModule.send(buffer + 3);
Reiko 1:a286bf92d291 170
Reiko 1:a286bf92d291 171 } else if (strncmp(cmd, "fs", 1) == 0) {
Reiko 0:ef6268629f0b 172 failSafeEnabled = buffer[3] != '0';
Reiko 0:ef6268629f0b 173 }
Reiko 0:ef6268629f0b 174 }