Created
July 17, 2017 06:49
-
-
Save brenapp/a4e5fb3b3cfaf5c7ca8b9c19ed651f44 to your computer and use it in GitHub Desktop.
Linker Error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Invoking make in /Users/tim/Documents/Robotics/In The Zone... | |
CPC -I../include -I../src motors.cpp | |
LN ./bin/auton.o ./bin/init.o ./bin/motors.o ./bin/opcontrol.o ./bin/pid.o ./bin/robot.o ./firmware/libpros.a -lgcc -lm to bin/output.elf | |
./bin/motors.o:(.data+0x0): multiple definition of `motors::slewRates' | |
./bin/init.o:(.data+0x0): first defined here | |
./bin/motors.o:(.bss+0x0): multiple definition of `motors::slewTargets' | |
./bin/init.o:(.bss+0x240): first defined here | |
collect2: error: ld returned 1 exit status | |
make: *** [bin/output.elf] Error 1 | |
The terminal process terminated with exit code: 1 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* motors.cpp | |
* Utilities for motors, including Deadbands, Slew Rate, and True Speed | |
*/ | |
#include "main.h" | |
#include "includes/motors.h" | |
// TODO: Move these to the utility file | |
int clamp(int value, int min, int max) { | |
if (value > max) return max; | |
if (value < min) return min; | |
return value; | |
} | |
int sgn(int value) { | |
return value > 0 ? 1 : value < 0 ? -1 : 0; | |
} | |
namespace motors { | |
int slewTargets[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
int slewRates[10] = {defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew, defaultSlew}; | |
/** | |
* Thanks to Jess from 21S for truespeed tables | |
*/ | |
static const char L298[128] = { | |
0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 11, 11, 12, | |
12, 12, 12, 13, 13, 13, 14, 14, 14, 14, | |
15, 15, 15, 16, 16, 16, 17, 17, 17, 18, | |
18, 18, 19, 19, 19, 20, 20, 20, 21, 21, | |
22, 22, 23, 23, 23, 24, 25, 25, 26, 26, | |
26, 27, 27, 28, 28, 29, 29, 30, 30, 31, | |
31, 32, 32, 33, 33, 34, 35, 35, 35, 35, | |
35, 35, 38, 38, 39, 41, 41, 41, 42, 43, | |
45, 46, 47, 47, 48, 49, 49, 50, 51, 52, | |
53, 54, 55, 56, 58, 59, 63, 66, 67, 70, | |
73, 74, 75, 78, 80, 84, 87, 88, 92, 95, | |
97, 100, 105, 108, 114, 117, 121, 122, 124, 127 | |
}; | |
static const char MC29[128] = { | |
0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 13, 13, 14, | |
14, 14, 14, 15, 15, 15, 15, 16, 16, 16, | |
16, 16, 17, 17, 17, 17, 17, 17, 17, 17, | |
18, 18, 18, 18, 18, 18, 18, 19, 19, 19, | |
19, 19, 20, 20, 20, 20, 21, 21, 21, 22, | |
22, 22, 22, 23, 23, 23, 23, 24, 24, 24, | |
25, 25, 25, 26, 26, 26, 27, 27, 27, 28, | |
28, 28, 29, 29, 30, 30, 30, 31, 31, 32, | |
32, 33, 33, 34, 34, 35, 36, 36, 37, 37, | |
38, 39, 40, 40, 41, 42, 43, 44, 45, 46, | |
46, 48, 49, 50, 51, 53, 55, 56, 58, 60, | |
62, 64, 67, 70, 72, 76, 79, 83, 84, 127, | |
}; | |
// Constructors | |
// TODO: Actually have inheritence | |
void Motor::init(int ports[], int invert[]) { | |
for (unsigned int x = 0; x < sizeof(ports); x++) { | |
Motor::ports[x] = ports[x]; | |
}; | |
for (unsigned int i = 0; i < sizeof(invert); i++) { | |
Motor::invert[i] = invert[i]; | |
}; | |
} | |
void TrueSpeedMotor::init(int ports[], int invert[]) { | |
for (unsigned int x = 0; x < sizeof(ports); x++) { | |
TrueSpeedMotor::ports[x] = ports[x]; | |
}; | |
for (unsigned int i = 0; i < sizeof(invert); i++) { | |
TrueSpeedMotor::invert[i] = invert[i]; | |
}; | |
} | |
// Motor set | |
void Motor::set(int pwm) { | |
for (unsigned int i = 0; i < sizeof(Motor::ports); i++) { | |
if(Motor::slew) { | |
slewMotorSet(Motor::ports[i], pwm * Motor::invert[(int)Motor::ports[i]]); | |
} else { | |
motorSet(Motor::ports[i], pwm * Motor::invert[(int)Motor::ports[i]]); | |
} | |
} | |
} | |
void TrueSpeedMotor::set(int pwm) { | |
for (unsigned int i = 0; i < sizeof(TrueSpeedMotor::ports); i++) { | |
int speed = pwm * TrueSpeedMotor::invert[(int) TrueSpeedMotor::ports[i]]; | |
speed = clamp(speed, -127, 127); | |
if(TrueSpeedMotor::slew) { | |
slewMotorSet(TrueSpeedMotor::ports[i], sgn(speed) * (TrueSpeedMotor::ports[i] == 1 || TrueSpeedMotor::ports[i] == 10 ? L298 : MC29)[abs(speed)]); | |
} else { | |
motorSet(TrueSpeedMotor::ports[i], sgn(speed) * (TrueSpeedMotor::ports[i] == 1 || TrueSpeedMotor::ports[i] == 10 ? L298 : MC29)[abs(speed)]); | |
} | |
} | |
} | |
// Slew Motor | |
void slewMotorSet(unsigned char channel, int speed, int rate) { | |
slewTargets[channel] = speed; | |
slewRates[channel] = rate; | |
} | |
void slewTask(void * parameter) { | |
while(true) { | |
// Iterate through all slew requests | |
for (unsigned int i = 0; i < 10; i++) { | |
if (motorGet(i) == slewTargets[i]) continue; // We're there, don't worry | |
int direction = sgn(slewTargets[i] - motorGet(i)); | |
int pwm = slewRates[i] * direction + motorGet(i); | |
if (abs(pwm) > abs(slewTargets[i])) pwm = slewTargets[i]; // If we're gonna go over, don't bother | |
motorSet(i, pwm); | |
} | |
delay(20); | |
} | |
} | |
void init() { | |
taskCreate(slewTask, TASK_DEFAULT_STACK_SIZE, NULL, TASK_PRIORITY_DEFAULT); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* motors.h | |
* Utilities for motors, as well as a better way of defining them | |
*/ | |
#pragma once | |
#define defaultSlew 10 | |
namespace motors { | |
/** | |
* Standard Motor Interface | |
*/ | |
class Motor { | |
public: | |
int ports[12]; | |
int invert[12]; | |
bool slew; | |
void set(int pwm); | |
void init(int ports[], int invert[]); | |
}; | |
/** | |
* True Speed applied to a motor | |
* | |
* VEX Motors don't increase at linear rates. They increase logarithmatically, so to counteract this, you map your requested values through | |
* a table to make them increase linearly. This is best for Programming Skills and Autonomous, where consistency is important, and PTC trips | |
* don't really need to be considered. | |
*/ | |
class TrueSpeedMotor { | |
public: | |
int ports[12]; | |
int invert[12]; | |
bool slew; | |
void set(int pwm); | |
void init(int ports[], int invert[]); | |
}; | |
/** | |
* Slew Rate applied to a motor | |
* | |
* Slew Rate was made to minimize PTC trips by linearly easing motor increases, as opposed to outright setting them. This way, there is not a sudden | |
* draw of power which would cause a PTC trip. This is best for Driver Control, as a driver's sudden changes in direction and driving style often | |
* involves setting motors to 127, but exact consistency isn't really a factor | |
* | |
* @param channel {unsigned char} The port to update | |
* @param speed {int} The target speed | |
* @param rate {int} The PWM to change per iteration | |
*/ | |
void slewMotorSet(unsigned char channel, int speed, int rate = defaultSlew); | |
extern int slewTargets[10]; | |
extern int slewRates[10]; | |
void slewTask(void * parameter); | |
void init(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment