1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-05-17 04:26:00 +02:00
cdf2018-principal/chef/src/movement.c

204 lines
4.9 KiB
C
Raw Normal View History

2018-05-06 08:14:51 +02:00
#include <math.h>
2018-05-06 18:35:26 +02:00
#include <pthread.h>
#include <stdio.h>
2018-05-09 01:00:16 +02:00
#include <stdlib.h>
2018-05-06 18:35:26 +02:00
#include <string.h>
#include <unistd.h>
2018-05-11 15:58:18 +02:00
#include "common.h"
2018-05-06 18:35:26 +02:00
#include "debug.h"
2018-05-11 15:58:18 +02:00
#include "dimensions.h"
2018-05-06 08:14:51 +02:00
#include "motor.h"
#include "movement.h"
2018-05-09 04:10:45 +02:00
#include "securite.h"
2018-05-01 08:45:02 +02:00
2018-05-06 18:35:26 +02:00
pthread_t tMovement;
struct position cons;
2018-05-10 10:08:56 +02:00
// Si une nouvelle instruction est disponible
pthread_mutex_t movInstructionMutex;
pthread_cond_t movInstructionCond;
bool movInstructionBool;
2018-05-06 18:35:26 +02:00
float xDiff;
float yDiff;
2018-05-11 15:58:18 +02:00
float dEcart;
2018-05-06 18:35:26 +02:00
float oEcart;
float oDirEcart;
2018-05-11 15:58:18 +02:00
float dDirEcart;
float oConsEcart;
2018-05-06 18:35:26 +02:00
float dErr;
float oErr;
2018-05-11 15:58:18 +02:00
float dVolt;
float oVolt;
2018-05-06 18:35:26 +02:00
float lErr;
float rErr;
unsigned int nbCalcCons;
2018-04-04 16:17:13 +02:00
void configureMovement()
{
2018-05-01 08:45:02 +02:00
stop();
2018-05-06 18:35:26 +02:00
2018-05-09 09:57:11 +02:00
configureMotor();
2018-05-09 04:10:45 +02:00
configureSecurite();
2018-05-06 18:35:26 +02:00
nbCalcCons = 0;
2018-05-10 10:08:56 +02:00
pthread_mutex_init(&movInstructionMutex, NULL);
pthread_cond_init(&movInstructionCond, NULL);
movInstructionBool = false;
2018-05-06 18:35:26 +02:00
pthread_create(&tMovement, NULL, TaskMovement, NULL);
registerDebugVar("xCons", f, &cons.x);
registerDebugVar("yCons", f, &cons.y);
registerDebugVar("oCons", f, &cons.o);
registerDebugVar("xDiff", f, &xDiff);
registerDebugVar("yDiff", f, &yDiff);
registerDebugVar("dErr", f, &dErr);
registerDebugVar("oErr", f, &oErr);
2018-05-11 15:58:18 +02:00
registerDebugVar("dVolt", f, &dVolt);
registerDebugVar("oVolt", f, &oVolt);
2018-05-06 18:35:26 +02:00
registerDebugVar("dDirEcart", f, &dDirEcart);
registerDebugVar("oDirEcart", f, &oDirEcart);
2018-05-11 15:58:18 +02:00
registerDebugVar("dEcart", f, &dEcart);
registerDebugVar("oEcart", f, &oEcart);
registerDebugVar("oConsEcart", f, &oConsEcart);
2018-05-06 18:35:26 +02:00
registerDebugVar("lErr", f, &lErr);
registerDebugVar("rErr", f, &rErr);
registerDebugVar("nbCalcCons", d, &nbCalcCons);
}
2018-05-11 15:58:18 +02:00
float angleMod(float angle)
2018-05-06 18:35:26 +02:00
{
2018-05-11 15:58:18 +02:00
return fmodf(angle + M_PI, 2 * M_PI) - M_PI;
2018-05-06 18:35:26 +02:00
}
2018-05-11 15:58:18 +02:00
float fcap(float value, float cap)
2018-05-07 20:25:38 +02:00
{
2018-05-11 15:58:18 +02:00
if (value > 0) {
return fmin(value, cap);
} else {
return fmax(value, -cap);
2018-05-07 20:25:38 +02:00
}
}
2018-05-06 18:35:26 +02:00
void* TaskMovement(void* pData)
{
(void)pData;
unsigned int lastPosCalc = 0;
struct position connu;
2018-05-11 15:58:18 +02:00
struct PID dPid;
struct PID oPid;
initPID(&dPid, D_KP, D_KI, D_KD);
initPID(&oPid, O_KP, O_KI, O_KD);
bool orienteDestination = false;
bool procheDestination = false;
bool orienteConsigne = false;
bool reverse;
2018-05-06 18:35:26 +02:00
for (;;) {
2018-05-10 10:08:56 +02:00
2018-05-11 15:58:18 +02:00
lastPosCalc = getPositionNewer(&connu, lastPosCalc);
xDiff = cons.x - connu.x;
yDiff = cons.y - connu.y;
dDirEcart = hypotf(xDiff, yDiff);
oDirEcart = angleMod(atan2(yDiff, xDiff) - connu.o);
oConsEcart = angleMod(cons.o - connu.o);
if ((reverse = fabsf(oDirEcart) > M_PI_2)) {
dDirEcart = -dDirEcart;
oDirEcart = angleMod(oDirEcart + M_PI);
2018-05-07 20:25:38 +02:00
}
2018-05-06 18:35:26 +02:00
2018-05-11 15:58:18 +02:00
if (fabsf(oDirEcart) < O_DIR_ECART_MIN) {
orienteDestination = true;
} else if (fabsf(oDirEcart) > O_DIR_ECART_MAX) {
orienteDestination = false;
}
if (fabsf(dDirEcart) < D_DIR_ECART_MIN) {
procheDestination = true;
} else if (fabsf(dDirEcart) > D_DIR_ECART_MAX) {
procheDestination = false;
}
if (fabsf(oConsEcart) < O_ECART_MIN) {
orienteConsigne = true;
} else if (fabsf(oConsEcart) > O_ECART_MAX) {
orienteConsigne = false;
}
// Carotte
dEcart = (orienteDestination && !procheDestination) ? dDirEcart : 0;
dErr = fcap(dEcart, CAROTTE_DISTANCE);
oEcart = procheDestination ? oConsEcart : oDirEcart;
oErr = fcap(oEcart * DISTANCE_BETWEEN_WHEELS, CAROTTE_ANGLE);
dVolt = updatePID(&dPid, dErr);
oVolt = updatePID(&oPid, oErr);
float lVolt = dVolt - oVolt;
float rVolt = dVolt + oVolt;
pthread_mutex_lock(&movInstructionMutex);
if (movInstructionBool) {
if (procheDestination && orienteConsigne) {
brake();
} else {
setMoteurTension(lVolt, rVolt);
}
}
2018-05-10 10:08:56 +02:00
pthread_mutex_unlock(&movInstructionMutex);
2018-05-11 15:58:18 +02:00
nbCalcCons++;
2018-05-06 18:35:26 +02:00
}
return NULL;
}
2018-04-04 16:17:13 +02:00
2018-05-11 15:58:18 +02:00
void enableAsservissement()
{
pthread_mutex_lock(&movInstructionMutex);
movInstructionBool = true;
pthread_mutex_unlock(&movInstructionMutex);
}
void disableAsservissement()
{
pthread_mutex_lock(&movInstructionMutex);
movInstructionBool = false;
pthread_mutex_unlock(&movInstructionMutex);
}
void setDestination(struct position* pos)
{
pthread_mutex_lock(&movInstructionMutex);
memcpy(&cons, pos, sizeof(struct position));
movInstructionBool = true;
pthread_cond_signal(&movInstructionCond);
pthread_mutex_unlock(&movInstructionMutex);
}
void waitDestination()
{
pthread_mutex_lock(&movInstructionMutex);
while (movInstructionBool) {
pthread_cond_wait(&movInstructionCond, &movInstructionMutex);
}
pthread_mutex_unlock(&movInstructionMutex);
}
2018-05-01 09:03:33 +02:00
void deconfigureMovement()
{
stop();
2018-05-06 18:35:26 +02:00
pthread_cancel(tMovement);
2018-05-09 04:10:45 +02:00
deconfigureSecurite();
2018-05-09 09:57:11 +02:00
deconfigureMotor();
2018-05-06 18:35:26 +02:00
}