ECE4180 Final Project
Dependencies: LSM9DS1_Library Motor mbed-rtos mbed HC_SR04_Ultrasonic_Library
Fork of IMURoomba4_ThrowSumMo by
Revision 0:c29fc80c3ca3, committed 2017-05-02
- Comitter:
- jplager3
- Date:
- Tue May 02 19:22:12 2017 +0000
- Child:
- 1:6b8a201f4f90
- Commit message:
- Setup good, no compile errors. Warnings aplenty. Drive functionality in progress
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LSM9DS1_Library.lib Tue May 02 19:22:12 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/jplager3/code/LSM9DS1_Library/#e30fde2db274
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Motor.lib Tue May 02 19:22:12 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/simon/code/Motor/#f265e441bcd9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue May 02 19:22:12 2017 +0000
@@ -0,0 +1,225 @@
+#include "mbed.h"
+#include "LSM9DS1.h"
+#include "rtos.h"
+//#include "SDFileSystem.h"
+#include "Motor.h"
+//#include "wave_player.h"
+
+#define PI 3.14159
+// Earth's magnetic field varies by location. Add or subtract
+// a declination to get a more accurate heading. Calculate
+// your's here:
+// http://www.ngdc.noaa.gov/geomag-web/#declination
+#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
+//collab test
+
+Serial pc(USBTX, USBRX);
+//RawSerial pc(USBTX, USBRX);
+Serial dev(p28,p27); //
+//RawSerial dev(p28,p27); //tx, rx
+DigitalOut myled(LED1);
+DigitalOut led2(LED2);
+DigitalOut led4(LED4);
+//IR sensors on p19(front) & p20 (right)
+AnalogIn IR1(p19);
+AnalogIn IR2(p20);
+//L and R DC motors
+Motor Left(p21, p14, p13); // green wires. pwm, fwd, rev, add ", 1" for braking
+Motor Right(p22, p12, p11); // red wires
+// Speaker out
+AnalogOut DACout(p18); //must(?) be p18
+//SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+
+
+Thread thread1;
+Thread thread2;
+Mutex BTmutex;
+Mutex mutex;
+
+
+// Calculate pitch, roll, and heading.
+// Pitch/roll calculations taken from this app note:
+// http://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf?fpsp=1
+// Heading calculations taken from this app note:
+// http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/Magnetic__Literature_Application_notes-documents/AN203_Compass_Heading_Using_Magnetometers.pdf
+void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
+{
+ float roll = atan2(ay, az);
+ float pitch = atan2(-ax, sqrt(ay * ay + az * az));
+ // touchy trig stuff to use arctan to get compass heading (scale is 0..360)
+ mx = -mx;
+ float heading;
+ if (my == 0.0)
+ heading = (mx < 0.0) ? 180.0 : 0.0;
+ else
+ heading = atan2(mx, my)*360.0/(2.0*PI);
+ //pc.printf("heading atan=%f \n\r",heading);
+ heading -= DECLINATION; //correct for geo location
+ if(heading>180.0) heading = heading - 360.0;
+ else if(heading<-180.0) heading = 360.0 + heading;
+ else if(heading<0.0) heading = 360.0 + heading;
+ // Convert everything from radians to degrees:
+ //heading *= 180.0 / PI;
+ pitch *= 180.0 / PI;
+ roll *= 180.0 / PI;
+ //~pc.printf("Pitch: %f, Roll: %f degress\n\r",pitch,roll);
+ //~pc.printf("Magnetic Heading: %f degress\n\r",heading);
+}
+
+/*
+void dev_recv()
+{
+ led2 = !led2;
+ while(dev.readable()) {
+ pc.putc(dev.getc());
+ }
+}
+
+void pc_recv()
+{
+ led4 = !led4;
+ while(pc.readable()) {
+ dev.putc(pc.getc());
+ }
+}*/
+
+ // Driving Methods
+void forward(float speed){
+ Left.speed(speed);
+ Right.speed(speed);
+}
+void reverse(float speed){
+ Left.speed(-speed);
+ Right.speed(-speed);
+}
+void turnRight(float speed){
+ Left.speed(speed);
+ Right.speed(-speed);
+ //wait(0.7);
+}
+void turnLeft(float speed){
+ Left.speed(-speed);
+ Right.speed(speed);
+ //wait(0.7);
+}
+void stop(){
+ Left.speed(0.0);
+ Right.speed(0.0);
+}
+
+void IMU(){
+ //IMU setup
+ LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); // this executes. Pins are correct. Changing them causes fault
+ IMU.begin();
+ if (!IMU.begin()) {
+ led2=1;
+ pc.printf("Failed to communicate with LSM9DS1.\n");
+ }
+ IMU.calibrate(1);
+ IMU.calibrateMag(0);
+
+ //bluetooth setup
+ pc.baud(9600);
+ dev.baud(9600);
+
+ /*pc.attach(&pc_recv, Serial::RxIrq);
+ dev.attach(&dev_recv, Serial::RxIrq);*/
+
+ while(1) {
+ //myled = 1;
+ while(!IMU.magAvailable(X_AXIS));
+ IMU.readMag();
+ //myled = 0;
+ while(!IMU.accelAvailable());
+ IMU.readAccel();
+ while(!IMU.gyroAvailable());
+ IMU.readGyro();
+ BTmutex.lock();
+ pc.puts(" X axis Y axis Z axis\n\r");
+ dev.puts(" X axis Y axis Z axis\n\r");
+ pc.printf("gyro: %9f %9f %9f in deg/s\n\r", IMU.calcGyro(IMU.gx), IMU.calcGyro(IMU.gy), IMU.calcGyro(IMU.gz));
+ pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az));
+ pc.printf("mag: %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
+ dev.printf("mag: %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
+ printAttitude(IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az), IMU.calcMag(IMU.mx),
+ IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
+ BTmutex.unlock();
+ myled = 1;
+ wait(0.5);
+ myled = 0;
+ wait(0.5);
+ }
+}
+
+void defaultDrive(){ //default behavior for robot
+//Drive forward until object detected. Stop, turn left, then drive until IR2 says path is clear, then turn right to go around object.
+ forward(0.2);
+ if(IR1 > 0.85) { // this is threshold for collision
+ stop();
+ Thread::wait(250);
+ // check if path to right is clear
+ if(IR2 < .4){
+ turnRight(0.3);
+ while(IR1>0.4){}; //turn until path in front is clear
+ stop();
+ }
+ else {
+ turnLeft(0.3);
+ while(IR1>0.4){}; //execute turn until front IR says path is clear
+ // consider placing Thread::wait(??) within loop to account for IR polling?
+ stop();
+ //Thread::wait(250);
+ }
+ Thread::wait(250);
+ forward(0.2);
+
+ /*PICK UP FROM HERE
+ Implement logic to control two scenarios:
+ 1) Roomba has detected obstacle in front, but Right is clear. Has turned right and needs to continue driving
+ 2) Roomba has detected obstacle, Right is blocked. Turn left & drive until Right is clear. Turn back to right (orig. Fwd heading) and continue.
+ 2a) Consider more complex routing to circle around obstacle
+ */
+
+
+ /*
+ //while(IR2>0.5 && IR1<0.8){}; // drive until roomba has passed object.
+ while(IR1<0.8){};
+ stop();
+ Thread::wait(250);
+ //check that path in front is clear
+ if(IR1>0.8){ // if not clear, turn left again until front is clear
+ turnLeft(0.3);
+ while(IR1>0.4){}
+ stop();
+ Thread::wait(250);
+
+ }
+ else {
+
+ }
+
+
+ Thread::wait(200);
+
+ while(IR2>0.85 ) forward(0.3); // drive until
+ */
+
+
+
+ }
+
+}
+
+int main()
+{
+ thread1.start(IMU); // start the IMU thread
+ //thread2.start(defaultDrive);
+
+ forward(0.3);
+ led4=1;
+ while(1){
+
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue May 02 19:22:12 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed-rtos/#58563e6cba1e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue May 02 19:22:12 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed/builds/794e51388b66 \ No newline at end of file

