johnwasser:
Here is a similar block of code that I wrote for my own purposes. Perhaps you will see how this is similar to your friend's code and the comments will help:
#include <PID_v1.h>
#include <TinyGPS.h>
#define USING_PWM
enum MotorIndex {MOTOR_FL_CW, MOTOR_FR_CCW, MOTOR_BL_CCW, MOTOR_BR_CW};
void MotorSpeed(MotorIndex motor, int throttle);
#ifdef USING_PWM
const int THROTTLE_MIN = 0;
const int THROTTLE_MAX = 255;
const int MotorPins[4] = {3, 5, 6, 9};
#else // USING_ESC
const int THROTTLE_MIN = 1000;
const int THROTTLE_MAX = 2000;
Servo MotorFL, MotorFR, MotorBL, MotorBR;
Servo *ESCs[MotorIndex] = {MotorFL, MotorFR, MotorBL, MotorBR};
const int ESCPins[4] = {4, 5, 6, 7};
#endif
// Set Pitch/Roll/Yaw limits to 10% of throttle range.
const double LIMIT_MIN = -0.1 * (THROTTLE_MAX - THROTTLE_MIN);
const double LIMIT_MAX = 0.1 * (THROTTLE_MAX - THROTTLE_MIN);
TinyGPS GPS;
const double Kp = 1.0, Ki = 0.0, Kd = 0.0;
double AltitudeSetpoint = 0; // Meters above start point
double AltitudeInput, ThrottleOutput;
PID AltitudePID(&AltitudeSetpoint, &AltitudeInput, &ThrottleOutput, Kp, Ki, Kd, DIRECT);
double PitchSetpoint = 0, PitchInput, PitchOutput;
PID PitchPID(&PitchSetpoint, &PitchInput, &PitchOutput, Kp, Ki, Kd, DIRECT);
double RollSetpoint = 0, RollInput, RollOutput;
PID RollPID(&RollSetpoint, &RollInput, &RollOutput, Kp, Ki, Kd, DIRECT);
double YawSetpoint = 0, YawInput, YawOutput;
PID YawPID(&YawSetpoint, &YawInput, &YawOutput, Kp, Ki, Kd, DIRECT);
struct Waypoint {
double altitude;
unsigned long latitude;
unsigned long longitude;
} StartPoint, Destination, CurrentLocation;
void setup() {
#ifndef USING_PWM
for (int i = 0; i < 4; i++)
ESCs[i].attach(ESCPins[i]);
#endif
AltitudePID.SetOutputLimits(THROTTLE_MIN, THROTTLE_MAX);
AltitudePID.SetMode(AUTOMATIC);
PitchPID.SetOutputLimits(LIMIT_MIN, LIMIT_MAX);
PitchPID.SetMode(AUTOMATIC);
RollPID.SetOutputLimits(LIMIT_MIN, LIMIT_MAX);
RollPID.SetMode(AUTOMATIC);
YawPID.SetOutputLimits(LIMIT_MIN, LIMIT_MAX);
YawPID.SetMode(AUTOMATIC);
// StartPoint.altitude = Barometer.altitude();
// StartPoint.latitude = GPS.GetLatitude();
// StartPoint.longitude = GPS.GetLongitude();
}
void loop() {
// AltitudeInput = Barometer.altitude() - StartPoint.altitude;
AltitudePID.Compute();
// PitchInput = Accelerometer.pitch();
PitchPID.Compute();
// RollInput = Accelerometer.roll();
RollPID.Compute();
// YawInput = Magnetometer.heading();
YawPID.Compute();
MotorSpeed(MOTOR_FL_CW , ThrottleOutput + PitchOutput - RollOutput + YawOutput);
MotorSpeed(MOTOR_FR_CCW, ThrottleOutput + PitchOutput + RollOutput - YawOutput);
MotorSpeed(MOTOR_BL_CCW , ThrottleOutput - PitchOutput - RollOutput - YawOutput);
MotorSpeed(MOTOR_BR_CW, ThrottleOutput - PitchOutput + RollOutput + YawOutput);
}
void MotorSpeed(MotorIndex motor, int throttle) {
throttle = constrain(throttle, THROTTLE_MIN, THROTTLE_MAX);
#ifdef USING_PWM
// Using PWM pins
analogWrite(MotorPins[motor], throttle);
#else
// Using ESC control
ESCs[motor]->writeMicroseconds(throttle);
#endif
}
The USING_PWM option is for brushed DC motors with a simple transistor driver. These are common on very small and inexpensive toy quadcopters. For BRUSHLESS motors you would use and Electronic Speed Control (ESC) for each and those are driven like a hobby servo.
Thanks alot jhonwasser. You are very helping to me
I would give your code a look and try to write something more useful from it. once again a bundle of thanks.