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: BNO055_fusion Emaxx_Navigation_Dynamic_HIL MODSERIAL ServoIn ServoOut Vehicle_Model mbed
Fork of Emaxx_Navigation_Dynamic_HIL by
Revision 4:e27ca0c82814, committed 2016-12-08
- Comitter:
- lddevrie
- Date:
- Thu Dec 08 20:38:24 2016 +0000
- Parent:
- 3:9b6db94aa2b3
- Child:
- 5:d6d8ecd418cf
- Commit message:
- Update for hardware and software in the loop simulation
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Wed Sep 14 18:19:50 2016 +0000
+++ b/main.cpp Thu Dec 08 20:38:24 2016 +0000
@@ -29,6 +29,8 @@
#define DIRECT_MODE 0 //command maps to throttle and steer commands normalized
#define COURSE_MODE 1 //Commands map to heading and speed
+#define HIL_MODE 0 // commands map to hardware active simulation
+#define SIL_MODE 1 // commands map to software only simulation
//I2C i2c(p9, p10); // SDA, SCL
BNO055 imu(p9, p10);
@@ -77,6 +79,13 @@
float Kp_psi, Kp_spd, Ki_psi, Ki_spd; // controller gains
int led1,led2,led3,led4; // neo-strip variables?
volatile bool newpacket = false; // boolean identifier of new odroid packet
+float x0; // initial x-position when in software or hardware in the loop simulation
+float y0; // initial y-position when in software or hardware in the loop simulation
+int sim_mode = 0; // sets simulation mode, zero by default, 1 for HIL, 2 for SIL
+float x = 0.0; // simulation variables
+float y = 0.0; // simulation variables
+float psi = 0.0; // simulation variables
+float spd = 0.005; // simulation speed
void rxCallback(MODSERIAL_IRQ_INFO *q)
{
@@ -138,6 +147,7 @@
imu_LED = 0; // turn off IMU indicator (LED 4)
gps.setRefPoint(REF_LAT,REF_LON,REF_ALT); // set local origin of reference frame for GPS conversion
+
// procedure to ensure IMU is operating correctly
if(imu.check()) {
pc.printf("BNO055 connected\r\n");
@@ -150,17 +160,22 @@
imu.set_mapping(2);
// Blinks light if IMU is not calibrated, stops when calibration is complete
- while(int(imu.calib) < 0xCF) {
+ /*while(int(imu.calib) < 0xCF) {
pc.printf("Calibration = %x.\n\r",imu.calib);
imu.get_calib();
wait(0.5);
imu_LED = !imu_LED;
} // end while(imu.calib)
+ */
imu_LED = 1; // turns on IMU light when calibration is successful
} else {
- pc.printf("IMU BNO055 NOT connected\r\n Program Trap."); // catch statement if IMU is not connected correctly
- // turn on all lights is IMU is not connected correctly
+ pc.printf("IMU BNO055 NOT connected\r\n Entering Simulation mode..."); // catch statement if IMU is not connected correctly
+
+ sim_mode = 2; // by default it will go to simulation mode without actuators active (SIL)
+
+
+ /* // turn on all lights is IMU is not connected correctly
rc_LED = 1;
armed_LED = 1;
imu_LED = 1;
@@ -174,8 +189,11 @@
wait(0.5);
} // end while(1) {blink if IMU is not connected}
+ */
+
} // end if(imu.check)
+
// int colors[4] = {ORANGE,YELLOW,GREEN,CYAN};
pc.printf("Emaxx Navigation Program\r\n"); // print indication that calibration is good and nav program is running
@@ -208,7 +226,7 @@
if(newpacket) { // if xbee port receives a complete message, parse it
char buf[MAX_MESSAGE_SIZE];
-
+
// reads from modserial port buffer, stores characters into string "buf"
int i = 0;
if(xbee.rxBufferGetCount()>0) {
@@ -273,10 +291,16 @@
} // end default status in switch
} // end switch(cmd_mode)
- Steer.write((int)((str*500.0)+1500.0)); // Write Steering Pulse
- Throttle.write((int)((thr*500.0)+1500.0)); //Write Throttle Pulse
- } else { // goes with if auto_ctrl
+ if(sim_mode<2) { // only actuates if in experiment or HIL modes
+ Steer.write((int)((str*500.0)+1500.0)); // Write Steering Pulse
+ Throttle.write((int)((thr*500.0)+1500.0)); //Write Throttle Pulse
+ } else {
+ // won't send command to motor and servo if in SIL mode
+ }
+
+
+ } else { // goes with if auto_ctrl, manual control mode
Steer.write((int)((str*500.0)+1500.0)); // Write Steering Pulse
Throttle.write(1500); //Write Throttle Pulse
@@ -293,41 +317,72 @@
}/// end else armed
- imu.get_angles();
- imu.get_accel();
- imu.get_gyro();
- imu.get_lia();
- float dt = t.read()-t_imu;
- if(dt > (1/IMU_RATE)) {
+ if(sim_mode==0) {
+ imu.get_angles();
+ imu.get_accel();
+ imu.get_gyro();
+ imu.get_lia();
+ float dt = t.read()-t_imu;
+ if(dt > (1/IMU_RATE)) {
+
+ float tic = t.read();
+ ekf.setRot(wrapToPi(imu.euler.yaw),imu.euler.pitch,imu.euler.roll);
+ ekf.timeUpdate(imu.lia.x,imu.lia.y,imu.lia.z,dt);
+
+ xbee.printf("$EKF,%.2f,%.2f,%.2f,%.2f\r\n",ekf.getPosNorth(),ekf.getPosEast(),ekf.getVelNorth(),ekf.getVelEast());
+ xbee.printf("$IMU,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",imu.lia.x,imu.lia.y,imu.lia.z,imu.gyro.x,imu.gyro.y,imu.gyro.z,imu.euler.roll,imu.euler.pitch,wrapToPi(imu.euler.yaw));
+ pc.printf("$EKF,%.2f,%.2f,%.2f,%.2f\r\n",ekf.getPosNorth(),ekf.getPosEast(),ekf.getVelNorth(),ekf.getVelEast());
+ pc.printf("$IMU,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",imu.lia.x,imu.lia.y,imu.lia.z,imu.gyro.x,imu.gyro.y,imu.gyro.z,imu.euler.roll,imu.euler.pitch,wrapToPi(imu.euler.yaw));
+
+ t_imu = t.read();
+ }
+
+ if(t.read()-t_gps >(1/GPS_RATE)) {
+ //printf("Kp_psi: %.2f Kp_spd: %.2f Ki_spd: %.2f\r\n", Kp_psi,Kp_spd,Ki_spd);
+
+
+ float tic2 = t.read();
+ ekf.measUpdate(gps.pos_north,gps.pos_east,gps.vel_north,gps.vel_east);
+ // xbee.printf("$GPS,%.8f,%.8f,%.3f,%.3f,%.3f\r\n",gps.dec_latitude,gps.dec_longitude,gps.msl_altitude,gps.course_d,KNOTS_2_MPS*gps.speed_k);
+ // xbee.printf("$STA,%d,%d,%d,%d\r\n",);
- float tic = t.read();
- ekf.setRot(wrapToPi(imu.euler.yaw),imu.euler.pitch,imu.euler.roll);
- ekf.timeUpdate(imu.lia.x,imu.lia.y,imu.lia.z,dt);
+ t_gps = t.read();
+
+ }
+ wait(1/LOOP_RATE);
+ // status_LED=!status_LED;
+ auto_ctrl_old = auto_ctrl;
+
+ } else { // else condition implies a simulation mode is enabled
+
+ float dt = t.read()-t_imu;
+ if(dt > (1/IMU_RATE)) {
- xbee.printf("$EKF,%.2f,%.2f,%.2f,%.2f\r\n",ekf.getPosNorth(),ekf.getPosEast(),ekf.getVelNorth(),ekf.getVelEast());
- xbee.printf("$IMU,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",imu.lia.x,imu.lia.y,imu.lia.z,imu.gyro.x,imu.gyro.y,imu.gyro.z,imu.euler.roll,imu.euler.pitch,wrapToPi(imu.euler.yaw));
+ float tic = t.read();
+
+ psi_err = wrapToPi(des_psi-psi);
+ spd_err = des_spd - spd;
+ spd_err_i += spd_err;
+ str = Kp_psi*psi_err/(spd+0.05);
+ thr = Kp_spd*spd_err + Ki_spd*spd_err_i/LOOP_RATE;
+
+ x = x + spd*cos(psi)*dt;
+ y = y + spd*sin(psi)*dt;
+ psi = psi + str*dt;
+ spd = spd + thr*dt;
- t_imu = t.read();
+ xbee.printf("$SIM,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",x,y,spd*cos(psi),spd*sin(psi),wrapToPi(psi));
+ pc.printf("$SIM,%.2f,%.2f,%.2f,%.2f,%.2f\r\n",x,y,spd*cos(psi),spd*sin(psi),wrapToPi(psi));
+ t_imu = t.read();
+ }
+
+
}
- if(t.read()-t_gps >(1/GPS_RATE)) {
- //printf("Kp_psi: %.2f Kp_spd: %.2f Ki_spd: %.2f\r\n", Kp_psi,Kp_spd,Ki_spd);
-
-
- float tic2 = t.read();
- ekf.measUpdate(gps.pos_north,gps.pos_east,gps.vel_north,gps.vel_east);
- // xbee.printf("$GPS,%.8f,%.8f,%.3f,%.3f,%.3f\r\n",gps.dec_latitude,gps.dec_longitude,gps.msl_altitude,gps.course_d,KNOTS_2_MPS*gps.speed_k);
- // xbee.printf("$STA,%d,%d,%d,%d\r\n",);
- t_gps = t.read();
+ } // end while(1)
- }
- wait(1/LOOP_RATE);
- // status_LED=!status_LED;
- auto_ctrl_old = auto_ctrl;
- }
-
-}
+} // end main
void parseMessage(char * msg)
{
@@ -368,23 +423,23 @@
Kp_psi = arg1;
Kp_spd = arg2;
Ki_spd = arg3;
-
+
pc.printf("Params Received: %f %f %f\n",arg1,arg2,arg3);
//xbee.printf("Params Recieved: %f %f %f\r\n",arg1,arg2,arg3);
break;
}
case 2: { // sets origin of local reference frame
-
+
//pc.printf("%s\n",msg);
float ref_lat = arg1;
float ref_lon = arg2;
float ref_alt = arg3;
gps.setRefPoint(ref_lat,ref_lon,ref_alt);
-
+
pc.printf("Params Received: %f %f %f\n",arg1,arg2,arg3);
//xbee.printf("Params Recieved: %f %f %f\r\n",arg1,arg2,arg3);
-
+
break;
}
default: {
@@ -402,7 +457,34 @@
int colors[4]= {arg1,arg1,arg1,arg1};
float brightness = arg2;
setLED(colors,brightness);
- }
+ } // end of $LED
+
+
+ if(!strncmp(msg, "$SIM", 4)) {
+ int arg1;
+ float arg2,arg3,arg4;
+
+ sscanf(msg,"$SIM,%d,%f,%f,%f\n",&arg1,&arg2,&arg3,&arg4);
+ sim_mode = arg1; // sets whether in hardware in the loop or software in the loop (actuators active or not during simulation)
+ auto_clock = t.read();
+ switch (cmd_mode) {
+ case HIL_MODE: {
+ auto_ctrl = true;
+ x = arg2;
+ y = arg3;
+ psi = arg4;
+ }
+ case SIL_MODE: {
+ auto_ctrl = true;
+ x = arg2;
+ y = arg3;
+ psi = arg4;
+ }
+ default: {
+ }
+ }
+ } //emd of $SIM
+
