2025-11-15 15:30:53 -06:00
|
|
|
#include <Arduino.h>
|
2025-11-16 10:31:46 -06:00
|
|
|
#include "IndSensorMap.hpp"
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
// PIN MAPPING
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
#define indL A0
|
|
|
|
|
#define indR A1
|
|
|
|
|
|
|
|
|
|
#define dirFR 2
|
|
|
|
|
#define pwmFR 3
|
|
|
|
|
#define dirBR 4
|
|
|
|
|
#define pwmBR 5
|
|
|
|
|
#define pwmFL 6
|
|
|
|
|
#define dirFL 7
|
|
|
|
|
#define dirBL 8
|
|
|
|
|
#define pwmBL 9
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
// variables
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
int dist_raw, tprior, telapsed, pwm, pwm2, oor, oor2, dist2_raw;
|
2025-11-15 15:30:53 -06:00
|
|
|
float dist,ecurr, eprior, derror, ecum, ff,dist2,ecurr2, eprior2, derror2, ecum2, ff2;
|
|
|
|
|
|
2025-11-16 10:50:26 -06:00
|
|
|
#define CAP 200
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// CONTROLLER CONSTANTS
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
float ki, kd, K;
|
2025-11-15 15:30:53 -06:00
|
|
|
float MAX_INTEGRAL_TERM = 1e4;
|
|
|
|
|
|
|
|
|
|
const float ref = 21.0; //14.9;
|
|
|
|
|
const float ref2 = 22.0; //14.9;
|
|
|
|
|
|
2025-11-16 10:31:46 -06:00
|
|
|
const float refL = (ref + ref2) / 2;
|
|
|
|
|
const float refR = refL;
|
|
|
|
|
|
2025-11-15 15:30:53 -06:00
|
|
|
const float K_current = 1;
|
|
|
|
|
const float ki_current = 0;
|
|
|
|
|
|
|
|
|
|
//// FOR MC 1
|
|
|
|
|
//const float K_f = 50; // gain for when we want to fall (ref > dist or error > 0)
|
|
|
|
|
//const float ki_f = 0.01;
|
|
|
|
|
//const float kd_f = 8; // 25
|
|
|
|
|
//
|
|
|
|
|
//const float K_a = 20;
|
|
|
|
|
//const float ki_a = ki_f;
|
|
|
|
|
//const float kd_a = 10; //30;
|
|
|
|
|
|
|
|
|
|
// FOR MC 1
|
|
|
|
|
const float K_f = 40; // gain for when we want to fall (ref > dist or error > 0)
|
|
|
|
|
const float ki_f = 0.01;
|
|
|
|
|
const float kd_f = 7; // 25
|
|
|
|
|
|
|
|
|
|
const float K_a = 20;
|
|
|
|
|
const float ki_a = ki_f;
|
|
|
|
|
const float kd_a = 20; //30;
|
|
|
|
|
|
|
|
|
|
// FOR MC 2
|
|
|
|
|
|
|
|
|
|
const float K2_f = K_f;// gain for when we want to fall (ref > dist or error > 0)
|
|
|
|
|
const float ki2_f = ki_f;
|
|
|
|
|
const float kd2_f = kd_f;
|
|
|
|
|
|
|
|
|
|
const float K2_a = K_a;
|
|
|
|
|
const float ki2_a = ki_a;
|
|
|
|
|
const float kd2_a = kd_a;
|
|
|
|
|
|
2025-11-16 10:50:26 -06:00
|
|
|
#define sampling_rate 1000
|
2025-11-15 15:30:53 -06:00
|
|
|
const int dt_micros = 1e6/sampling_rate;
|
|
|
|
|
|
|
|
|
|
#define LEV_ON
|
|
|
|
|
|
|
|
|
|
int ON = 0;
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
// put your setup code here, to run once:
|
|
|
|
|
|
|
|
|
|
Serial.begin(57600);
|
|
|
|
|
|
2025-11-16 10:31:46 -06:00
|
|
|
tprior = micros();
|
2025-11-15 15:30:53 -06:00
|
|
|
ecum = 0;
|
|
|
|
|
ecum2 = 0;
|
|
|
|
|
|
|
|
|
|
// positive pwm is A
|
|
|
|
|
// negative is B
|
|
|
|
|
|
|
|
|
|
// ATTRACT IS B // REPEL IS A
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//when error is negative, I want to attract.
|
2025-11-16 11:43:43 -06:00
|
|
|
send_pwmFL(0);
|
|
|
|
|
send_pwmFR(0);
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
if (Serial.available() > 0) {
|
|
|
|
|
String inputString = Serial.readStringUntil('\n'); // Read the full input
|
|
|
|
|
inputString.trim(); // Remove leading/trailing whitespace, including \n and \r
|
|
|
|
|
|
|
|
|
|
// Conditional pipeline
|
|
|
|
|
if (inputString == "0") {
|
|
|
|
|
ON=0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ON=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
telapsed = micros() - tprior;
|
|
|
|
|
|
|
|
|
|
if (telapsed >= dt_micros){
|
|
|
|
|
// put your main code here, to run repeatedly:
|
2025-11-16 11:43:43 -06:00
|
|
|
dist_raw = analogRead(indL);
|
2025-11-16 11:45:02 -06:00
|
|
|
if (dist_raw > 870) oor = true;
|
2025-11-16 10:31:46 -06:00
|
|
|
dist = ind2mm(ind0Map, dist_raw); // 189->950, 16->26
|
2025-11-15 15:30:53 -06:00
|
|
|
Serial.print(dist);
|
|
|
|
|
Serial.print(", ");
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
dist2_raw = analogRead(indR);
|
2025-11-16 11:45:02 -06:00
|
|
|
if (dist2_raw > 870) oor2 = true;
|
2025-11-16 12:12:02 -06:00
|
|
|
qoueirhpqwerpioqwejpoi;
|
2025-11-16 10:31:46 -06:00
|
|
|
dist2 = ind2mm(ind1Map, dist2_raw);
|
2025-11-15 15:30:53 -06:00
|
|
|
Serial.print(dist2);
|
|
|
|
|
Serial.print(", ");
|
|
|
|
|
|
|
|
|
|
ecurr = ref - dist;
|
|
|
|
|
derror = ecurr - eprior;
|
|
|
|
|
|
|
|
|
|
ecurr2 = ref2 - dist2;
|
|
|
|
|
derror2 = ecurr2 - eprior2;
|
2025-11-16 12:11:03 -06:00
|
|
|
|
|
|
|
|
ecum += ecurr * (telapsed / 1e6);
|
|
|
|
|
ecum = constrain(ecum, -MAX_INTEGRAL_TERM, MAX_INTEGRAL_TERM);
|
|
|
|
|
ecum2 += ecurr2 * (telapsed / 1e6);
|
|
|
|
|
ecum2 = constrain(ecum2, -MAX_INTEGRAL_TERM, MAX_INTEGRAL_TERM);
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ON) {
|
2025-11-16 10:31:46 -06:00
|
|
|
int collective1 = levitate(ecurr, derror, ecum, oor);
|
|
|
|
|
int collective2 = levitate2(ecurr2, derror2, ecum2, oor2);
|
2025-11-16 11:43:43 -06:00
|
|
|
send_pwmFL(pwm);
|
|
|
|
|
send_pwmFR(pwm2);
|
2025-11-16 10:31:46 -06:00
|
|
|
Serial.print(pwm);
|
2025-11-15 15:30:53 -06:00
|
|
|
Serial.print(", ");
|
|
|
|
|
Serial.print(pwm2);
|
|
|
|
|
Serial.print(", ");
|
|
|
|
|
}
|
|
|
|
|
else {
|
2025-11-16 11:43:43 -06:00
|
|
|
send_pwmFL(0);
|
|
|
|
|
send_pwmFR(0);
|
2025-11-15 15:30:53 -06:00
|
|
|
Serial.print(0);
|
|
|
|
|
Serial.print(", ");
|
|
|
|
|
Serial.print(0);
|
|
|
|
|
Serial.print(", ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Serial.print(ON);
|
|
|
|
|
|
|
|
|
|
tprior = micros();
|
|
|
|
|
eprior = ecurr;
|
|
|
|
|
eprior2 = ecurr2;
|
|
|
|
|
// //Serial.print(ecurr); Serial.print(","); Serial.print(oor); Serial.print(","); Serial.print(derror); Serial.print(","); Serial.print(pwm); Serial.print("; "); Serial.print(ecurr2); Serial.print(","); Serial.print(oor2); Serial.print(","); Serial.print(derror2); Serial.print(","); Serial.print(pwm2);
|
|
|
|
|
// Serial.print(ecurr); Serial.print(","); Serial.print(ecurr2); Serial.print(","); Serial.print(ecum); Serial.print(",");Serial.print(ecum2); Serial.print(",");
|
|
|
|
|
//
|
|
|
|
|
Serial.println();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Serial.println(telapsed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int levitate(float e, float de, float ecum, int oor){
|
|
|
|
|
if (oor){
|
|
|
|
|
pwm = 0;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if (e < 0) { // this means that dist > ref so we gotta attract to track now
|
|
|
|
|
kd = kd_a;
|
|
|
|
|
ki = ki_a;
|
|
|
|
|
K = K_a;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
kd = kd_f;
|
|
|
|
|
ki = ki_f;
|
|
|
|
|
K = K_f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pwm = constrain(K*(e + ki*ecum + kd*de), -CAP,CAP);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return (int)pwm;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-16 10:31:46 -06:00
|
|
|
int levitate2(float e, float de, float ecunm, int oor){
|
2025-11-15 15:30:53 -06:00
|
|
|
if (oor){
|
|
|
|
|
pwm2 = 0;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if (e < 0) { // this means that dist > ref so we gotta attract to track now
|
|
|
|
|
kd = kd2_a;
|
|
|
|
|
ki = ki2_a;
|
|
|
|
|
K = K2_a;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
kd = kd2_f;
|
|
|
|
|
ki = ki2_f;
|
|
|
|
|
K = K2_f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pwm2 = constrain(K*(e + ki*ecum + kd*de), -CAP,CAP);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return (int)pwm2;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
void send_pwmFL(int val){
|
2025-11-15 15:30:53 -06:00
|
|
|
if (val > 0) {
|
2025-11-16 11:43:43 -06:00
|
|
|
digitalWrite(dirFL, LOW);
|
2025-11-15 15:30:53 -06:00
|
|
|
}
|
|
|
|
|
else{
|
2025-11-16 11:43:43 -06:00
|
|
|
digitalWrite(dirFL,HIGH);
|
2025-11-15 15:30:53 -06:00
|
|
|
}
|
2025-11-16 11:43:43 -06:00
|
|
|
analogWrite(pwmFL,abs(val));
|
2025-11-15 15:30:53 -06:00
|
|
|
}
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
void send_pwmFR(int val){
|
2025-11-15 15:30:53 -06:00
|
|
|
if (val > 0) {
|
2025-11-16 11:43:43 -06:00
|
|
|
digitalWrite(dirFR, LOW);
|
2025-11-15 15:30:53 -06:00
|
|
|
}
|
|
|
|
|
else{
|
2025-11-16 11:43:43 -06:00
|
|
|
digitalWrite(dirFR,HIGH);
|
2025-11-15 15:30:53 -06:00
|
|
|
}
|
|
|
|
|
|
2025-11-16 11:43:43 -06:00
|
|
|
analogWrite(pwmFR,abs(val));
|
2025-11-15 15:30:53 -06:00
|
|
|
|
|
|
|
|
}
|