Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BCEmotor Battery_Linear_Actuator Controller_ IMU_code_ LTC1298_7_14 MODSERIAL PosVelFilter System mbed
Fork of 7_21_17_FSG by
main.cpp
- Committer:
- mdavis30
- Date:
- 2017-07-27
- Revision:
- 11:b5cc98f154a4
- Parent:
- 10:68c3b3f9dc50
- Child:
- 12:fa9f84f2967f
File content as of revision 11:b5cc98f154a4:
#include "mbed.h"
#include "MODSERIAL.h" //for IMU (and got rid of regular serial library) #include "IMU_code.h"
#include "StaticDefs.hpp"
#include "ltc1298.hpp"
//new line to get the publish working
#include <cstdlib>
#include <string>
using namespace std;
#include "IMU_code.h" //IMU code
#include "Battery_Linear_Actuator.h" //Battery Linear Actuator code (TROY) (FIX INCLUSION ISSUES, ports)
Serial PC(USBTX,USBRX); //tx, rx
extern "C" void mbed_reset(); //utilized to reset the mbed through the serial terminal
char Key;
float input_num;
string IMU_STRING = "";
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
//Pin for limit switch for buoyancy engine
AnalogIn ain(p18);
/* ************ These tickers work independent of any while loops ********** */
Ticker IMU_ticker; //ticker for printing IMU //https://developer.mbed.org/handbook/Ticker
Ticker BE_position_ticker; //probably delete soon
Ticker PRESSURE_ticker;
Ticker BCE_ticker; //new 6/5/17
Ticker PID_ticker; //new 6/14/17
Ticker LA_ticker; //new 6/22/17
/* ************************************************************************* */
//Set beginning position for buoyancy and linear actuator
float positionCmd = 190.0;
float pi = 3.14159265359;
float la_setPoint = 0.00; //the IMU pitch angle we want (setpoint)
/* PID LOOP STUFF */
float la_P_gain = 1.0;
float la_I_gain = 0.00;
float la_D_gain = 0.00;
/* PID LOOP STUFF */
int count_while = 0;
float IMU_pitch_angle;
double double_actual_position = 0.00;
string MC_readable_string = "";
int IMU_count = 0;
int Pr_count = 0;
int BCE_count = 0;
void IMU_ticking()
{
//led1 = !led1; //flash the IMU LED
//PC.printf("%s\n", IMU_STRING.c_str()); //if there's something there, print it
PC.printf("%s\n", IMU_STRING.c_str());
}
void PRESSURE_ticking()
{
PC.printf("pressure: %f psi \n", (0.00122*(adc().ch1_filt)*9.9542)-0.0845); //read the analog pin
//this voltage has been checked and scaled properly (6/28/2017)
}
void BCE_ticking() //new 6/5/17
{
PC.printf("BE_pos: %3.0f mm BE_vel: %2.2f mm/s Set Point %3.0f controller output: % 1.3f \n", pvf().getPosition(), pvf().getVelocity(), positionCmd, posCon().getOutput());
}
int main()
{
PC.baud(9600); //mbed to PC serial connection speed
hBridge().stop(); //Stop the buoyancy engine from moving
systemTime().start(); //start the timer, needed for PID loop
/* **************** Linear Actuator MOTOR CONTROLLER **************** */
Battery_Linear_Actuator BLA_object; //create the IMU object from the imported class
PC.printf("%s\n", BLA_object.Keyboard_U().c_str()); //velocity = 0, motor disabled
PC.printf("%s\n", BLA_object.Keyboard_Q().c_str()); //turn off motor
wait(1);
PC.printf("%s\n", BLA_object.Keyboard_E().c_str()); //turn on motor
wait(1);
//setup and start the adc. This runs on a fixed interval and is interrupt driven
adc().initialize();
adc().start();
//Initialize the position velocity filter. This will consume a couple of seconds for
//the filter to converge
pvf().init();
//NEW 7/21 Homing the motor
PC.printf("### homing the device ###");
BLA_object.Keyboard_H();
wait(10); //for debugging
float P = 0.10;
float I = 0.00;
float D = 0.00;
float count = 0.0;
float positionCmd_cm;
float la_step = 1.0;
float la_setPoint_temp = 0.0;
bool BCE_auto = true;
bool LA_auto = false;
float bce_auto_step = 0.1;
float volume_bce = 1.0;
int bce_man_step = 50;
float ticker_step_size = 1.0;
//set the intial gains for the position controller
posCon().setPgain(P);
posCon().setIgain(I);
posCon().setDgain(D);
posCon().writeSetPoint(positionCmd);
hBridge().reset();
//hBridge().run(motor_cmd);
/* *************************** LED *************************** */
led1 = 1; //initial values
led2 = 1;
led3 = 1;
led4 = 1;
/* *************************** LED *************************** */
IMU_code IMU_object;
while(1)
{
/* *************************** IMU *************************** */
IMU_STRING = IMU_object.IMU_run(); //grab the IMU string each iteration through the loop
IMU_pitch_angle = 1.0 * IMU_object.IMU_pitch(); //get the pitch update constantly?
//PC.printf("pitch angle... %f set pitch angle: %f\n", IMU_yaw_angle, la_setPoint);
/* *************************** IMU *************************** */
/* Buoyancy Engine */
// update the position velocity filter
pvf().update();
//update the controller with the current numbers in the position guesser
posCon().update(pvf().getPosition(), pvf().getVelocity(), pvf().getDt()) ;
hBridge().run(posCon().getOutput());
/* Buoyancy Engine */
//FOR DEBUGGING
//PC.printf("BE_pos: %3.0f mm BE_vel: %2.2f mm/s Set Point %3.0f controller output: % 1.3f P: %1.3f I: %1.4f D: %1.4f\r", pvf().getPosition(), pvf().getVelocity(), positionCmd, posCon().getOutput(), P, I, D);
//PC.printf("WHILE LOOP\n"); //DEBUG
if (PC.readable())
{
//led4 != led4;
//PC.printf("DEBUG: PC IS READABLE\n"); //DEBUG
Key=PC.getc();
//Universal MBED Controls
if(Key=='!') //RESET THE MBED
{
PC.printf("MBED RESET KEY (!) PRESSED\n");
PC.printf("Linear Actuator Motor disabled!\n");
//disable the motor
BLA_object.Keyboard_Q(); //DISABLE THE MOTOR
wait(0.5); //500 milliseconds
mbed_reset(); //reset the mbed!
}
/* else if(Key == '[')
{
BLA_object.velocity_only(-100); //send speed -100 command to linear actuator (retract)
}
else if(Key == ']')
{
BLA_object.velocity_only(100); //send speed +100 command to linear actuator (extend)
}
else if(Key == 'u')
{
BLA_object.Keyboard_U(); //stop linear actuator
} */
else if(Key =='H') //homing sequence
{
PC.printf("### homing the device ###");
BLA_object.Keyboard_H();
wait(10); //for debugging
const char *char_actual_position = BLA_object.get_pos().c_str();
//actual_position_string = BLA_object.get_pos().c_str();
sscanf(char_actual_position, "%lf", &double_actual_position);
// 7/10/17
PC.printf("LA actual position: %lf \n", double_actual_position);
//TROY NOTES on Linear Actuator commands:
//"pos" returns integer value "66813 for example"
//"hosp-100" is the setting of the motor, it retracts at 100 rpm
//"gohoseq" to home it, it will not give you feedback
//print the position after you do this to see where the LA is
}
else if(Key=='p' or Key == 'P')
{
// 7/10/17
//actual_position_string = BLA_object.get_pos();
//actual_position_string = BLA_object.get_pos().c_str();
//const char *char_actual_position = string_actual_position.c_str();
const char *char_actual_position = BLA_object.get_pos().c_str();
//actual_position_string = BLA_object.get_pos().c_str();
sscanf(char_actual_position, "%lf", &double_actual_position);
// 7/10/17
PC.printf("### L.A. position is\nLA_AP: %lf ###\n", double_actual_position); //flip this back and forth
if (double_actual_position > 180000)
PC.printf(" <<<< REACHED MAXIMUM L.A. POSITION! >>>>\n");
else if (double_actual_position < 0)
PC.printf(" <<<< REACHED MINIMUM L.A. POSITION! >>>>\n");
wait(1); //for debugging
// "-999999" means it is not working
}
else if (Key == '3' or Key == '#')
{
PC.printf("Ticker Sensor Step Size\n");
if (ticker_step_size == 1.0)
{
ticker_step_size = 5.0;
}
else if (ticker_step_size == 5.0)
{
ticker_step_size = 10.0;
}
else if (ticker_step_size == 10.0)
{
ticker_step_size = 20.0;
}
else if (ticker_step_size == 20.0)
{
ticker_step_size = 1.0;
}
PC.printf("Ticker Step Size is %f\n", ticker_step_size);
}
else if (Key =='4' or Key == '$')
{
if (IMU_count == 0)
{
PC.printf("IMU turned on! Ticker time is %f seconds\n", ticker_step_size);
IMU_ticker.attach(&IMU_ticking, ticker_step_size);
IMU_count = 1;
}
else if (IMU_count == 1)
{
PC.printf("IMU turned off!\n");
IMU_ticker.detach();
IMU_count = 0;
}
}
else if (Key == '5' or Key == '%')
{
if (Pr_count == 0)
{
PC.printf("Pressure turned on! Ticker time is %f seconds\n", ticker_step_size);
PRESSURE_ticker.attach(&PRESSURE_ticking, ticker_step_size);
Pr_count = 1;
}
else if (Pr_count == 1)
{
PC.printf("Pressure turned off!\n");
PRESSURE_ticker.detach();
Pr_count = 0;
}
}
else if (Key == '6' or Key == '^')
{
if (BCE_count == 0)
{
PC.printf("BCE turned on! Ticker time is %f seconds\n", ticker_step_size);
BCE_ticker.attach(&BCE_ticking, ticker_step_size);
BCE_count = 1;
}
else if (BCE_count == 1)
{
PC.printf("BCE turned off!\n");
BCE_ticker.detach();
BCE_count = 0;
}
}
//Buoyancy Engine Controls
else if (Key == ',' or Key == '<')
{
if (BCE_auto == false)
{
PC.printf("BCE: Now in Automatic Mode\n");
BCE_auto = true;
}
else
{
PC.printf("BCE: Still in Automatic Mode\n");
}
}
else if (Key == '.' or Key == '>')
{
if (BCE_auto == true)
{
PC.printf("BCE: Now in Manual Mode\n");
BCE_auto = false;
}
else
{
PC.printf("BCE: Still in Manual Mode\n");
}
}
//BCE Automatic Controls
else if(Key =='d' or Key == 'D')
{
if (BCE_auto == true)
{
volume_bce -= bce_auto_step;
PC.printf("The volume for the buoyancy motor is\nVBE: %1.3f liters\n", volume_bce); //to read in MATLAB
}
else
{
PC.printf("ERROR: In BCE Manual Mode, this is a auto command\n");
}
}
else if(Key == 'f' or Key == 'F')
{
if (BCE_auto == true)
{
volume_bce += bce_auto_step;
PC.printf("The volume for the buoyancy motor is\nVBE: %1.3f liters\n", volume_bce); //to read in MATLAB
}
else
{
PC.printf("ERROR: In BCE Manual Mode, this is a auto command\n");
}
}
else if(Key == 'r' or Key == 'R')
{
if (BCE_auto == true)
{
PC.printf("\nR received!\n");
positionCmd_cm=(1000/(16*pi))*volume_bce;
positionCmd = positionCmd_cm*10;
//positionCmd= positionCmd_temp*0.000000001;
//PC.printf("BCE engine going to position: %3.2f\n", positionCmd);
PC.printf("\nBASETP: %3.0f\n", positionCmd);
posCon().writeSetPoint(positionCmd);
//posCon().setPgain(P);
//posCon().setIgain(I);
//posCon().setDgain(D);
hBridge().run(posCon().getOutput());
count = 0;
}
else
{
PC.printf("ERROR: In BCE Manual Mode, this is a auto command\n");
}
}
//BCE Manual Controls
else if (Key == '2' or Key == '@')
{
if (BCE_auto == false)
{
PC.printf("BCE Manual Step Size Change\n");
if (bce_man_step == 50)
{
bce_man_step = 25;
}
else if (bce_man_step == 25)
{
bce_man_step = 10;
}
else if (bce_man_step == 10)
{
bce_man_step = 1;
}
else if (bce_man_step == 1)
{
bce_man_step = 50;
}
PC.printf("BCE Manual Step Size Now %d\n", bce_man_step);
}
else
{
PC.printf("ERROR: In BCE Auto Mode, this is a manual command\n");
}
}
else if (Key == 'z' or Key =='Z')
{
if (BCE_auto == false and positionCmd < 395)
{
//increment the duty cycle
positionCmd -= bce_man_step;
PC.printf("The position for the buoyancy motor is\nBEP: %3.0f\n", positionCmd); //to read in MATLAB
}
else if (positionCmd > 395)
{
PC.printf("ERROR: Cannot move past 395 mm\n");
positionCmd = 370;
}
else
{
PC.printf("ERROR: In BCE Auto Mode, this is a manual command\n");
}
}
else if (Key == 'x' or Key == 'X')
{
if (BCE_auto == false and positionCmd > -25)
{
//decrement the duty cycle
positionCmd += bce_man_step;
PC.printf("The position for the buoyancy motor is\nBEP: %3.0f\n", positionCmd); //to read in MATLAB
}
else if (positionCmd < -25)
{
PC.printf("ERROR: Cannot move past -5 mm\n");
positionCmd = -5;
}
else
{
PC.printf("ERROR: In BCE Auto Mode, this is a manual command\n");
}
}
else if(Key=='w' or Key =='W')
{
if (BCE_auto == false)
{
PC.printf("\nW received!\n");
PC.printf("BASETP: %3.0f\n", positionCmd);
posCon().writeSetPoint(positionCmd);
//posCon().setPgain(P);
//posCon().setIgain(I);
//posCon().setDgain(D);
hBridge().run(posCon().getOutput());
hBridge().reset();
count = 0;
}
else
{
PC.printf("ERROR: In BCE Auto Mode, this is a manual command\n");
}
}
else if (Key == 'l' or Key == 'L')
PC.printf("DEBUG: String position? %f set position? %f velocity? %f (BCE active: %f)\n", pvf().getPosition(), positionCmd, pvf().getVelocity(),posCon().getOutput()); //DEBUG TROY
//Linear Actuator Controls
else if(Key == 'c' or Key == 'C')
{
if (LA_auto == true)
{
PC.printf("ERROR: LA already in auto mode\n");
}
else
{
LA_auto = true;
PC.printf("```````````Now in IMU Controlled Mode```````````````\n");
count_while = 0;
}
}
else if (Key == 'v' or Key == 'V')
{
if (LA_auto == true)
{
LA_auto = false;
//go from imu controlled to manual
PC.printf("```````````Now in Manual Mode````````````````````\n");
count_while = 0;
}
else
{
PC.printf("ERROR: LA already in manual mode\n");
}
}
else if (Key == '0' or Key == ')')
{
PC.printf(") recieved\n");
if (la_step == 0.5)
{
la_step = 1.0;
}
else if (la_step == 1.0)
{
la_step = 5.0;
}
else if (la_step == 5.0)
{
la_step = 10.0;
}
else if (la_step == 10.0)
{
la_step = 15.0;
}
else if (la_step == 15.0)
{
la_step = 0.5;
}
PC.printf("LA Step Size Now %f\n", la_step);
}
else if (Key=='-' or Key == '_')
{
if (LA_auto == true)
{
la_setPoint_temp -= la_step; //IMU_yaw_angle -= 1.0;
PC.printf("- recieved\n");
PC.printf("LA auto step size: %f\n", la_step);
PC.printf("LA angle changed to\nLA_ANG: %f\n", la_setPoint_temp);
}
else
{
PC.printf("ERROR: LA in manual mode!\n");
}
}
else if (Key =='=' or Key == '+')
{
if (LA_auto == true)
{
la_setPoint_temp += la_step; //IMU_yaw_angle += 1.0;
PC.printf("+ recieved\n");
PC.printf("LA auto step size: %f\n", la_step);
PC.printf("LA angle changed to\nLA_ANG: %f\n", la_setPoint_temp);
}
else
{
PC.printf("ERROR: LA in manual mode!\n");
}
}
else if (Key == 'A' or Key == 'a')
{
if (LA_auto == true)
{
PC.printf("A recieved\n");
la_setPoint=la_setPoint_temp;
PC.printf("LA angle now set to\nLA_A_SND: %f\n", la_setPoint);
}
else
{
PC.printf("ERROR: LA in manual mode!\n");
}
}
else if(Key == 'n' or Key == 'N')
{
if (LA_auto == false)
{
PC.printf("N key pressed. \n");
PC.printf("%s\n", BLA_object.Keyboard_DASH_KEY().c_str());
}
else
{
PC.printf("ERROR: In LA in Auto Mode, this is a manual command\n");
}
}
else if(Key == 'm' or Key == 'M')
{
if (LA_auto == false)
{
PC.printf("M key pressed. \n");
PC.printf("%s\n", BLA_object.Keyboard_EQUAL_KEY().c_str());
}
else
{
PC.printf("ERROR: In LA in Auto Mode, this is a manual command\n");
}
}
else if(Key == 'j' or Key == 'J')
{
if (LA_auto == false)
{
PC.printf("J key pressed. \n");
PC.printf("%s\n", BLA_object.Keyboard_A().c_str());
}
else
{
PC.printf("ERROR: In LA in Auto Mode, this is a manual command\n");
}
}
else if(Key == 'k' or Key == 'K')
{
if (LA_auto == false)
{
PC.printf("K key pressed. \n");
PC.printf("%s\n", BLA_object.Keyboard_D().c_str());
}
else
{
PC.printf("ERROR: In LA in Auto Mode, this is a manual command\n");
}
}
else
{
PC.printf("\n%c received!\n", Key);
PC.printf("\nDoing nothing.\n");
}
wait_us(100); //for PC readable
//PC.printf("%s\n", BLA_object.PID_velocity_control(la_setPoint, IMU_yaw_angle, la_P_gain, la_I_gain, la_D_gain).c_str()); //get output string
//BLA_object.PID_velocity_control(la_setPoint, IMU_yaw_angle, la_P_gain, la_I_gain, la_D_gain).c_str();
}
//end of PC readBLE
//MC readable
MC_readable_string = BLA_object.MC_readable_redux();
//PC.printf("CHECK_MC_readable:\n%s\n", MC_readable_string);
/* if (LA_auto == false)
{
if (!MC_readable_string.empty()) //if this string is empty
{
PC.printf("%s\n", MC_readable_string); //get responses from the linear actuator motor controller
}
else
{
;
//PC.printf("NOTHING?\n");
}
}*/
if (LA_auto==true)
{
//PC.printf("LA_auto true\n");
//PC.printf("%s\n", BLA_object.PID_velocity_control(la_setPoint, IMU_pitch_angle, la_P_gain, la_I_gain, la_D_gain).c_str()); //get output string
BLA_object.PID_velocity_control(la_setPoint, IMU_pitch_angle, la_P_gain, la_I_gain, la_D_gain).c_str();
//wait_us(100); //for PC readable (0.1 ms)
}
else if (LA_auto == false)
{
//PC.printf("LA_auto false\n");
// if (!MC_readable_string.empty()) //if this string is empty
// {
// PC.printf("%s\n", MC_readable_string); //get responses from the linear actuator motor controller
// }
// else
// {
// ;
// //PC.printf("NOTHING?\n");
// }
// while (count_while==0)
// {
//// PC.printf("%s\n", BLA_object.Keyboard_U().c_str()); //velocity = 0, motor disabled
//// PC.printf("%s\n", BLA_object.Keyboard_Q().c_str()); //turn off motor
//// wait(1);
//// PC.printf("%s\n", BLA_object.Keyboard_E().c_str()); //turn on motor
//// wait(1);
//// PC.printf("\n```````````Linear Actuator in Manual controlled mode````````````\n\n");
//// count_while++;
//
// BLA_object.Keyboard_E(); //turn on motor
// BLA_object.velocity_only(0); //set the velocity to zero just in case
// PC.printf("\n```````````Linear Actuator in Manual controlled mode````````````\n\n");
// count_while++;
// }
}
if ((abs(pvf().getVelocity())<0.1) && (posCon().getOutput()>0.0))
{
count ++;
//pc().printf("We have a small issue\n");
if(count==10)
{
pc().printf("Bad pot issue\n");
//hBridge().stop();
count = 0;
}
}
else if ((5.0*ain.read())<1.0)
{
pc().printf("Hit the limit switch??\n");
hBridge().stop();
wait(1);
hBridge().reset();
positionCmd= 375;
posCon().writeSetPoint(positionCmd);
hBridge().run(posCon().getOutput());
wait(2);
}
//string snaps
else if (pvf().getVelocity() > 100)
{
PC.printf("DEBUG: String position? %f velocity? %f\n", pvf().getPosition(), pvf().getVelocity()); //DEBUG TROY
//hBridge().stop();
//PC.printf("PosVelFilter B.E. Velocity: %f\n", pvf().getVelocity());
PC.printf("********** String broke? *********\n");
}
}
}
