Skip to content

Instantly share code, notes, and snippets.

@brenapp
Created July 17, 2017 06:49
Show Gist options
  • Save brenapp/a4e5fb3b3cfaf5c7ca8b9c19ed651f44 to your computer and use it in GitHub Desktop.
Save brenapp/a4e5fb3b3cfaf5c7ca8b9c19ed651f44 to your computer and use it in GitHub Desktop.
Linker Error
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
/**
* 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);
}
}
/**
* 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