Quadcopter software. Flying - Contact me for more details or a copy of the PC ground station code

Dependencies:   ConfigFile PID PPM MODSERIAL mbed-rtos mbed MaxbotixDriver TinyGPS filter

Committer:
joe4465
Date:
Fri May 16 14:18:05 2014 +0000
Revision:
1:045edcf091f3
Parent:
0:0010a5abcc31
Child:
3:82665e39f1ea
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joe4465 0:0010a5abcc31 1 //Includes
joe4465 0:0010a5abcc31 2 #include "mbed.h"
joe4465 0:0010a5abcc31 3 #include "rtos.h"
joe4465 0:0010a5abcc31 4 #include "FreeIMU.h"
joe4465 0:0010a5abcc31 5 #include "PID.h"
joe4465 0:0010a5abcc31 6 #include "ConfigFile.h"
joe4465 0:0010a5abcc31 7 #include "hardware.h"
joe4465 0:0010a5abcc31 8 #include "statusLights.h"
joe4465 0:0010a5abcc31 9 #include "serialPortMonitor.h"
joe4465 0:0010a5abcc31 10 #include "flightController.h"
joe4465 1:045edcf091f3 11 #include "MAF.h"
joe4465 0:0010a5abcc31 12
joe4465 0:0010a5abcc31 13 //Declarations
joe4465 0:0010a5abcc31 14 void LoadSettingsFromConfig();
joe4465 0:0010a5abcc31 15 void InitialisePID();
joe4465 0:0010a5abcc31 16 void InitialisePWM();
joe4465 0:0010a5abcc31 17 void Setup();
joe4465 1:045edcf091f3 18 void SignalRise();
joe4465 1:045edcf091f3 19
joe4465 1:045edcf091f3 20 //VERY MESSY NNED TO TIDY
joe4465 1:045edcf091f3 21
joe4465 1:045edcf091f3 22 //PPM STUFF
joe4465 1:045edcf091f3 23 Timer _PPMTimer;
joe4465 1:045edcf091f3 24 const int _numberOfPPMChannels=8; // This is the number of channels in your PPM signal
joe4465 1:045edcf091f3 25 unsigned char _currentPPMChannel=0; //This will point to the current channel in PPM frame.
joe4465 1:045edcf091f3 26 int _PPMChannelValues[_numberOfPPMChannels]={0,0,0,0,0,0}; //This where the channels value is stored until frame is complete.
joe4465 1:045edcf091f3 27 unsigned int _PPMChannelTimes[_numberOfPPMChannels]={0,0,0,0,0,0}; //This where the channel pulse time value is stored until frame is complete.
joe4465 1:045edcf091f3 28 float C0s[_numberOfPPMChannels]; // Zeroth order coefficient for converting times to channels
joe4465 1:045edcf091f3 29 float C1s[_numberOfPPMChannels]; // First order coefficient for converting times to channels
joe4465 1:045edcf091f3 30 int _frameCount=0;
joe4465 1:045edcf091f3 31 int i;
joe4465 1:045edcf091f3 32 int _timeElapsedBetweenPPMInterrupts =0; //Keeps track of time between PPM interrupts
joe4465 1:045edcf091f3 33 int _miniumumSyncTime = 6000; // Minimum time of the sync pulse (us)
joe4465 1:045edcf091f3 34 int _shortPulseTime = 800; // If the pulse time for a channel is this short, something is wrong (us)
joe4465 1:045edcf091f3 35 int _pulseMin = 1000; // The minimum pulse time for a channel should be this long (us)
joe4465 1:045edcf091f3 36 int _pulseMax = 2000; // The maximum pulse time for a channel should be this long (us)
joe4465 1:045edcf091f3 37 int _channelOutputMin = RCMIN; // Desired minimum value for outputs
joe4465 1:045edcf091f3 38 int _channelOutputMax = RCMAX; // Desired maximum value for outputs
joe4465 1:045edcf091f3 39 const int JCCount=4; //Number of joystick channels
joe4465 1:045edcf091f3 40 unsigned char JoystickChannels[JCCount]={0,1,2,3}; // List of joystick channels
joe4465 1:045edcf091f3 41 char dum1,dum2;
joe4465 1:045edcf091f3 42
joe4465 1:045edcf091f3 43 //RC command filters
joe4465 1:045edcf091f3 44 MAF _thrustFilter;
joe4465 1:045edcf091f3 45 MAF _yawFilter;
joe4465 1:045edcf091f3 46 MAF _pitchRateFilter;
joe4465 1:045edcf091f3 47 MAF _rollRateFilter;
joe4465 1:045edcf091f3 48 MAF _pitchStabFilter;
joe4465 1:045edcf091f3 49 MAF _rollStabFilter;
joe4465 1:045edcf091f3 50
joe4465 1:045edcf091f3 51 //Here were all the work decoding the PPM signal takes place
joe4465 1:045edcf091f3 52 void SignalRise()
joe4465 1:045edcf091f3 53 {
joe4465 1:045edcf091f3 54 _timeElapsedBetweenPPMInterrupts = _PPMTimer.read_us(); // Since we are measuring from signal rise to signal rise, note that _timeElapsedBetweenPPMInterrupts includes the fixed separator time as well
joe4465 1:045edcf091f3 55 if (_timeElapsedBetweenPPMInterrupts < _shortPulseTime)
joe4465 1:045edcf091f3 56 {
joe4465 1:045edcf091f3 57 return; //Channel timing too short; ignore, it's a glitch. Don't move to the next channel
joe4465 1:045edcf091f3 58 }
joe4465 1:045edcf091f3 59 __disable_irq();
joe4465 1:045edcf091f3 60 //_PPMSignal.rise(NULL);
joe4465 1:045edcf091f3 61 _PPMTimer.reset();
joe4465 1:045edcf091f3 62 if ((_timeElapsedBetweenPPMInterrupts > _miniumumSyncTime ) && (_currentPPMChannel != 0))
joe4465 1:045edcf091f3 63 {
joe4465 1:045edcf091f3 64 //somehow before reaching the end of PPM frame you read "New" frame signal???
joe4465 1:045edcf091f3 65 //Ok, it happens. Just ignore this frame and start a new one
joe4465 1:045edcf091f3 66 _currentPPMChannel=0;
joe4465 1:045edcf091f3 67 }
joe4465 1:045edcf091f3 68 if ((_timeElapsedBetweenPPMInterrupts > _miniumumSyncTime ) && (_currentPPMChannel == 0))
joe4465 1:045edcf091f3 69 {
joe4465 1:045edcf091f3 70 // This is good. You've received "New" frame signal as expected
joe4465 1:045edcf091f3 71 __enable_irq();
joe4465 1:045edcf091f3 72 //_PPMSignal.rise(&SignalRise);
joe4465 1:045edcf091f3 73 return;
joe4465 1:045edcf091f3 74 }
joe4465 1:045edcf091f3 75
joe4465 1:045edcf091f3 76 // Process current channel. This is a correct channel in a correct frame so far
joe4465 1:045edcf091f3 77 _PPMChannelValues[_currentPPMChannel]= C0s[_currentPPMChannel] + C1s[_currentPPMChannel]*_timeElapsedBetweenPPMInterrupts; // Normalize reading (Min: 900us Max: 1900 us). This is my readings, yours can be different
joe4465 1:045edcf091f3 78 _PPMChannelTimes[_currentPPMChannel] = _timeElapsedBetweenPPMInterrupts;
joe4465 1:045edcf091f3 79 _currentPPMChannel++;
joe4465 1:045edcf091f3 80
joe4465 1:045edcf091f3 81 if (_currentPPMChannel==_numberOfPPMChannels )
joe4465 1:045edcf091f3 82 {
joe4465 1:045edcf091f3 83 // great!, you've a complete correct frame. Set CanUpdate and start a new frame
joe4465 1:045edcf091f3 84 _frameCount++;
joe4465 1:045edcf091f3 85 _currentPPMChannel=0;
joe4465 1:045edcf091f3 86
joe4465 1:045edcf091f3 87 //Aux Channels
joe4465 1:045edcf091f3 88 float channel5 = map(_PPMChannelValues[4], RCMIN, RCMAX, 0, 1);
joe4465 1:045edcf091f3 89 float channel6 = map(_PPMChannelValues[5], RCMIN, RCMAX, 0, 1);
joe4465 1:045edcf091f3 90 float channel7 = map(_PPMChannelValues[6], RCMIN, RCMAX, 0, 1);
joe4465 1:045edcf091f3 91 float channel8 = map(_PPMChannelValues[7], RCMIN, RCMAX, 0, 1);
joe4465 1:045edcf091f3 92
joe4465 1:045edcf091f3 93 //Arm
joe4465 1:045edcf091f3 94 if(channel5 > 0.4)
joe4465 1:045edcf091f3 95 {
joe4465 1:045edcf091f3 96 //Zero gyro
joe4465 1:045edcf091f3 97 _freeIMU.zeroGyro();
joe4465 1:045edcf091f3 98 _armed = true;
joe4465 1:045edcf091f3 99 }
joe4465 1:045edcf091f3 100 else _armed = false;
joe4465 1:045edcf091f3 101
joe4465 1:045edcf091f3 102 //Mode
joe4465 1:045edcf091f3 103 if(channel6 > 0.4)
joe4465 1:045edcf091f3 104 {
joe4465 1:045edcf091f3 105 _rate = true;
joe4465 1:045edcf091f3 106 _stab = false;
joe4465 1:045edcf091f3 107 }
joe4465 1:045edcf091f3 108 else
joe4465 1:045edcf091f3 109 {
joe4465 1:045edcf091f3 110 _rate = false;
joe4465 1:045edcf091f3 111 _stab = true;
joe4465 1:045edcf091f3 112 }
joe4465 1:045edcf091f3 113
joe4465 1:045edcf091f3 114 //Filtering
joe4465 1:045edcf091f3 115 float thrust = _thrustFilter.update(map(_PPMChannelValues[2], RCMIN, RCMAX, RC_THRUST_MIN, RC_THRUST_MAX));
joe4465 1:045edcf091f3 116 float yaw = _yawFilter.update(map(_PPMChannelValues[3], RCMIN, RCMAX, RC_YAW_RATE_MIN, RC_YAW_RATE_MAX));
joe4465 1:045edcf091f3 117 float rollRate = _rollRateFilter.update(map(_PPMChannelValues[0], RCMIN, RCMAX, RC_ROLL_RATE_MIN, RC_ROLL_RATE_MAX));
joe4465 1:045edcf091f3 118 float pitchRate = _pitchRateFilter.update(map(_PPMChannelValues[1], RCMIN, RCMAX, RC_PITCH_RATE_MIN, RC_PITCH_RATE_MAX));
joe4465 1:045edcf091f3 119 float rollStab = _rollStabFilter.update(map(_PPMChannelValues[0], RCMIN, RCMAX, RC_ROLL_ANGLE_MIN, RC_ROLL_ANGLE_MAX));
joe4465 1:045edcf091f3 120 float pitchStab = _pitchStabFilter.update(map(_PPMChannelValues[1], RCMIN, RCMAX, RC_PITCH_ANGLE_MIN, RC_PITCH_ANGLE_MAX));
joe4465 1:045edcf091f3 121
joe4465 1:045edcf091f3 122 //Set rc commands
joe4465 1:045edcf091f3 123 //Rate mode
joe4465 1:045edcf091f3 124 if(_rate == true && _stab == false)
joe4465 1:045edcf091f3 125 {
joe4465 1:045edcf091f3 126 _rcMappedCommands[0] = yaw;
joe4465 1:045edcf091f3 127 _rcMappedCommands[1] = pitchRate;
joe4465 1:045edcf091f3 128 _rcMappedCommands[2] = rollRate;
joe4465 1:045edcf091f3 129 _rcMappedCommands[3] = thrust;
joe4465 1:045edcf091f3 130 }
joe4465 1:045edcf091f3 131 else // Stab mode
joe4465 1:045edcf091f3 132 {
joe4465 1:045edcf091f3 133 _rcMappedCommands[0] = yaw;
joe4465 1:045edcf091f3 134 _rcMappedCommands[1] = pitchStab;
joe4465 1:045edcf091f3 135 _rcMappedCommands[2] = rollStab;
joe4465 1:045edcf091f3 136 _rcMappedCommands[3] = thrust;
joe4465 1:045edcf091f3 137 }
joe4465 1:045edcf091f3 138 }
joe4465 1:045edcf091f3 139 __enable_irq();
joe4465 1:045edcf091f3 140 }
joe4465 0:0010a5abcc31 141
joe4465 0:0010a5abcc31 142 //Loads settings from the config file
joe4465 0:0010a5abcc31 143 void LoadSettingsFromConfig()
joe4465 0:0010a5abcc31 144 {
joe4465 0:0010a5abcc31 145 _wiredSerial.printf("Loading settings from config file\n\r");
joe4465 0:0010a5abcc31 146
joe4465 0:0010a5abcc31 147 //_wiredSerial.printf("Loading settings from config file\n\r");
joe4465 0:0010a5abcc31 148 char value[BUFSIZ];
joe4465 0:0010a5abcc31 149
joe4465 0:0010a5abcc31 150 //Read a configuration file from a mbed.
joe4465 0:0010a5abcc31 151 if (!_configFile.read("/local/config.cfg"))
joe4465 0:0010a5abcc31 152 {
joe4465 0:0010a5abcc31 153 _wiredSerial.printf("Config file does not exist\n\r");
joe4465 0:0010a5abcc31 154 _initialised = false;
joe4465 0:0010a5abcc31 155 }
joe4465 0:0010a5abcc31 156
joe4465 0:0010a5abcc31 157 //Get values
joe4465 0:0010a5abcc31 158 if (_configFile.getValue("_yawRatePIDControllerP", &value[0], sizeof(value))) _yawRatePIDControllerP = atof(value);
joe4465 0:0010a5abcc31 159 else
joe4465 0:0010a5abcc31 160 {
joe4465 0:0010a5abcc31 161 _initialised = false;
joe4465 0:0010a5abcc31 162 _wiredSerial.printf("Failed to get value for _yawRatePIDControllerP\n\r");
joe4465 0:0010a5abcc31 163 }
joe4465 0:0010a5abcc31 164 if (_configFile.getValue("_yawRatePIDControllerI", &value[0], sizeof(value))) _yawRatePIDControllerI = atof(value);
joe4465 0:0010a5abcc31 165 else
joe4465 0:0010a5abcc31 166 {
joe4465 0:0010a5abcc31 167 _initialised = false;
joe4465 0:0010a5abcc31 168 _wiredSerial.printf("Failed to get value for _yawRatePIDControllerI\n\r");
joe4465 0:0010a5abcc31 169 }
joe4465 0:0010a5abcc31 170 if (_configFile.getValue("_yawRatePIDControllerD", &value[0], sizeof(value))) _yawRatePIDControllerD = atof(value);
joe4465 0:0010a5abcc31 171 else
joe4465 0:0010a5abcc31 172 {
joe4465 0:0010a5abcc31 173 _initialised = false;
joe4465 0:0010a5abcc31 174 _wiredSerial.printf("Failed to get value for _yawRatePIDControllerD\n\r");
joe4465 0:0010a5abcc31 175 }
joe4465 0:0010a5abcc31 176 if (_configFile.getValue("_pitchRatePIDControllerP", &value[0], sizeof(value))) _pitchRatePIDControllerP = atof(value);
joe4465 0:0010a5abcc31 177 else
joe4465 0:0010a5abcc31 178 {
joe4465 0:0010a5abcc31 179 _initialised = false;
joe4465 0:0010a5abcc31 180 _wiredSerial.printf("Failed to get value for _pitchRatePIDControllerP\n\r");
joe4465 0:0010a5abcc31 181 }
joe4465 0:0010a5abcc31 182 if (_configFile.getValue("_pitchRatePIDControllerI", &value[0], sizeof(value))) _pitchRatePIDControllerI = atof(value);
joe4465 0:0010a5abcc31 183 else
joe4465 0:0010a5abcc31 184 {
joe4465 0:0010a5abcc31 185 _initialised = false;
joe4465 0:0010a5abcc31 186 _wiredSerial.printf("Failed to get value for _pitchRatePIDControllerI\n\r");
joe4465 0:0010a5abcc31 187 }
joe4465 0:0010a5abcc31 188 if (_configFile.getValue("_pitchRatePIDControllerD", &value[0], sizeof(value))) _pitchRatePIDControllerD = atof(value);
joe4465 0:0010a5abcc31 189 else
joe4465 0:0010a5abcc31 190 {
joe4465 0:0010a5abcc31 191 _initialised = false;
joe4465 0:0010a5abcc31 192 _wiredSerial.printf("Failed to get value for _pitchRatePIDControllerD\n\r");
joe4465 0:0010a5abcc31 193 }
joe4465 0:0010a5abcc31 194 if (_configFile.getValue("_rollRatePIDControllerP", &value[0], sizeof(value))) _rollRatePIDControllerP = atof(value);
joe4465 0:0010a5abcc31 195 else
joe4465 0:0010a5abcc31 196 {
joe4465 0:0010a5abcc31 197 _initialised = false;
joe4465 0:0010a5abcc31 198 _wiredSerial.printf("Failed to get value for _rollRatePIDControllerP\n\r");
joe4465 0:0010a5abcc31 199 }
joe4465 0:0010a5abcc31 200 if (_configFile.getValue("_rollRatePIDControllerI", &value[0], sizeof(value))) _rollRatePIDControllerI = atof(value);
joe4465 0:0010a5abcc31 201 else
joe4465 0:0010a5abcc31 202 {
joe4465 0:0010a5abcc31 203 _initialised = false;
joe4465 0:0010a5abcc31 204 _wiredSerial.printf("Failed to get value for _rollRatePIDControllerI\n\r");
joe4465 0:0010a5abcc31 205 }
joe4465 0:0010a5abcc31 206 if (_configFile.getValue("_rollRatePIDControllerD", &value[0], sizeof(value))) _rollRatePIDControllerD = atof(value);
joe4465 0:0010a5abcc31 207 else
joe4465 0:0010a5abcc31 208 {
joe4465 0:0010a5abcc31 209 _initialised = false;
joe4465 0:0010a5abcc31 210 _wiredSerial.printf("Failed to get value for _rollRatePIDControllerD\n\r");
joe4465 0:0010a5abcc31 211 }
joe4465 0:0010a5abcc31 212
joe4465 0:0010a5abcc31 213 if (_configFile.getValue("_yawStabPIDControllerP", &value[0], sizeof(value))) _yawStabPIDControllerP = atof(value);
joe4465 0:0010a5abcc31 214 else
joe4465 0:0010a5abcc31 215 {
joe4465 0:0010a5abcc31 216 _initialised = false;
joe4465 0:0010a5abcc31 217 _wiredSerial.printf("Failed to get value for _yawStabPIDControllerP\n\r");
joe4465 0:0010a5abcc31 218 }
joe4465 0:0010a5abcc31 219 if (_configFile.getValue("_yawStabPIDControllerI", &value[0], sizeof(value))) _yawStabPIDControllerI = atof(value);
joe4465 0:0010a5abcc31 220 else
joe4465 0:0010a5abcc31 221 {
joe4465 0:0010a5abcc31 222 _initialised = false;
joe4465 0:0010a5abcc31 223 _wiredSerial.printf("Failed to get value for _yawStabPIDControllerI\n\r");
joe4465 0:0010a5abcc31 224 }
joe4465 0:0010a5abcc31 225 if (_configFile.getValue("_yawStabPIDControllerD", &value[0], sizeof(value))) _yawStabPIDControllerD = atof(value);
joe4465 0:0010a5abcc31 226 else
joe4465 0:0010a5abcc31 227 {
joe4465 0:0010a5abcc31 228 _initialised = false;
joe4465 0:0010a5abcc31 229 _wiredSerial.printf("Failed to get value for _yawStabPIDControllerD\n\r");
joe4465 0:0010a5abcc31 230 }
joe4465 0:0010a5abcc31 231 if (_configFile.getValue("_pitchStabPIDControllerP", &value[0], sizeof(value))) _pitchStabPIDControllerP = atof(value);
joe4465 0:0010a5abcc31 232 else
joe4465 0:0010a5abcc31 233 {
joe4465 0:0010a5abcc31 234 _initialised = false;
joe4465 0:0010a5abcc31 235 _wiredSerial.printf("Failed to get value for _pitchStabPIDControllerP\n\r");
joe4465 0:0010a5abcc31 236 }
joe4465 0:0010a5abcc31 237 if (_configFile.getValue("_pitchStabPIDControllerI", &value[0], sizeof(value))) _pitchStabPIDControllerI = atof(value);
joe4465 0:0010a5abcc31 238 else
joe4465 0:0010a5abcc31 239 {
joe4465 0:0010a5abcc31 240 _initialised = false;
joe4465 0:0010a5abcc31 241 _wiredSerial.printf("Failed to get value for _pitchStabPIDControllerI\n\r");
joe4465 0:0010a5abcc31 242 }
joe4465 0:0010a5abcc31 243 if (_configFile.getValue("_pitchStabPIDControllerD", &value[0], sizeof(value))) _pitchStabPIDControllerD = atof(value);
joe4465 0:0010a5abcc31 244 else
joe4465 0:0010a5abcc31 245 {
joe4465 0:0010a5abcc31 246 _initialised = false;
joe4465 0:0010a5abcc31 247 _wiredSerial.printf("Failed to get value for _pitchStabPIDControllerD\n\r");
joe4465 0:0010a5abcc31 248 }
joe4465 0:0010a5abcc31 249 if (_configFile.getValue("_rollStabPIDControllerP", &value[0], sizeof(value))) _rollStabPIDControllerP = atof(value);
joe4465 0:0010a5abcc31 250 else
joe4465 0:0010a5abcc31 251 {
joe4465 0:0010a5abcc31 252 _initialised = false;
joe4465 0:0010a5abcc31 253 _wiredSerial.printf("Failed to get value for _rollStabPIDControllerP\n\r");
joe4465 0:0010a5abcc31 254 }
joe4465 0:0010a5abcc31 255 if (_configFile.getValue("_rollStabPIDControllerI", &value[0], sizeof(value))) _rollStabPIDControllerI = atof(value);
joe4465 0:0010a5abcc31 256 else
joe4465 0:0010a5abcc31 257 {
joe4465 0:0010a5abcc31 258 _initialised = false;
joe4465 0:0010a5abcc31 259 _wiredSerial.printf("Failed to get value for _rollStabPIDControllerI\n\r");
joe4465 0:0010a5abcc31 260 }
joe4465 0:0010a5abcc31 261 if (_configFile.getValue("_rollStabPIDControllerD", &value[0], sizeof(value))) _rollStabPIDControllerD = atof(value);
joe4465 0:0010a5abcc31 262 else
joe4465 0:0010a5abcc31 263 {
joe4465 0:0010a5abcc31 264 _initialised = false;
joe4465 0:0010a5abcc31 265 _wiredSerial.printf("Failed to get value for _rollStabPIDControllerD\n\r");
joe4465 0:0010a5abcc31 266 }
joe4465 0:0010a5abcc31 267 if (_configFile.getValue("_zeroPitch", &value[0], sizeof(value))) _zeroValues[1] = atof(value);
joe4465 0:0010a5abcc31 268 else
joe4465 0:0010a5abcc31 269 {
joe4465 0:0010a5abcc31 270 _initialised = false;
joe4465 0:0010a5abcc31 271 _wiredSerial.printf("Failed to get value for zero pitch\n\r");
joe4465 0:0010a5abcc31 272 }
joe4465 0:0010a5abcc31 273 if (_configFile.getValue("_zeroRoll", &value[0], sizeof(value))) _zeroValues[2] = atof(value);
joe4465 0:0010a5abcc31 274 else
joe4465 0:0010a5abcc31 275 {
joe4465 0:0010a5abcc31 276 _initialised = false;
joe4465 0:0010a5abcc31 277 _wiredSerial.printf("Failed to get value for zero roll\n\r");
joe4465 0:0010a5abcc31 278 }
joe4465 0:0010a5abcc31 279
joe4465 0:0010a5abcc31 280 if(_initialised == true)
joe4465 0:0010a5abcc31 281 {
joe4465 0:0010a5abcc31 282 _wiredSerial.printf("Finished loading settings from config file\n\r");
joe4465 0:0010a5abcc31 283 }
joe4465 0:0010a5abcc31 284 else
joe4465 0:0010a5abcc31 285 {
joe4465 0:0010a5abcc31 286 _wiredSerial.printf("Failed to load settings from config file\n\r");
joe4465 0:0010a5abcc31 287 }
joe4465 0:0010a5abcc31 288 }
joe4465 0:0010a5abcc31 289
joe4465 0:0010a5abcc31 290 //PID initialisation
joe4465 0:0010a5abcc31 291 void InitialisePID()
joe4465 0:0010a5abcc31 292 {
joe4465 0:0010a5abcc31 293 float updateTime = 1.0 / UPDATE_FREQUENCY;
joe4465 0:0010a5abcc31 294
joe4465 0:0010a5abcc31 295 _yawRatePIDController = new PID(_yawRatePIDControllerP, _yawRatePIDControllerI, _yawRatePIDControllerD, updateTime);
joe4465 0:0010a5abcc31 296 _yawRatePIDController->setInputLimits(IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX);
joe4465 0:0010a5abcc31 297 _yawRatePIDController->setOutputLimits(RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
joe4465 0:0010a5abcc31 298 _yawRatePIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 299 _yawRatePIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 300 _yawRatePIDController->setBias(0);
joe4465 0:0010a5abcc31 301
joe4465 0:0010a5abcc31 302 _pitchRatePIDController = new PID(_pitchRatePIDControllerP, _pitchRatePIDControllerI, _pitchRatePIDControllerD, updateTime);
joe4465 0:0010a5abcc31 303 _pitchRatePIDController->setInputLimits(IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX);
joe4465 0:0010a5abcc31 304 _pitchRatePIDController->setOutputLimits(RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
joe4465 0:0010a5abcc31 305 _pitchRatePIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 306 _pitchRatePIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 307 _pitchRatePIDController->setBias(0);
joe4465 0:0010a5abcc31 308
joe4465 0:0010a5abcc31 309 _rollRatePIDController = new PID(_rollRatePIDControllerP, _rollRatePIDControllerI, _rollRatePIDControllerD, updateTime);
joe4465 0:0010a5abcc31 310 _rollRatePIDController->setInputLimits(IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX);
joe4465 0:0010a5abcc31 311 _rollRatePIDController->setOutputLimits(RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
joe4465 0:0010a5abcc31 312 _rollRatePIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 313 _rollRatePIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 314 _rollRatePIDController->setBias(0);
joe4465 0:0010a5abcc31 315
joe4465 0:0010a5abcc31 316 _yawStabPIDController = new PID(_yawStabPIDControllerP, _yawStabPIDControllerI, _yawStabPIDControllerD, updateTime);
joe4465 0:0010a5abcc31 317 _yawStabPIDController->setInputLimits(IMU_YAW_ANGLE_MIN, IMU_YAW_ANGLE_MAX);
joe4465 0:0010a5abcc31 318 _yawStabPIDController->setOutputLimits(IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX);
joe4465 0:0010a5abcc31 319 _yawStabPIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 320 _yawStabPIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 321 _yawStabPIDController->setBias(0);
joe4465 0:0010a5abcc31 322
joe4465 0:0010a5abcc31 323 _pitchStabPIDController = new PID(_pitchStabPIDControllerP, _pitchStabPIDControllerI, _pitchStabPIDControllerD, updateTime);
joe4465 0:0010a5abcc31 324 _pitchStabPIDController->setInputLimits(IMU_PITCH_ANGLE_MIN, IMU_PITCH_ANGLE_MAX);
joe4465 0:0010a5abcc31 325 _pitchStabPIDController->setOutputLimits(IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX);
joe4465 0:0010a5abcc31 326 _pitchStabPIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 327 _pitchStabPIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 328 _pitchStabPIDController->setBias(0);
joe4465 0:0010a5abcc31 329
joe4465 0:0010a5abcc31 330 _rollStabPIDController = new PID(_rollStabPIDControllerP, _rollStabPIDControllerI, _rollStabPIDControllerD, updateTime);
joe4465 0:0010a5abcc31 331 _rollStabPIDController->setInputLimits(IMU_ROLL_ANGLE_MIN, IMU_ROLL_ANGLE_MAX);
joe4465 0:0010a5abcc31 332 _rollStabPIDController->setOutputLimits(IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX);
joe4465 0:0010a5abcc31 333 _rollStabPIDController->setMode(AUTO_MODE);
joe4465 0:0010a5abcc31 334 _rollStabPIDController->setSetPoint(0.0);
joe4465 0:0010a5abcc31 335 _rollStabPIDController->setBias(0);
joe4465 0:0010a5abcc31 336 }
joe4465 0:0010a5abcc31 337
joe4465 0:0010a5abcc31 338 //PWM Initialisation
joe4465 0:0010a5abcc31 339 void InitialisePWM()
joe4465 0:0010a5abcc31 340 {
joe4465 1:045edcf091f3 341 //500Hz
joe4465 0:0010a5abcc31 342 float period = 1.0 / MOTOR_PWM_FREQUENCY;
joe4465 0:0010a5abcc31 343 _motor1.period(period);
joe4465 0:0010a5abcc31 344 _motor2.period(period);
joe4465 0:0010a5abcc31 345 _motor3.period(period);
joe4465 0:0010a5abcc31 346 _motor4.period(period);
joe4465 0:0010a5abcc31 347
joe4465 0:0010a5abcc31 348 //Disable
joe4465 0:0010a5abcc31 349 _motor1 = MOTORS_OFF;
joe4465 0:0010a5abcc31 350 _motor2 = MOTORS_OFF;
joe4465 0:0010a5abcc31 351 _motor2 = MOTORS_OFF;
joe4465 0:0010a5abcc31 352 _motor2 = MOTORS_OFF;
joe4465 0:0010a5abcc31 353 }
joe4465 0:0010a5abcc31 354
joe4465 0:0010a5abcc31 355 //Setup
joe4465 0:0010a5abcc31 356 void Setup()
joe4465 1:045edcf091f3 357 {
joe4465 0:0010a5abcc31 358 //Setup wired serial coms
joe4465 0:0010a5abcc31 359 _wiredSerial.baud(115200);
joe4465 0:0010a5abcc31 360
joe4465 0:0010a5abcc31 361 //Setup wireless serial coms
joe4465 0:0010a5abcc31 362 _wirelessSerial.baud(57600);
joe4465 0:0010a5abcc31 363
joe4465 0:0010a5abcc31 364 //Read config file
joe4465 0:0010a5abcc31 365 LoadSettingsFromConfig();
joe4465 0:0010a5abcc31 366
joe4465 0:0010a5abcc31 367 //Set initial RC Ccommands
joe4465 1:045edcf091f3 368 _rcMappedCommands[0] = 0;
joe4465 1:045edcf091f3 369 _rcMappedCommands[1] = 0;
joe4465 1:045edcf091f3 370 _rcMappedCommands[2] = 0;
joe4465 1:045edcf091f3 371 _rcMappedCommands[3] = 0;
joe4465 0:0010a5abcc31 372
joe4465 0:0010a5abcc31 373 //Initialise IMU
joe4465 0:0010a5abcc31 374 _freeIMU.init(true);
joe4465 0:0010a5abcc31 375
joe4465 0:0010a5abcc31 376 //Initialise PID
joe4465 0:0010a5abcc31 377 InitialisePID();
joe4465 0:0010a5abcc31 378
joe4465 0:0010a5abcc31 379 //Initialise PWM
joe4465 0:0010a5abcc31 380 InitialisePWM();
joe4465 0:0010a5abcc31 381
joe4465 1:045edcf091f3 382 //Initalise PPM
joe4465 1:045edcf091f3 383 _PPMSignal.mode (PullUp);
joe4465 1:045edcf091f3 384 _PPMSignal.rise(&SignalRise); //Attach SignalRise routine to handle _PPMSignal rise
joe4465 1:045edcf091f3 385 _PPMTimer.start();
joe4465 1:045edcf091f3 386
joe4465 1:045edcf091f3 387 //Initialize all channels to produce "sane" outputs (depending on your definition of sanity ;-).
joe4465 1:045edcf091f3 388 C1s[0] = 1.0*(_channelOutputMax-_channelOutputMin)/(_pulseMax-_pulseMin);
joe4465 1:045edcf091f3 389 C0s[0] = 1.0*_channelOutputMin - _pulseMin*C1s[0];
joe4465 1:045edcf091f3 390 for (i=1; i<_numberOfPPMChannels; i++)
joe4465 1:045edcf091f3 391 {
joe4465 1:045edcf091f3 392 C1s[i]=C1s[0];
joe4465 1:045edcf091f3 393 C0s[i]=C0s[0];
joe4465 1:045edcf091f3 394 }
joe4465 1:045edcf091f3 395
joe4465 1:045edcf091f3 396 // Initialize joystick channels using saved calibration information
joe4465 1:045edcf091f3 397 FILE *fpi = fopen("/local/coefs.txt", "r"); // Open coefficient file on the local file system for reading
joe4465 1:045edcf091f3 398 for(i=0; i<JCCount; i++)
joe4465 1:045edcf091f3 399 {
joe4465 1:045edcf091f3 400 fscanf(fpi, "%f%c%f%c",&C0s[JoystickChannels[i]],&dum1,&C1s[JoystickChannels[i]],&dum2);
joe4465 1:045edcf091f3 401 }
joe4465 1:045edcf091f3 402 fclose(fpi);
joe4465 1:045edcf091f3 403 _PPMTimer.reset();
joe4465 1:045edcf091f3 404
joe4465 0:0010a5abcc31 405 //Start new line
joe4465 0:0010a5abcc31 406 _wiredSerial.printf("\n\r");
joe4465 1:045edcf091f3 407 _wiredSerial.printf("Finished initialising\n\r");
joe4465 0:0010a5abcc31 408
joe4465 0:0010a5abcc31 409 // Start threads
joe4465 0:0010a5abcc31 410 if(_initialised == true)
joe4465 0:0010a5abcc31 411 {
joe4465 0:0010a5abcc31 412 _serialPortMonitorThread = new Thread (SerialPortMonitorThread);
joe4465 0:0010a5abcc31 413 _serialPortMonitorThread->set_priority(osPriorityLow);
joe4465 0:0010a5abcc31 414 _statusThread = new Thread(StatusThread);
joe4465 0:0010a5abcc31 415 _statusThread->set_priority(osPriorityIdle);
joe4465 0:0010a5abcc31 416 _flightControllerThread = new Thread (FlightControllerThread);
joe4465 0:0010a5abcc31 417 _flightControllerThread->set_priority(osPriorityRealtime);
joe4465 0:0010a5abcc31 418 }
joe4465 0:0010a5abcc31 419 }
joe4465 0:0010a5abcc31 420
joe4465 0:0010a5abcc31 421 //MAIN LOOP//////////////////////////////////////////////////////////////////////////
joe4465 0:0010a5abcc31 422 int main()
joe4465 0:0010a5abcc31 423 {
joe4465 0:0010a5abcc31 424 Setup();
joe4465 0:0010a5abcc31 425
joe4465 0:0010a5abcc31 426 // Wait here forever
joe4465 0:0010a5abcc31 427 Thread::wait(osWaitForever);
joe4465 0:0010a5abcc31 428 }