SmartWheels self-driving race car. Designed for NXP Cup. Uses FRDM-KL25Z, area-scan camera, and simple image processing to detect and navigate any NXP spec track.

Dependencies:   TSI USBDevice mbed-dev

Fork of SmartWheels by haofan Zheng

Branch:
Drift
Revision:
87:15fcf7891bf9
Parent:
64:43ab429a37e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RemovedSources/IMUManager.cpp.txt	Wed Apr 19 04:06:01 2017 +0000
@@ -0,0 +1,268 @@
+#if 0
+
+#include "IMUManager.h"
+#include "PinAssignment.h"
+#include "math.h"
+
+//#define SW_DEBUG
+#include "SWCommon.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KEEP_TWO_DECIMAL(X) ((float)((int)(X * 100)) / 100)
+
+static const int SLAVE_ADDR_WRITE = (FXOS8700CQ_SLAVE_ADDR << 1);
+static const int SLAVE_ADDR_READ  = (FXOS8700CQ_SLAVE_ADDR << 1) | 0x01;
+static const float ACCELER_SCALE_F_G = ACCELER_SCALE_F_MG * 0.001f;
+
+static volatile struct imu_vec3 accel_value;
+static volatile struct imu_vec3 accel_offset;
+static volatile struct imu_vec3 velocity_value;
+static volatile struct imu_vec3 position_value;
+static volatile int8_t imu_temp = 0;
+//static volatile struct imu_vec3 magt_value;
+static I2C imu_i2c_port(PIN_IMC_SDA, PIN_IMC_SCL);
+static DigitalOut imu_accl_sa0(PIN_IMC_ACCL_SA0, ACCEL_MAG_SA0);
+static DigitalOut imu_accl_sa1(PIN_IMC_ACCL_SA1, ACCEL_MAG_SA1);
+static char imu_data_buffer[FXOS8700CQ_READ_LEN] = { 0 };
+static Ticker m_imu_update_tick;
+static Timer m_imu_update_timer;
+static float m_imu_update_prev_time;
+
+//Debug
+static DebugCounter counter(10, PTE4);
+
+inline void imu_i2c_write_8bit(const char addr, const char* buffer)
+{
+    static char write_buf[2];
+    write_buf[0] = addr;
+    write_buf[1] = *buffer;
+    imu_i2c_port.write(SLAVE_ADDR_WRITE, write_buf,  2, false);
+}
+
+inline void imu_i2c_read_8bit(const char addr, char* buffer)
+{
+    int t1 = imu_i2c_port.write(SLAVE_ADDR_WRITE, &addr,  1, true);
+    int t2 = imu_i2c_port.read( SLAVE_ADDR_READ,  buffer, 1, false);
+}
+
+inline void imu_i2c_read(const char addr, char* buffer, const int length)
+{
+    int t1 = imu_i2c_port.write(SLAVE_ADDR_WRITE, &addr,  1, true);
+    int t2 = imu_i2c_port.read( SLAVE_ADDR_READ,  buffer, length, false);
+}
+
+uint8_t imu_manager_init()
+{
+    accel_value.x = accel_value.y = accel_value.z = 0;
+    velocity_value.x = velocity_value.y = velocity_value.z = 0;
+    position_value.x = position_value.y = position_value.z = 0;
+    
+    char dataBuf = 0;
+    imu_i2c_read_8bit(FXOS8700CQ_WHOAMI, &dataBuf);
+    if(dataBuf != FXOS8700CQ_WHOAMI_VAL)
+    {
+        return dataBuf;
+    }
+    //standby
+    dataBuf = 0x00;
+    imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG1, &dataBuf);
+    //reset
+    dataBuf = FXOS8700CQ_RESET_MASK;
+    imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG2, &dataBuf);
+    wait(0.5);
+    //standby
+    dataBuf = 0x00;
+    imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG1, &dataBuf);
+    
+    dataBuf = 0x09;
+    imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG2, &dataBuf);
+    dataBuf = 0x00;
+    imu_i2c_write_8bit(FXOS8700CQ_F_SETUP, &dataBuf);
+    dataBuf = 0x00; //0x1F;
+    imu_i2c_write_8bit(FXOS8700CQ_M_CTRL_REG1, &dataBuf);
+    dataBuf = 0x00; //0x20;
+    imu_i2c_write_8bit(FXOS8700CQ_M_CTRL_REG2, &dataBuf);
+    dataBuf = FXOS8700CQ_XYZ_DATA_SC;
+    imu_i2c_write_8bit(FXOS8700CQ_XYZ_DATA_CFG, &dataBuf);
+    dataBuf = 0x10;
+    imu_i2c_write_8bit(FXOS8700CQ_HP_FILTER_CUTOFF, &dataBuf);
+    dataBuf = FXOS8700CQ_CTRL_REG1_v;
+    imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG1, &dataBuf);
+    
+    return FXOS8700CQ_WHOAMI_VAL;
+}
+
+void imu_manager_calibrate()
+{
+    
+    static const int calibrate_sample_num = 1.0f / IMU_UPDATE_TICK_RATE;
+    
+    int16_t temp = 0;
+    for(int k = 0; k < 2; ++k)
+    {
+        double avgX = 0.0;
+        double avgY = 0.0;
+        for(int i = 0; i < calibrate_sample_num; ++i)
+        {
+            imu_data_buffer[0] = 0x00;
+            while(!(imu_data_buffer[0] & 0x0F))
+            {
+                imu_i2c_read(FXOS8700CQ_STATUS, imu_data_buffer, FXOS8700CQ_READ_LEN);
+            }
+            
+            temp = ((((imu_data_buffer[1] << 8) | imu_data_buffer[2])) >> 2);
+            if(temp & 0x2000)
+            {
+                temp = -1 * ((~(temp | 0xC000)) + 1);
+                
+            }
+            avgX += (static_cast<double>(temp) * ACCELER_SCALE_F_MG);
+            
+            temp = ((((imu_data_buffer[3] << 8) | imu_data_buffer[4])) >> 2);
+            if(temp & 0x2000)
+            {
+                temp = -1 * ((~(temp | 0xC000)) + 1);
+            }
+            avgY += (static_cast<double>(temp) * ACCELER_SCALE_F_MG);
+            wait(IMU_UPDATE_TICK_RATE);
+        }
+        //Standby mode
+        //char dataBuf = 0x00;
+        //imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG1, &dataBuf);
+        avgX = avgX / calibrate_sample_num;
+        avgY = avgY / calibrate_sample_num;
+        if(k == 0)
+        {
+            accel_offset.x = static_cast<float>(avgX * 0.001);
+            accel_offset.y = static_cast<float>(avgY * 0.001);
+        }
+        else
+        {
+            accel_offset.x = (accel_offset.x + static_cast<float>(avgX * 0.001)) / 2.0f;
+            accel_offset.y = (accel_offset.y + static_cast<float>(avgY * 0.001)) / 2.0f;
+        }
+    }
+    
+    accel_offset.z = 0;
+    /*
+    dataBuf = static_cast<char>((abs(avgX)) / OFFSET_SCALE_F);
+    if(avgX > 0)
+    {
+        dataBuf = (~dataBuf) + 1;
+    }
+    //imu_i2c_write_8bit(FXOS8700CQ_OFF_X, &dataBuf);
+    //LOGI("I: %5.3f, %d  ", avgX, dataBuf);
+    //wait(5.0f);
+    
+    dataBuf = static_cast<char>((abs(avgY)) / OFFSET_SCALE_F);
+    if(avgY > 0)
+    {
+        dataBuf = (~dataBuf) + 1;
+    }
+    //imu_i2c_write_8bit(FXOS8700CQ_OFF_Y, &dataBuf);
+    */
+    //Avtive mode.
+    //dataBuf = FXOS8700CQ_CTRL_REG1_v;
+    //imu_i2c_write_8bit(FXOS8700CQ_CTRL_REG1, &dataBuf);
+}
+
+void imu_manager_begin_tick()
+{
+    m_imu_update_prev_time = 0.0f;
+    m_imu_update_tick.attach(&imu_manager_update, IMU_UPDATE_TICK_RATE);
+    m_imu_update_timer.start();
+}
+
+void imu_manager_update()
+{
+    imu_i2c_read(FXOS8700CQ_STATUS, imu_data_buffer, FXOS8700CQ_READ_LEN);
+    
+    if(!(imu_data_buffer[0] & 0x0F))
+    {
+        return;
+    }
+    
+    float currentTime = m_imu_update_timer.read();
+    float deltaTime = currentTime - m_imu_update_prev_time;
+    m_imu_update_prev_time = currentTime;
+    
+    
+    // copy the 14 bit accelerometer byte data into 16 bit words
+    static int16_t temp = 0;
+    temp = ((((imu_data_buffer[1] << 8) | imu_data_buffer[2])) >> 2);
+    if(temp & 0x2000)
+    {
+        temp = -1 * ((~(temp | 0xC000)) + 1);
+    }
+    accel_value.x = (static_cast<float>(temp) * ACCELER_SCALE_F_G) - accel_offset.x;
+    //accel_value.x = KEEP_TWO_DECIMAL(accel_value.x);
+    
+    temp = ((((imu_data_buffer[3] << 8) | imu_data_buffer[4])) >> 2);
+    if(temp & 0x2000)
+    {
+        temp = -1 * ((~(temp | 0xC000)) + 1);
+    }
+    accel_value.y = (static_cast<float>(temp) * ACCELER_SCALE_F_G) - accel_offset.y;
+    //accel_value.y = KEEP_TWO_DECIMAL(accel_value.y);
+    
+    temp = ((((imu_data_buffer[5] << 8) | imu_data_buffer[6])) >> 2);
+    if(temp & 0x2000)
+    {
+        temp = -1 * ((~(temp | 0xC000)) + 1);
+    }
+    accel_value.z = (static_cast<float>(temp) * ACCELER_SCALE_F_G) - accel_offset.z;
+    //accel_value.z = KEEP_TWO_DECIMAL(accel_value.z);
+    /*
+    // copy the magnetometer byte data into 16 bit words
+    magt_value.x = (((imu_data_buffer[7]) << 8) | imu_data_buffer[8]);
+    magt_value.y = (((imu_data_buffer[9]) << 8) | imu_data_buffer[10]);
+    magt_value.z = (((imu_data_buffer[11]) << 8) | imu_data_buffer[12]);
+    */
+    
+    velocity_value.x = velocity_value.x + (accel_value.x * IMU_DEFAULT_G * deltaTime);
+    velocity_value.y = velocity_value.y + (accel_value.y * IMU_DEFAULT_G * deltaTime);
+    
+    position_value.x = position_value.x + (velocity_value.x * deltaTime);
+    position_value.y = position_value.y + (velocity_value.y * deltaTime);
+    
+    char dataBuf = 0;
+    imu_i2c_read_8bit(FXOS8700CQ_TEMP, &dataBuf);
+    imu_temp = (dataBuf & 0x80) ? (~dataBuf + 1) : dataBuf;
+    
+    counter.Update();
+}
+
+const volatile struct imu_vec3* imu_manager_get_accl()
+{
+    return &accel_value;
+}
+/*
+const volatile struct imu_vec3* imu_manager_get_magt()
+{
+    return &magt_value;
+}
+*/
+
+const volatile struct imu_vec3* imu_manager_get_velocity()
+{
+    return &velocity_value;
+}
+
+const volatile struct imu_vec3* imu_manager_get_position()
+{
+    return &position_value;
+}
+
+float imu_manager_get_temp()
+{
+    return static_cast<float>(imu_temp) * 0.96f;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //if 0
\ No newline at end of file