174 lines
4.8 KiB
C++
174 lines
4.8 KiB
C++
#include "motors_movement/drivecontroller.h"
|
|
#include "sensors/sensors.h"
|
|
#include "behaviour_control/status_vector.h"
|
|
#include "vars.h"
|
|
|
|
DriveController::DriveController(Motor* m1_, Motor* m2_, Motor* m3_, Motor* m4_){
|
|
m1 = m1_;
|
|
m2 = m2_;
|
|
m3 = m3_;
|
|
m4 = m4_;
|
|
|
|
pDir = 0;
|
|
pSpeed = 0;
|
|
pTilt = 0;
|
|
|
|
vx = 0;
|
|
vy = 0;
|
|
|
|
speed1 = 0;
|
|
speed2 = 0;
|
|
speed3 = 0;
|
|
speed4 = 0;
|
|
|
|
delta = 0;
|
|
input = 0;
|
|
output = 0;
|
|
setpoint = 0;
|
|
|
|
pid = new PID(&input, &output, &setpoint, KP, KI, KD,DIRECT);
|
|
|
|
pid->SetSampleTime(2.5);
|
|
pid->setAngleWrap(true);
|
|
// pid->SetDerivativeLag(2);
|
|
pid->SetOutputLimits(-255,255);
|
|
pid->SetMode(AUTOMATIC);
|
|
|
|
// Complementary filter for speed
|
|
speedFilter = new ComplementaryFilter(0.3);
|
|
|
|
canUnlock = true;
|
|
unlockTime = 0;
|
|
|
|
vxp = 0;
|
|
vxn = 0;
|
|
vyp = 0;
|
|
vyn = 0;
|
|
}
|
|
|
|
void DriveController::prepareDrive(int dir, int speed, int tilt){
|
|
pDir = dir;
|
|
pSpeed = speed;
|
|
pTilt = tilt;
|
|
}
|
|
|
|
void DriveController::drivePrepared(){
|
|
drive(pDir, pSpeed, pTilt);
|
|
}
|
|
|
|
float DriveController::torad(float f){
|
|
return (f * PI / 180.0);
|
|
}
|
|
|
|
void DriveController::drive(int dir, int speed, int tilt){
|
|
speed = speedFilter->calculate(speed)*GLOBAL_SPD_MULT;
|
|
|
|
//tilt = tilt > 180 ? tilt - 360 : tilt;
|
|
|
|
//TODO: Changing CURRENT_DATA_READ to CURRENT_DATA_WRITE?
|
|
// Disable vector sum because calculations are a bitty crappy imho. Will have to test if it's what makes the robot act strange with lines
|
|
// Re enabling the below lines requires to comment out drive->prepareDrive and uncommenting the lines relative to vector sum inside positionsys_camera and comment out the other lines here
|
|
#ifdef DRIVE_VECTOR_SUM
|
|
vx = ((speed * cosins[dir])) + CURRENT_DATA_READ.addvx;
|
|
vy = ((-speed * sins[dir])) + CURRENT_DATA_READ.addvy;
|
|
#else
|
|
vx = ((speed * cosins[dir]));
|
|
vy = ((-speed * sins[dir]));
|
|
#endif
|
|
|
|
// if((((vy < 0 && vxn == 1) || (vy > 0 && vxp == 1) || (vx < 0 && vyp == 1) || (vx > 0 && vyn == 1)) && canUnlock) || (millis() > this->unlockTime+UNLOCK_THRESH)) {
|
|
// vxn = 0;
|
|
// vxp = 0;
|
|
// vyp = 0;
|
|
// vyn = 0;
|
|
// }
|
|
|
|
// if((vy > 0 && vxn == 1) || (vy < 0 && vxp == 1)) vy = 0;
|
|
// if((vx > 0 && vyp == 1) || (vx < 0 && vyn == 1)) vx = 0;
|
|
|
|
speed1 = ((vx * sins[m1->angle] ) + (vy * cosins[m1->angle] ));
|
|
speed2 = ((vx * sins[m2->angle]) + (vy * cosins[m2->angle]));
|
|
speed3 = ((vx * sins[m3->angle]) + (vy * cosins[m3->angle]));
|
|
speed4 = ((vx * sins[m4->angle]) + (vy * cosins[m4->angle]));
|
|
|
|
// Calculate position error relative to the 0
|
|
delta = CURRENT_DATA_READ.IMUAngle;
|
|
if(delta > 180) delta = delta - 360;
|
|
input = delta;
|
|
|
|
if(tilt > 180) tilt = tilt - 360;
|
|
setpoint = tilt;
|
|
|
|
if(pid->Compute()){
|
|
pidfactor = -output;
|
|
speed1 += pidfactor;
|
|
speed2 += pidfactor;
|
|
speed3 += pidfactor;
|
|
speed4 += pidfactor;
|
|
|
|
// Find the maximum speed and scale all of them for the maximum to be 255
|
|
float maxVel = 0;
|
|
maxVel = max(abs(speed1), maxVel);
|
|
maxVel = max(abs(speed2), maxVel);
|
|
maxVel = max(abs(speed3), maxVel);
|
|
maxVel = max(abs(speed4), maxVel);
|
|
|
|
if(maxVel > 255){
|
|
// Ratio to 255
|
|
float ratio = maxVel/255;
|
|
|
|
// //Scale all the velocities
|
|
speed1 /= ratio;
|
|
speed2 /= ratio;
|
|
speed3 /= ratio;
|
|
speed4 /= ratio;
|
|
|
|
// DEBUG.print(speed1);
|
|
// DEBUG.print(" | ");
|
|
// DEBUG.print(speed2);
|
|
// DEBUG.print(" | ");
|
|
// DEBUG.print(speed3);
|
|
// DEBUG.print(" | ");
|
|
// DEBUG.print(speed4);
|
|
// DEBUG.print(" | ");
|
|
// DEBUG.println(maxVel);
|
|
}
|
|
|
|
speed1 = constrain(speed1, -255, 255);
|
|
speed2 = constrain(speed2, -255, 255);
|
|
speed3 = constrain(speed3, -255, 255);
|
|
speed4 = constrain(speed4, -255, 255);
|
|
|
|
m1->drive((int) speed1);
|
|
m2->drive((int) speed2);
|
|
m3->drive((int) speed3);
|
|
m4->drive((int) speed4);
|
|
|
|
oldSpeed = speed;
|
|
}
|
|
|
|
CURRENT_DATA_WRITE.dir = dir;
|
|
CURRENT_DATA_WRITE.speed = speed;
|
|
CURRENT_DATA_WRITE.tilt = tilt;
|
|
CURRENT_DATA_WRITE.axisBlock[0] = vxp;
|
|
CURRENT_DATA_WRITE.axisBlock[1] = vxn;
|
|
CURRENT_DATA_WRITE.axisBlock[2] = vyp;
|
|
CURRENT_DATA_WRITE.axisBlock[3] = vyn;
|
|
}
|
|
|
|
void DriveController::resetDrive(){
|
|
CURRENT_DATA_WRITE.addvx = 0;
|
|
CURRENT_DATA_WRITE.addvy = 0;
|
|
prepareDrive(0,0,0);
|
|
}
|
|
|
|
void DriveController::stopAll(){
|
|
m1->stop();
|
|
m2->stop();
|
|
m3->stop();
|
|
m4->stop();
|
|
}
|
|
|
|
int DriveController::directionAccountingForTilt(int wanted_direction, int tilt){
|
|
return ((360-tilt+wanted_direction)+360)%360;
|
|
} |