Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SPI.h>
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- /*************************************************************************
- DECLARE MAIN
- */
- #define OLED_RESET 4
- Adafruit_SSD1306 display(OLED_RESET);
- Adafruit_SSD1306 display2(OLED_RESET);
- #define XPOS 0
- #define YPOS 1
- #define DELTAY 2
- #define LOGO16_GLCD_HEIGHT 16
- #define LOGO16_GLCD_WIDTH 16
- static const unsigned char PROGMEM logo16_glcd_bmp[] =
- { B00000000, B00000100,
- B00000000, B00011000,
- B00000000, B01110000,
- B00000001, B11100000,
- B00000011, B11000000,
- B00000111, B10000000,
- B00000111, B10000000,
- B00000011, B11000000,
- B00011111, B11111000,
- B00001111, B11111000,
- B00000001, B11100000,
- B00000011, B11000000,
- B00000111, B10000000,
- B00011110, B00000000,
- B01110000, B00000000,
- B00000000, B00000000
- };
- #if (SSD1306_LCDHEIGHT != 64)
- #error("Height incorrect");
- #endif
- int incomingByte = 0;
- byte menu = 0;
- byte menuSelect = 0;
- #define menuOffset 16
- bool dispVR = true;
- float eyeSocket[4];
- float eyeDirection[4];
- float eyeUp[4];
- float worldMat[16];
- float worldMat2[16];
- float rollMat[16];
- float rollMat2[16];
- float tmpMat[16];
- float clipWidth = 2.0; //change that to zoom
- float clipHeight = 1.0;
- /*float halfClipWidth = clipWidth / 2.0;
- float halfClipHeight = clipHeight / 2.0;*/
- float Plocal[4];
- float Pworld[4];
- float Pcamera[4];
- float Pscreen[4];
- float Pnds[2];
- byte Ppix[2];
- int timeOffset;
- int startOffset;
- float pitch = 0.0;
- float yaw = 0.0;
- float roll = 0.0;
- bool didOnce = false;
- bool showKeyb = false;
- bool showDebug = false;
- /******************************************************************************
- DECLARE IMU
- */
- // "MPU-9150 Register Map and Descriptions Revision 4.0",
- #define MPU9150_SELF_TEST_X 0x0D // R/W
- #define MPU9150_SELF_TEST_Y 0x0E // R/W
- #define MPU9150_SELF_TEST_X 0x0F // R/W
- #define MPU9150_SELF_TEST_A 0x10 // R/W
- #define MPU9150_SMPLRT_DIV 0x19 // R/W
- #define MPU9150_CONFIG 0x1A // R/W
- #define MPU9150_GYRO_CONFIG 0x1B // R/W
- #define MPU9150_ACCEL_CONFIG 0x1C // R/W
- #define MPU9150_FF_THR 0x1D // R/W
- #define MPU9150_FF_DUR 0x1E // R/W
- #define MPU9150_MOT_THR 0x1F // R/W
- #define MPU9150_MOT_DUR 0x20 // R/W
- #define MPU9150_ZRMOT_THR 0x21 // R/W
- #define MPU9150_ZRMOT_DUR 0x22 // R/W
- #define MPU9150_FIFO_EN 0x23 // R/W
- #define MPU9150_I2C_MST_CTRL 0x24 // R/W
- #define MPU9150_I2C_SLV0_ADDR 0x25 // R/W
- #define MPU9150_I2C_SLV0_REG 0x26 // R/W
- #define MPU9150_I2C_SLV0_CTRL 0x27 // R/W
- #define MPU9150_I2C_SLV1_ADDR 0x28 // R/W
- #define MPU9150_I2C_SLV1_REG 0x29 // R/W
- #define MPU9150_I2C_SLV1_CTRL 0x2A // R/W
- #define MPU9150_I2C_SLV2_ADDR 0x2B // R/W
- #define MPU9150_I2C_SLV2_REG 0x2C // R/W
- #define MPU9150_I2C_SLV2_CTRL 0x2D // R/W
- #define MPU9150_I2C_SLV3_ADDR 0x2E // R/W
- #define MPU9150_I2C_SLV3_REG 0x2F // R/W
- #define MPU9150_I2C_SLV3_CTRL 0x30 // R/W
- #define MPU9150_I2C_SLV4_ADDR 0x31 // R/W
- #define MPU9150_I2C_SLV4_REG 0x32 // R/W
- #define MPU9150_I2C_SLV4_DO 0x33 // R/W
- #define MPU9150_I2C_SLV4_CTRL 0x34 // R/W
- #define MPU9150_I2C_SLV4_DI 0x35 // R
- #define MPU9150_I2C_MST_STATUS 0x36 // R
- #define MPU9150_INT_PIN_CFG 0x37 // R/W
- #define MPU9150_INT_ENABLE 0x38 // R/W
- #define MPU9150_INT_STATUS 0x3A // R
- #define MPU9150_ACCEL_XOUT_H 0x3B // R
- #define MPU9150_ACCEL_XOUT_L 0x3C // R
- #define MPU9150_ACCEL_YOUT_H 0x3D // R
- #define MPU9150_ACCEL_YOUT_L 0x3E // R
- #define MPU9150_ACCEL_ZOUT_H 0x3F // R
- #define MPU9150_ACCEL_ZOUT_L 0x40 // R
- #define MPU9150_TEMP_OUT_H 0x41 // R
- #define MPU9150_TEMP_OUT_L 0x42 // R
- #define MPU9150_GYRO_XOUT_H 0x43 // R
- #define MPU9150_GYRO_XOUT_L 0x44 // R
- #define MPU9150_GYRO_YOUT_H 0x45 // R
- #define MPU9150_GYRO_YOUT_L 0x46 // R
- #define MPU9150_GYRO_ZOUT_H 0x47 // R
- #define MPU9150_GYRO_ZOUT_L 0x48 // R
- #define MPU9150_EXT_SENS_DATA_00 0x49 // R
- #define MPU9150_EXT_SENS_DATA_01 0x4A // R
- #define MPU9150_EXT_SENS_DATA_02 0x4B // R
- #define MPU9150_EXT_SENS_DATA_03 0x4C // R
- #define MPU9150_EXT_SENS_DATA_04 0x4D // R
- #define MPU9150_EXT_SENS_DATA_05 0x4E // R
- #define MPU9150_EXT_SENS_DATA_06 0x4F // R
- #define MPU9150_EXT_SENS_DATA_07 0x50 // R
- #define MPU9150_EXT_SENS_DATA_08 0x51 // R
- #define MPU9150_EXT_SENS_DATA_09 0x52 // R
- #define MPU9150_EXT_SENS_DATA_10 0x53 // R
- #define MPU9150_EXT_SENS_DATA_11 0x54 // R
- #define MPU9150_EXT_SENS_DATA_12 0x55 // R
- #define MPU9150_EXT_SENS_DATA_13 0x56 // R
- #define MPU9150_EXT_SENS_DATA_14 0x57 // R
- #define MPU9150_EXT_SENS_DATA_15 0x58 // R
- #define MPU9150_EXT_SENS_DATA_16 0x59 // R
- #define MPU9150_EXT_SENS_DATA_17 0x5A // R
- #define MPU9150_EXT_SENS_DATA_18 0x5B // R
- #define MPU9150_EXT_SENS_DATA_19 0x5C // R
- #define MPU9150_EXT_SENS_DATA_20 0x5D // R
- #define MPU9150_EXT_SENS_DATA_21 0x5E // R
- #define MPU9150_EXT_SENS_DATA_22 0x5F // R
- #define MPU9150_EXT_SENS_DATA_23 0x60 // R
- #define MPU9150_MOT_DETECT_STATUS 0x61 // R
- #define MPU9150_I2C_SLV0_DO 0x63 // R/W
- #define MPU9150_I2C_SLV1_DO 0x64 // R/W
- #define MPU9150_I2C_SLV2_DO 0x65 // R/W
- #define MPU9150_I2C_SLV3_DO 0x66 // R/W
- #define MPU9150_I2C_MST_DELAY_CTRL 0x67 // R/W
- #define MPU9150_SIGNAL_PATH_RESET 0x68 // R/W
- #define MPU9150_MOT_DETECT_CTRL 0x69 // R/W
- #define MPU9150_USER_CTRL 0x6A // R/W
- #define MPU9150_PWR_MGMT_1 0x6B // R/W
- #define MPU9150_PWR_MGMT_2 0x6C // R/W
- #define MPU9150_FIFO_COUNTH 0x72 // R/W
- #define MPU9150_FIFO_COUNTL 0x73 // R/W
- #define MPU9150_FIFO_R_W 0x74 // R/W
- #define MPU9150_WHO_AM_I 0x75 // R
- //MPU9150 Compass
- #define MPU9150_CMPS_XOUT_L 0x4A // R
- #define MPU9150_CMPS_XOUT_H 0x4B // R
- #define MPU9150_CMPS_YOUT_L 0x4C // R
- #define MPU9150_CMPS_YOUT_H 0x4D // R
- #define MPU9150_CMPS_ZOUT_L 0x4E // R
- #define MPU9150_CMPS_ZOUT_H 0x4F // R
- // I2C address 0x69 could be 0x68 depends on your wiring.
- int MPU9150_I2C_ADDRESS = 0x69;
- //Variables where our values can be stored
- int cmps[3];
- int accl[3];
- int gyro[3];
- int temp;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////SETUP
- /***
- FUNCTIONS MAIN
- */
- void setup() {
- Serial.begin(115200);
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
- display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
- display.clearDisplay();
- display2.clearDisplay();
- display2.display();
- int i, j;
- for (i = 0; i < 4; ++i)
- for (j = 0; j < 4; ++j)
- if (i == j) worldMat[i] = rollMat[i] = rollMat2[i] = tmpMat[i] = 1;
- else worldMat[i] = rollMat[i] = rollMat2[i] = tmpMat[i] = 0;
- //worldMat[0] = worldMat[4 + 1] = worldMat[8 + 2] = worldMat[12 + 3] = 1; //Identity world
- eyeSocket[0] = 0.0;
- eyeSocket[1] = -1.8;
- eyeSocket[2] = 0.0;
- eyeSocket[3] = 1.0;
- eyeDirection[0] = 0.0;
- eyeDirection[1] = 0.0;
- eyeDirection[2] = -1.0;
- eyeDirection[3] = 1.0;
- eyeUp[0] = 0; eyeUp[2] = 0;
- eyeUp[1] = 1; eyeUp[3] = 1;
- /*
- float ca = cos(yaw);
- float cb = cos(roll);
- float cy = cos(pitch); //camera relative pitch/yaw/roll
- float sa = sin(yaw);
- float sb = sin(roll);
- float sy = sin(pitch);
- rollMat[0] = ca * cb;
- rollMat[1] = ca * sb * sy - sa * cy;
- rollMat[2] = ca * sb * cy + sa * sy;
- rollMat[3] = 0;
- rollMat[4] = sa * cb;
- rollMat[5] = sa * sb * sy + ca * cy;
- rollMat[6] = sa * sb * cy - ca * sy;
- rollMat[7] = 0;
- rollMat[8] = -sb;
- rollMat[9] = cb * sy;
- rollMat[10] = cb * cy;
- rollMat[11] = 0;
- rollMat[12] = rollMat[13] = rollMat[14] = 0;
- rollMat[15] = 1;*/
- /////OTHER SETUP
- setupIMU();
- startOffset = millis();
- Serial.println(F("Setup."));
- displayMenu(0);
- }
- void displayMenu(int menuID) {
- display.clearDisplay();
- display.setTextSize(1);
- display.setTextColor(BLACK, WHITE);
- display.setCursor(0, 0);
- //display.display();
- switch (menuID) {
- case 0: display.println(F(" freecomm OS "));
- break;
- case 1: display.println(F(" VR Metaverse "));
- break; // hide menu in metaverse
- case 2: display.println(F(" Messenger "));
- break;
- case 3: display.println(F(" Music "));
- break;
- case 4: display.println(F(" Other "));
- break;
- case 5: display.println(F(" Settings "));
- break;
- case 6: display.println(F(" Apps "));
- break;
- default: display.println(F(" freecomm OS "));
- break;
- }
- display.println(F("wat"));
- display.setTextColor(WHITE);
- displayMenuItems(menuID);
- display.setCursor(0, menuOffset + menuSelect * 8);
- display.print("*");
- display.drawBitmap(100, 10, logo16_glcd_bmp, 16, 16, 1);
- }
- void displayMenuItems(int menuID) {
- switch (menuID) {
- case 0: //Main menu
- display.println(F(" VR Metaverse"));
- display.println(F(" Messenger"));
- display.println(F(" Music"));
- display.println(F(" Other"));
- display.println(F(" Settings"));
- break;
- case 1: //Metaverse menu
- display.println(F(" Summon Object"));
- display.println(F(" Invite Peer"));
- display.println(F(" Teleport"));
- display.println(F(" Settings"));
- display.println(F(" Exit"));
- break; // no header in metaverse
- case 2: //Messenger menu
- display.println(F(" New (0)"));
- display.println(F(" Send"));
- display.println(F(" Inbox"));
- display.println(F(" Outbox"));
- display.println(F(" Exit"));
- break;
- case 3: //Music menu
- display.println(F(" Listen"));
- display.println(F(" Play"));
- display.println(F(" Exit"));
- break;
- case 4: //Other menu
- display.println(F(" Wiki "));
- display.println(F(" Apps "));
- display.println(F(" Files "));
- display.println(F(" Stream "));
- display.println(F(" Exit "));
- break;
- case 5: //Settings menu
- display.println(F(" General "));
- display.println(F(" Display "));
- display.println(F(" Memory "));
- display.println(F(" Network "));
- display.println(F(" Reset "));
- display.println(F(" Exit "));
- break;
- case 6: //Apps menu
- //Here we should load Apps from memory
- display.println(F(" Learn Chinese "));
- break;
- default: display.println(F(" Exit ")); //go to Main
- break;
- }
- }
- void loop() {
- if (Serial.available() > 0) {
- // read the incoming byte:
- incomingByte = Serial.read();
- while (incomingByte != -1) {
- // say what you got:
- Serial.println(incomingByte, DEC);
- //display.write(incomingByte);
- if (incomingByte == '1')
- menu = 1;
- switch (incomingByte) {
- case 'j': menuSelect++; if (menuSelect > 6) menuSelect = 0; break; //up button
- case 'h': menuSelect--; if (menuSelect == -1) menuSelect = 0; break; //down button
- case 'g': select(menuSelect); break; //select button
- case 'e': dispVR = false; menu = 0; menuSelect = 0; break; //home button
- case 'r': goRoll(-0.1); break;
- case 't': goRoll(0.1); break;
- case 'x': goYaw(-0.1); break; ////yaw -= 0.1; break;
- case 'c': goYaw(0.1); break;
- case 'f': goPitch(-0.1); break;
- case 'v': goPitch(0.1); break;
- /*case 'r': roll -= 0.1; break;
- case 't': roll += 0.1; break;
- case 'd': yaw -= 0.1; break; ////yaw -= 0.1; break;
- case 'c': yaw += 0.1; break;
- case 'f': pitch -= 0.1; break;
- case 'v': pitch += 0.1; break;*/
- case 'z': goForward(1.0); break;
- case 's': goBackward(1.0); break;
- case 'q': goLeft(1.0); break;
- case 'd': goRight(1.0); break;
- case '5': eyeSocket[0] = eyeSocket[2] = 0; eyeSocket[1] = -1.8; yaw = pitch = roll = 0; break;
- case '8': /*eyeSocket[2]--; */ goForward(1); break;
- case '2': eyeSocket[2]++; break;
- case '4': eyeSocket[0]++; break;
- case '6': eyeSocket[0]--; break;
- case 'k': showKeyb = !showKeyb; break;
- case 'i': displayStream(); break; //serial stream to display --sends what comes after i, until newline
- default: break; // store input for processing
- }
- incomingByte = Serial.read();
- }
- }
- readGyroYaw();
- readAccelPitch();
- readAccelRoll();
- if (dispVR)
- displayVR();
- else
- displayMenu(menu);
- if (showKeyb)
- displayKeyb();
- display.display();
- display2.display();
- //OTHER LOOP
- if (false)
- loopIMU();
- delay(30);
- }
- void readAccelPitch() {
- //double accelX = MPU9150_readSensor(MPU9150_ACCEL_XOUT_L, MPU9150_ACCEL_XOUT_H);
- //double accelY = MPU9150_readSensor(MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H);
- double accelZ = MPU9150_readSensor(MPU9150_ACCEL_ZOUT_L, MPU9150_ACCEL_ZOUT_H);
- //de z = 15000 (bas) Ã z = -15000 (haut), soit en radian -pi/2 Ã pi/2
- //map(
- double pitchRad = accelZ / 10000.0;
- if (pitchRad < -1.57) pitchRad = -1.57;
- if (pitchRad > 1.57) pitchRad = 1.57;
- goPitchAbsolute(-pitchRad);
- if (showDebug) {
- Serial.print("Pitch: ");
- Serial.println(pitchRad);
- }
- //pitch = pitchRad;
- }
- void readAccelRoll() {
- //double accelX = MPU9150_readSensor(MPU9150_ACCEL_XOUT_L, MPU9150_ACCEL_XOUT_H);
- //double accelY = MPU9150_readSensor(MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H);
- double accelY = MPU9150_readSensor(MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H);
- //de z = 15000 (bas) Ã z = -15000 (haut), soit en radian -pi/2 Ã pi/2
- //map(
- double rollRad = accelY / 10000.0;
- if (rollRad < -1.57) rollRad = -1.57;
- if (rollRad > 1.57) rollRad = 1.57;
- goRollAbsolute(rollRad);
- if (showDebug) {
- Serial.print("Roll: ");
- Serial.println(rollRad);
- }
- //roll = rollRad;
- }
- void readGyroYaw() {
- double gyroX = MPU9150_readSensor(MPU9150_GYRO_XOUT_L, MPU9150_GYRO_XOUT_H);
- double gyroY = MPU9150_readSensor(MPU9150_GYRO_YOUT_L, MPU9150_GYRO_YOUT_L);
- double gyroZ = MPU9150_readSensor(MPU9150_GYRO_ZOUT_L, MPU9150_GYRO_ZOUT_H);
- Serial.print("Gyro: "); Serial.print(gyroX); Serial.print("/"); Serial.print(gyroY);Serial.print("/");Serial.println(gyroZ);
- float gyroToYaw;
- gyroToYaw = gyroX / 15000;
- //Donc il faut simplement réduire gyroToYaw en fonction de roll, et ça serait un bon début
- gyroToYaw = gyroToYaw * cos(roll);
- gyroToYaw = -gyroToYaw;
- gyroToYaw += yaw;
- Serial.print("GyroToYaw: "); Serial.println(gyroToYaw);
- goYawAbsolute(-gyroToYaw);
- }
- /*void printtab(char* text) {
- Serial.print
- }*/
- void displayStream() {
- bool goOn = true;
- byte streamByte;
- Serial.println(F("displaying stream"));
- display.clearDisplay();
- int i;
- int pixelPos = 0;
- int maxPixelPos = 128 * 64 + 127; //todo: selon taille de l'écran
- /*Serial.end();
- delay(5000);
- Serial.begin(115200);*/
- while (goOn) {
- if (goOn && Serial.available() > 0) {
- // read the incoming byte:
- incomingByte = (int) (streamByte = Serial.read());
- /*Serial.print(F("stream read "));
- Serial.println(streamByte);*/
- if (streamByte == 111)
- goOn = false;
- while (goOn && streamByte != -1 && streamByte != 255) {
- for (i = 0; i < 8; ++i) {
- display.drawPixel(pixelPos % 128, pixelPos / 128, (streamByte & (128 >> i)) ? WHITE : BLACK); //todo: replace 128 with display width
- //todo: diviser selon taille de l'écran
- ++pixelPos;
- if (pixelPos > maxPixelPos) pixelPos = 0;
- }
- incomingByte = (int) (streamByte = Serial.read());
- }
- }
- display.display();
- delay(100);
- }
- incomingByte = -1;
- //Serial.end();
- //Serial.begin(9600);
- }
- void displayApps() {
- }
- /*
- void downloadStream(int dlAddr, int dlSize) {
- }
- void uploadStream(int ulAddr, int ulSize) {
- }
- */
- void displayKeyb() {
- display.setCursor(0, 10);
- display.println(F("buffer"));
- display.println();
- display.println(F("1 2 3 4 5 6 7 8 9 0"));
- display.println(F("q w e r t y u i o p"));
- display.println(F("a s d f g h j k l ."));
- display.println(F("z x c v b n m ; : !"));
- }
- void select(int menuSel) {
- switch (menu) {
- case 0:
- switch (menuSel) {
- case 0: dispVR = true; menu = 1; menuSelect = 0; break; //go metaverse
- case 1: menu = 2; menuSelect = 0; break; //Messenger
- case 2: menu = 3; menuSelect = 0; break; //Music
- case 3: menu = 4; menuSelect = 0; break; //Other
- case 4: menu = 5; menuSelect = 0; break; //Settings
- default: break;
- } break;
- case 1: //VR
- switch (menuSel) {
- case 4: menu = 0; menuSelect = 0; break;
- default: break;
- } break;
- case 2:
- switch (menuSel) {
- case 4: menu = 0; menuSelect = 0; break;
- default: break;
- } break;
- case 3:
- switch (menuSel) {
- case 2: menu = 0; menuSelect = 0; break;
- default: break;
- } break;
- case 4:
- switch (menuSel) {
- case 1: menu = 6; menuSelect = 0; break; //throw event here? //Apps
- case 3: displayStream(); break; //serial stream to display --sends what comes until user presses o
- case 4: menu = 0; menuSelect = 0; break;
- default: break;
- } break;
- case 5:
- switch (menuSel) {
- case 5: menu = 0; menuSelect = 0; break;
- default: break;
- } break;
- case 6:
- /*switch (menuSel) {
- Here we should have loaded the list of App IDs, and depending on menuSel, launch the corresponding app dynamically
- }*/
- switch (menuSel) {
- case 0: learnChineseApp(); break;
- }
- break;
- default:
- menu = 0; menuSelect = 0; break;
- }
- }
- void goForward(float speed) {
- int i;
- for (i = 0; i < 3; ++i)
- eyeSocket[i] += eyeDirection[i] * speed;
- }
- void goBackward(float speed) {
- int i;
- for (i = 0; i < 3; ++i)
- eyeSocket[i] -= eyeDirection[i] * speed;
- }
- void goLeft(float speed) {
- int i;
- float camDir[4];
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- for (i = 0; i < 3; ++i)
- eyeSocket[i] += camDir[i] * speed;
- }
- void goRight(float speed) {
- int i;
- float camDir[4];
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- for (i = 0; i < 3; ++i)
- eyeSocket[i] -= camDir[i] * speed;
- }
- void goYaw(float ang) {
- int i;
- float camDir[4];
- for (i = 0; i < 4; ++i) camDir[i] = eyeDirection[i];
- transformFromAxisAngle(tmpMat, eyeUp, ang);
- multiplication(tmpMat, camDir, eyeDirection, 4, 4, 4, 1);
- // maybe null &ang
- }
- void goRoll(float ang) {
- int i;
- float camDir[4];
- for (i = 0; i < 4; ++i) camDir[i] = eyeUp[i];
- transformFromAxisAngle(tmpMat, eyeDirection, ang);
- multiplication(tmpMat, camDir, eyeUp, 4, 4, 4, 1);
- roll += ang;
- }
- //this is not the pitch I want, but it is good to use for Gyro X
- void goPitch(float ang) {
- int i;
- float camDir[4];
- //for (i = 0; i < 4; ++i) camDir[i] = eyeDirection[i];
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- camDir[3] = 1;
- normalize3(camDir);
- transformFromAxisAngle(tmpMat, camDir, ang);
- for (i = 0; i < 4; ++i) camDir[i] = eyeDirection[i];
- multiplication(tmpMat, camDir, eyeDirection, 4, 4, 4, 1);
- //normalize3(eyeDirection);
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- camDir[3] = 1;
- normalize3(camDir);
- transformFromAxisAngle(tmpMat, camDir, ang);
- for (i = 0; i < 4; ++i) camDir[i] = eyeUp[i];
- multiplication(tmpMat, camDir, eyeUp, 4, 4, 4, 1);
- //normalize3(eyeUp);
- /*for (i = 0; i < 4; ++i) camDir[i] = eyeUp[i];
- multiplication(tmpMat, camDir, eyeUp, 4, 4, 4, 1);*/
- //Full Pitch; disable for different effect with fixed eyeup
- /*
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- camDir[3] = 1;
- normalize3(camDir);
- transformFromAxisAngle(tmpMat, camDir, ang);
- for (i = 0; i < 4; ++i) camDir[i] = eyeUp[i];
- multiplication(tmpMat, camDir, eyeUp, 4, 4, 4, 1);*/
- pitch += ang;
- }
- //void goPitchSimple(angle
- void goPitchAbsolute(float ang) {
- //What the fuck.
- /*
- int i;
- float camDir[4];
- //for (i = 0; i < 4; ++i) camDir[i] = eyeDirection[i];
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- camDir[3] = 1;
- normalize3(camDir);
- transformFromAxisAngle(tmpMat, camDir, ang);
- for (i = 0; i < 4; ++i) camDir[i] = eyeDirection[i];
- multiplication(tmpMat, camDir, eyeDirection, 4, 4, 4, 1);
- //normalize3(eyeDirection);
- Vector_Cross_Product(camDir, eyeUp, eyeDirection);
- camDir[3] = 1;
- normalize3(camDir);
- transformFromAxisAngle(tmpMat, camDir, ang);
- for (i = 0; i < 4; ++i) camDir[i] = eyeUp[i];
- multiplication(tmpMat, camDir, eyeUp, 4, 4, 4, 1);
- */
- //WTF- On va juste enlever le dernier pitch, et remettre le nouveau
- goPitch(-pitch);
- goPitch(ang);
- }
- void goRollAbsolute(float ang) {
- //What the fuck.
- goRoll(-roll);
- goRoll(ang);
- }
- void goYawAbsolute(float ang) {
- //What the fuck.
- goYaw(-yaw);
- goYaw(ang);
- }
- void displayVR() {
- display.clearDisplay();
- display2.clearDisplay();
- int i, j;
- /*worldMat[0] = cos(pitch);
- worldMat[2] = sin(pitch);
- worldMat[8] = -sin(pitch);
- worldMat[10] = cos(pitch);*/
- for (i = 0; i < 4; ++i)
- for (j = 0; j < 4; ++j)
- if (i == j) tmpMat[i * 4 + j] = 1;
- else tmpMat[i * 4 + j] = 0;
- /*tmpMat[3] = -eyeSocket[0];
- tmpMat[7] = -eyeSocket[1];
- tmpMat[11] = -eyeSocket[2];
- tmpMat[15] = 1;*/
- //We should compute eyeDir here out of roll/pitch/yaw, and use that as rollMat
- //order is roll pitch yaw, or reverse
- //roll should create eyeUp, and yaw/pitch should create eyeDir. Yaw first, then pitch, to the eyeDir vector, with transformFromAng
- //void transformFromAxisAngle(float vecOut[], float v[], float a) {
- float newEyeUp[4];
- for (i = 0; i < 4; ++i) newEyeUp[4] = eyeUp[4];
- //cela depend de eyeDir. On était sur l'axe Z, mais on va tourner dans X/Y au sacrifice de Z.
- //First eye
- float eyeDir[4];
- for (i = 0; i < 4; ++i) {
- eyeDir[i] = eyeSocket[i] + eyeDirection[i]; //* //speed
- }
- createLookAt(eyeSocket, eyeDir, eyeUp, rollMat);
- //Second eye
- float eyeRight[4];
- Vector_Cross_Product(eyeRight, eyeDirection, eyeUp); //should be eyeDirection, not eyeDir, as eyeDir isn't even unitary
- //matrixScalarMult(eyeRight, 3, 3.0); //eye separation
- eyeRight[4] = 1.0;
- float eyeDir2[4];
- for (i = 0; i < 4; ++i)
- eyeDir2[i] = eyeDir[i] + eyeRight[i];
- for (i = 0; i < 4; ++i)
- eyeRight[i] += eyeSocket[i];
- createLookAt(eyeRight/*todo: * eyeSeparation*/, eyeDir2, eyeUp, rollMat2);
- //createLookAt(tmpMat, eyeDir, eyeUp, rollMat);
- /*
- float ca = cos(roll);
- float sa = sin(roll);
- float cy = cos(pitch); //camera relative pitch/yaw/roll
- float sy = sin(pitch); //on a inversé pitch et yaw
- float cb = cos(yaw);
- float sb = sin(yaw);
- rollMat[0] = ca * cb;
- rollMat[1] = ca * sb * sy - sa * cy;
- rollMat[2] = ca * sb * cy + sa * sy;
- rollMat[3] = 0;
- rollMat[4] = sa * cb;
- rollMat[5] = sa * sb * sy + ca * cy;
- rollMat[6] = sa * sb * cy - ca * sy;
- rollMat[7] = 0;
- rollMat[8] = -sb;
- rollMat[9] = cb * sy;
- rollMat[10] = cb * cy;
- rollMat[11] = 0;
- rollMat[12] = rollMat[13] = rollMat[14] = 0;
- rollMat[15] = 1; 5h du mat' last change*/
- tmpMat[3] = -eyeSocket[0];
- tmpMat[7] = -eyeSocket[1];
- tmpMat[11] = -eyeSocket[2];
- tmpMat[15] = 1;
- multiplication(rollMat, tmpMat, worldMat, 4, 4, 4, 4);
- tmpMat[3] = -eyeRight[0];
- tmpMat[7] = -eyeRight[1];
- tmpMat[11] = -eyeRight[2];
- tmpMat[15] = 1;
- multiplication(rollMat, tmpMat, worldMat2, 4, 4, 4, 4);
- /*for (i = 0; i < 16; ++i)
- worldMat[i] = tmpMat[i];*/
- //transform tmpMat en camMat
- for (i = 0; i < 4; ++i)
- for (j = 0; j < 4; ++j)
- if (i == j) tmpMat[i * 4 + j] = 1;
- else tmpMat[i * 4 + j] = 0;
- /*tmpMat[3] = 0;
- tmpMat[7] = 0;
- tmpMat[11] = 0;
- tmpMat[10] = -1;*/
- timeOffset = (millis() - startOffset) / 100;
- for (i = 0; i < 10; ++i) {
- for (j = 0; j < 20; ++j) {
- Plocal[0] = -5.0 + i;
- Plocal[1] = 1;
- Plocal[2] = 10.0 - j;// - timeOffset;
- Plocal[3] = 1.0;
- if (computePix()) {
- display.drawPixel(Ppix[0], Ppix[1], WHITE);
- if (computePix2()) {
- display2.drawPixel(Ppix[0], Ppix[1], WHITE);
- }
- }
- }
- }
- /* draw Objects */
- //I can't have 200 vertices in SRAM because it's like 1kB
- //so I need to load them one by one and compute
- //I could have loaded them on external 23k256
- //or read them from flash each time
- //what is flash read time?
- /*
- for (i = 0; i < 5; ++i) {
- Plocal[0] = 0;
- Plocal[1] = - i;
- Plocal[2] = 0;
- Plocal[3] = 1.0;
- if (computePix()) {
- display.drawPixel(Ppix[0], Ppix[1], WHITE);
- if (computePix2()) {
- display2.drawPixel(Ppix[0], Ppix[1], WHITE);
- }
- }
- }*/
- /*display.println(eyeSocket[0]);
- display.println(eyeSocket[1]);
- display.println(eyeSocket[2]);*/
- if (showDebug && !showKeyb) {
- display.setCursor(0, 0);
- display.println(eyeDirection[0]);
- display.println(eyeDirection[1]);
- display.println(eyeDirection[2]);
- display.println(eyeUp[0]);
- display.println(eyeUp[1]);
- display.println(eyeUp[2]);
- }
- }
- bool computePix() {
- int i, j;
- multiplication(worldMat, Plocal, Pworld, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i) {
- if (!didOnce) {
- Serial.println(Pworld[i]);
- }
- }
- multiplication(tmpMat, Pworld, Pcamera, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i) {
- if (!didOnce) {
- Serial.println(Pcamera[i]);
- }
- }
- /*multiplication(rollMat, Pcamera, Pworld, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i)
- Pcamera[i] = Pworld[i];*/
- didOnce = true;
- if (Pcamera[2] < 1) {
- return false;
- }
- float negInvPcameraZ = -(1.0 / (Pcamera[2]));
- for (i = 0; i < 4; ++i)
- Pscreen[i] = Pcamera[i] * negInvPcameraZ;
- Pnds[0] = (Pscreen[0] + clipWidth / 2.0) / clipWidth;
- Pnds[1] = (Pscreen[1] + clipHeight / 2.0) / clipHeight;
- if (Pnds[0] < 0 || Pnds[0] > 1) return false;
- if (Pnds[1] < 0 || Pnds[1] > 1) return false;
- Ppix[0] = (int) (Pnds[0] * 128); //todo dynamic pixelWidth //replaced 128 and 64
- Ppix[1] = (int) ((1 - Pnds[1]) * 64);
- didOnce = true;
- return true;
- }
- bool computePix2() {
- int i, j;
- multiplication(worldMat2, Plocal, Pworld, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i) {
- if (!didOnce) {
- Serial.println(Pworld[i]);
- }
- }
- multiplication(tmpMat, Pworld, Pcamera, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i) {
- if (!didOnce) {
- Serial.println(Pcamera[i]);
- }
- }
- /*multiplication(rollMat, Pcamera, Pworld, 4, 4, 4, 1);
- for (i = 0; i < 4; ++i)
- Pcamera[i] = Pworld[i];*/
- didOnce = true;
- if (Pcamera[2] < 1) {
- return false;
- }
- float negInvPcameraZ = -(1.0 / (Pcamera[2]));
- for (i = 0; i < 4; ++i)
- Pscreen[i] = Pcamera[i] * negInvPcameraZ;
- Pnds[0] = (Pscreen[0] + clipWidth / 2.0) / clipWidth;
- Pnds[1] = (Pscreen[1] + clipHeight / 2.0) / clipHeight;
- if (Pnds[0] < 0 || Pnds[0] > 1) return false;
- if (Pnds[1] < 0 || Pnds[1] > 1) return false;
- Ppix[0] = (int) (Pnds[0] * 128); //todo dynamic pixelWidth //replaced 128 and 64
- Ppix[1] = (int) ((1 - Pnds[1]) * 64);
- didOnce = true;
- return true;
- }
- //For LeftHanded system camTar - camPos
- ////For RightHanded system camPos - camTar
- void createLookAt(float cameraPosition[], float cameraTarget[], float cameraUp[], float lookAt[]) {
- int i;
- //zaxis = normal(cameraTarget - cameraPosition)
- float zaxis[3];
- zaxis[0] = cameraTarget[0] - cameraPosition[0];
- zaxis[1] = cameraTarget[1] - cameraPosition[1];
- zaxis[2] = cameraTarget[2] - cameraPosition[2];
- normalize3(zaxis);
- //xaxis = normal(cross(cameraUpVector, zaxis))
- float xaxis[3];
- Vector_Cross_Product(xaxis, cameraUp, zaxis);
- normalize3(xaxis);
- //yaxis = cross(zaxis, xaxis)
- float yaxis[3];
- Vector_Cross_Product(yaxis, zaxis, xaxis);
- lookAt[0] = xaxis[0];
- lookAt[4] = xaxis[1];
- lookAt[8] = xaxis[2];
- lookAt[1] = yaxis[0];
- lookAt[5] = yaxis[1];
- lookAt[9] = yaxis[2];
- lookAt[2] = zaxis[0];
- lookAt[6] = zaxis[1];
- lookAt[10] = zaxis[2];
- lookAt[3] = lookAt[7] = lookAt[11] = 0;
- lookAt[12] = -Vector_Dot_Product(xaxis, cameraPosition);
- lookAt[13] = -Vector_Dot_Product(yaxis, cameraPosition);
- lookAt[14] = -Vector_Dot_Product(zaxis, cameraPosition);
- lookAt[15] = 1;
- /*
- xaxis.x yaxis.x zaxis.x 0
- xaxis.y yaxis.y zaxis.y 0
- xaxis.z yaxis.z zaxis.z 0
- -dot(xaxis, cameraPosition) -dot(yaxis, cameraPosition) -dot(zaxis, cameraPosition) 1*/
- }
- void normalize3(float vec[]) {
- int i;
- float tmpnormal = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
- for (i = 0; i < 3; ++i)
- vec[i] /= tmpnormal;
- }
- void Vector_Cross_Product(float vectorOut[3], float v1[3], float v2[3])
- {
- vectorOut[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
- vectorOut[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
- vectorOut[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
- }
- float Vector_Dot_Product(float vector1[], float vector2[])
- {
- float op = 0;
- for (int c = 0; c < 3; c++)
- {
- op += vector1[c] * vector2[c];
- }
- return op;
- }
- void matrixScalarMult(float m[], int sz, float f) {
- int i;
- for (i = 0; i < sz; ++i)
- m[i] = f * m[i];
- }
- void transformFromAxisAngle(float vecOut[], float v[], float a) {
- float axis[3];
- axis[0] = v[0]; axis[1] = v[1]; axis[2] = v[2];
- float angle = a;
- normalize3(axis);
- float s = sin(angle);
- float c = cos(angle);
- float oc = 1.0 - c;
- vecOut[0] = oc * axis[0] * axis[0] + c;
- vecOut[1] = oc * axis[0] * axis[1] - axis[2] * s;
- vecOut[2] = oc * axis[2] * axis[0] + axis[1] * s;
- vecOut[3] = 0.0;
- vecOut[4] = oc * axis[0] * axis[1] + axis[2] * s;
- vecOut[5] = oc * axis[1] * axis[1] + c;
- vecOut[6] = oc * axis[1] * axis[2] - axis[0] * s;
- vecOut[7] = 0.0;
- vecOut[8] = oc * axis[2] * axis[0] - axis[1] * s;
- vecOut[9] = oc * axis[1] * axis[2] + axis[0] * s;
- vecOut[10] = oc * axis[2] * axis[2] + c;
- vecOut[11] = 0.0;
- vecOut[12] = 0.0;
- vecOut[13] = 0.0;
- vecOut[14] = 0.0;
- vecOut[15] = 1.0;
- /*return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
- oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
- oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
- 0.0, 0.0, 0.0, 1.0);*/
- }
- void multiplication(float a[], float b[], float mult[], int r1, int c1, int r2, int c2)
- {
- int i, j, k;
- for (i = 0; i < r1; ++i)
- for (j = 0; j < c2; ++j)
- {
- mult[i * c2 + j] = 0;
- }
- for (i = 0; i < r1; ++i)
- for (j = 0; j < c2; ++j)
- for (k = 0; k < c1; ++k)
- {
- mult[i * c2 + j] += a[i * c1 + k] * b[k * c2 + j];
- }
- }
- /************************************************************************************
- FUNCTIONS IMU
- */
- ////////////////////////////////////////////////////////////
- ///////// IMU functions to get easier all values ///////////
- ////////////////////////////////////////////////////////////
- void MPU9150_setupCompass() {
- MPU9150_I2C_ADDRESS = 0x0C; //change Address to Compass
- MPU9150_writeSensor(0x0A, 0x00); //PowerDownMode
- MPU9150_writeSensor(0x0A, 0x0F); //SelfTest
- MPU9150_writeSensor(0x0A, 0x00); //PowerDownMode
- MPU9150_I2C_ADDRESS = 0x69; //change Address to MPU
- MPU9150_writeSensor(0x24, 0x40); //Wait for Data at Slave0
- MPU9150_writeSensor(0x25, 0x8C); //Set i2c address at slave0 at 0x0C
- MPU9150_writeSensor(0x26, 0x02); //Set where reading at slave 0 starts
- MPU9150_writeSensor(0x27, 0x88); //set offset at start reading and enable
- MPU9150_writeSensor(0x28, 0x0C); //set i2c address at slv1 at 0x0C
- MPU9150_writeSensor(0x29, 0x0A); //Set where reading at slave 1 starts
- MPU9150_writeSensor(0x2A, 0x81); //Enable at set length to 1
- MPU9150_writeSensor(0x64, 0x01); //overvride register
- MPU9150_writeSensor(0x67, 0x03); //set delay rate
- MPU9150_writeSensor(0x01, 0x80);
- MPU9150_writeSensor(0x34, 0x04); //set i2c slv4 delay
- MPU9150_writeSensor(0x64, 0x00); //override register
- MPU9150_writeSensor(0x6A, 0x00); //clear usr setting
- MPU9150_writeSensor(0x64, 0x01); //override register
- MPU9150_writeSensor(0x6A, 0x20); //enable master i2c mode
- MPU9150_writeSensor(0x34, 0x13); //disable slv4
- }
- int MPU9150_readSensor(int addrL, int addrH) {
- Wire.beginTransmission(MPU9150_I2C_ADDRESS);
- Wire.write(addrL);
- Wire.endTransmission(false);
- Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
- byte L = Wire.read();
- Wire.beginTransmission(MPU9150_I2C_ADDRESS);
- Wire.write(addrH);
- Wire.endTransmission(false);
- Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
- byte H = Wire.read();
- return (int16_t)((H << 8) + L);
- }
- int MPU9150_readSensor(int addr) {
- Wire.beginTransmission(MPU9150_I2C_ADDRESS);
- Wire.write(addr);
- Wire.endTransmission(false);
- Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
- return Wire.read();
- }
- int MPU9150_writeSensor(int addr, int data) {
- Wire.beginTransmission(MPU9150_I2C_ADDRESS);
- Wire.write(addr);
- Wire.write(data);
- Wire.endTransmission(true);
- return 1;
- }
- void setupIMU() {
- // Initialize the 'Wire' class for the I2C-bus.
- Wire.begin();
- // Clear the 'sleep' bit to start the sensor.
- MPU9150_writeSensor(MPU9150_PWR_MGMT_1, 0);
- MPU9150_setupCompass();
- }
- void loopIMU() {
- // Print all sensor values which the sensor provides
- // Formated all values as x, y, and z in order for
- // Compass, Gyro, Acceleration. The First value is
- // the temperature.
- double dT = ( (double) MPU9150_readSensor(MPU9150_TEMP_OUT_L, MPU9150_TEMP_OUT_H) + 12412.0) / 340.0;
- Serial.print(dT);
- Serial.println("C Temperature ");
- double magX = MPU9150_readSensor(MPU9150_CMPS_XOUT_L, MPU9150_CMPS_XOUT_H);
- Serial.print(magX);
- Serial.print(" ");
- double magY = MPU9150_readSensor(MPU9150_CMPS_YOUT_L, MPU9150_CMPS_YOUT_H);
- Serial.print(magY);
- Serial.print(" ");
- Serial.print(MPU9150_readSensor(MPU9150_CMPS_ZOUT_L, MPU9150_CMPS_ZOUT_H));
- /*Serial.print(" ");
- Serial.print(MPU9150_readSensor(MPU9150_GYRO_XOUT_L, MPU9150_GYRO_XOUT_H));
- Serial.print(" ");
- Serial.print(MPU9150_readSensor(MPU9150_GYRO_YOUT_L, MPU9150_GYRO_YOUT_H));
- Serial.print(" ");
- Serial.print(MPU9150_readSensor(MPU9150_GYRO_ZOUT_L, MPU9150_GYRO_ZOUT_H));*/
- Serial.println(" x/y/z Compass ");
- /*
- float magNorthDegrees = 0;
- if (magY>1) magNorthDegrees = 90 - atan(magX/magY)*(180.0/PI);
- else if (magY<-1) magNorthDegrees = 270 - atan(magX/magY)*(180.0/PI);
- else if (magX<-1) magNorthDegrees = 180.0; //Direction (y=0, x<0) = 180.0
- else if (magX>=-1) magNorthDegrees = 0.0; //Direction (y=0, x>0) = 0.0
- Serial.print(magNorthDegrees);
- Serial.println(" Magnetic North");*/
- double ax, ay, az;
- ax = MPU9150_readSensor(MPU9150_ACCEL_XOUT_L, MPU9150_ACCEL_XOUT_H);
- Serial.print(ax);
- Serial.print(" ");
- ay = MPU9150_readSensor(MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H);
- Serial.print(ay);
- //Serial.print(MPU9150_readSensor(MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H));
- Serial.print(" ");
- az = MPU9150_readSensor(MPU9150_ACCEL_ZOUT_L, MPU9150_ACCEL_ZOUT_H);
- Serial.print(az);
- //Serial.print(MPU9150_readSensor(MPU9150_ACCEL_ZOUT_L, MPU9150_ACCEL_ZOUT_H));
- Serial.println(" x/y/z Accelero");
- ///double xyz[3];
- //double ax, ay, az;
- //adxl.get_Gxyz(xyz);
- //ax = xyz[0];
- //ay = xyz[1];
- //az = xyz[2];
- /*double xAngle = atan( ax / (sqrt(square(ay) + square(az))));
- double yAngle = atan( ay / (sqrt(square(ax) + square(az))));
- double zAngle = atan( sqrt(square(ax) + square(ay)) / az);
- xAngle *= 180.00; yAngle *= 180.00; zAngle *= 180.00;
- xAngle /= 3.141592; yAngle /= 3.141592; zAngle /= 3.141592;
- Serial.print("As angles: "); Serial.print(xAngle); Serial.print("/");
- Serial.print(yAngle); Serial.print("/"); Serial.println(zAngle); */
- //delay(10);
- }
- /////////////////////// APPS
- void learnChineseApp() {
- display.clearDisplay();
- display2.clearDisplay();
- //I should drawbitmap logo
- display.setTextSize(2);
- display.setTextColor(BLACK, WHITE);
- display.setCursor(10, 10);
- display.println("China is Awesome!");
- display.display();
- delay(10000);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement