### Install I2C Tools Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Install the I2C tools package to help detect and manage I2C devices. ```bash sudo apt-get install i2c-tools ``` -------------------------------- ### Minimal RTIMULib Application Example Source: https://context7.com/smukkejohan/rtimulib/llms.txt A complete minimal application demonstrating RTIMULib integration for real-time pose monitoring. It includes sample rate calculation and Euler angle display. Requires RTIMULib.ini for configuration. ```cpp // RTIMULibDrive.cpp - Minimal RTIMULib application #include "RTIMULib.h" int main() { int sampleCount = 0; int sampleRate = 0; uint64_t rateTimer; uint64_t displayTimer; uint64_t now; // Create settings object - uses RTIMULib.ini if present RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); // Create IMU with auto-detection RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL) { printf("No IMU found\n"); exit(1); } // Initialize IMU hardware if (!imu->IMUInit()) { printf("IMU init failed\n"); exit(1); } // Initialize timing rateTimer = displayTimer = RTMath::currentUSecsSinceEpoch(); // Main processing loop while (1) { // Poll at the rate recommended by the IMU driver usleep(imu->IMUGetPollInterval() * 1000); // Read all available samples while (imu->IMURead()) { RTIMU_DATA imuData = imu->getIMUData(); sampleCount++; now = RTMath::currentUSecsSinceEpoch(); // Update display 10 times per second if ((now - displayTimer) > 100000) { printf("Sample rate %d: %s\r", sampleRate, RTMath::displayDegrees("", imuData.fusionPose)); fflush(stdout); displayTimer = now; } // Calculate sample rate every second if ((now - rateTimer) > 1000000) { sampleRate = sampleCount; sampleCount = 0; rateTimer = now; } } } // Cleanup (unreachable in this example) delete imu; delete settings; return 0; } // Compile: g++ -O2 -I../RTIMULib RTIMULibDrive.cpp ../RTIMULib/*.cpp -o RTIMULibDrive // Run: ./RTIMULibDrive // Output: Sample rate 50: roll=1.23, pitch=-2.45, yaw=127.89 ``` -------------------------------- ### RTIMULib INI Configuration File Example Source: https://context7.com/smukkejohan/rtimulib/llms.txt Example of the RTIMULib.ini configuration file, which controls IMU type, fusion algorithm, I2C settings, compass calibration, and sensor-specific parameters. This file is automatically created with defaults. ```ini # RTIMULib.ini - Configuration file # IMU Type Selection # 0 = Auto-discover, 1 = Null (no hardware), 2 = MPU9150, 3 = GD20M303 IMUType=0 # Fusion Algorithm # 0 = Null (no fusion), 1 = Kalman STATE4 (quaternion state) FusionType=1 # I2C Configuration I2CBus=1 I2CSlaveAddress=104 # Compass Calibration Data CompassCalValid=true CompassCalMinX=-52.300000 CompassCalMaxX=54.800000 CompassCalMinY=-48.700000 CompassCalMaxY=47.200000 CompassCalMinZ=-41.200000 CompassCalMaxZ=53.100000 # MPU9150 Settings MPU9150GyroAccelSampleRate=50 MPU9150CompassSampleRate=25 MPU9150GyroAccelLpf=4 MPU9150GyroFSR=16 MPU9150AccelFSR=16 ``` -------------------------------- ### Calibrate Compass Data Source: https://context7.com/smukkejohan/rtimulib/llms.txt Guides through the process of calibrating the compass by collecting raw data while rotating the IMU. It then applies these calibration parameters to correct for hard-iron distortions and saves the settings. ```cpp #include "RTIMULib.h" // Compass calibration procedure void calibrateCompass(RTIMU *imu, RTIMUSettings *settings) { RTVector3 compassMin(1e10, 1e10, 1e10); RTVector3 compassMax(-1e10, -1e10, -1e10); printf("Rotate IMU through all orientations...\n"); printf("Press Ctrl+C when finished\n\n"); // Enable calibration mode to get raw compass data imu->setCalibrationMode(true); int samples = 0; while (samples < 1000) { usleep(imu->IMUGetPollInterval() * 1000); if (imu->IMURead()) { const RTIMU_DATA& data = imu->getIMUData(); samples++; // Track min/max for each axis if (data.compass.x() < compassMin.x()) compassMin.setX(data.compass.x()); if (data.compass.y() < compassMin.y()) compassMin.setY(data.compass.y()); if (data.compass.z() < compassMin.z()) compassMin.setZ(data.compass.z()); if (data.compass.x() > compassMax.x()) compassMax.setX(data.compass.x()); if (data.compass.y() > compassMax.y()) compassMax.setY(data.compass.y()); if (data.compass.z() > compassMax.z()) compassMax.setZ(data.compass.z()); printf("Min: (%6.1f, %6.1f, %6.1f) Max: (%6.1f, %6.1f, %6.1f)\r", compassMin.x(), compassMin.y(), compassMin.z(), compassMax.x(), compassMax.y(), compassMax.z()); } } // Apply calibration data imu->setCalibrationData(true, compassMin, compassMax); imu->setCalibrationMode(false); // Save to settings file settings->m_compassCalValid = true; settings->m_compassCalMin = compassMin; settings->m_compassCalMax = compassMax; settings->saveSettings(); printf("\nCalibration complete and saved\n"); // Expected output: // Rotate IMU through all orientations... // Min: (-52.3, -48.7, -41.2) Max: ( 54.8, 47.2, 53.1) // Calibration complete and saved } ``` -------------------------------- ### Initialize IMU Hardware with IMUInit Source: https://context7.com/smukkejohan/rtimulib/llms.txt Configures I2C communication, sample rates, and filters. Must be called before attempting to read sensor data. ```cpp #include "RTIMULib.h" int main() { RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL) { printf("No IMU found\n"); exit(1); } // Initialize the IMU - configures hardware and starts sampling if (!imu->IMUInit()) { printf("IMU initialization failed\n"); exit(1); } printf("IMU initialized successfully\n"); printf("Recommended poll interval: %d ms\n", imu->IMUGetPollInterval()); // Expected output: // Using Kalman STATE4 // IMU initialized successfully // Recommended poll interval: 20 ms delete imu; delete settings; return 0; } ``` -------------------------------- ### Create IMU Instance with RTIMU::createIMU Source: https://context7.com/smukkejohan/rtimulib/llms.txt Uses the factory method to instantiate an IMU driver based on configuration settings. Requires an RTIMUSettings object and returns NULL if no hardware is detected. ```cpp #include "RTIMULib.h" int main() { // Create settings object - uses RTIMULib.ini for configuration RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); // Create IMU instance with auto-detection // Returns NULL if no IMU found RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL) { printf("No IMU found\n"); exit(1); } // IMU type codes: // RTIMU_TYPE_AUTODISCOVER (0) - Auto-detect IMU // RTIMU_TYPE_NULL (1) - No physical hardware // RTIMU_TYPE_MPU9150 (2) - InvenSense MPU9150 // RTIMU_TYPE_GD20M303 (3) - STM L3GD20H/LSM303D printf("IMU type %d detected at address 0x%02x\n", settings->m_imuType, settings->m_I2CSlaveAddress); // Cleanup delete imu; delete settings; return 0; } ``` -------------------------------- ### Demonstrate RTMath Utilities Source: https://context7.com/smukkejohan/rtimulib/llms.txt Showcases various RTMath utility functions including timestamp generation, pose calculation from accelerometer and magnetometer, and formatted display of sensor data in degrees and radians. Useful for debugging and understanding sensor data. ```cpp #include "RTIMULib.h" void demonstrateRTMath() { // High-resolution timestamp (microseconds since epoch) uint64_t timestamp = RTMath::currentUSecsSinceEpoch(); printf("Current timestamp: %llu us\n", timestamp); // Calculate pose from accelerometer and magnetometer // (without gyro fusion - just tilt and heading) RTVector3 accel(0.0, 0.0, 1.0); // Flat orientation (z-up) RTVector3 mag(20.0, 0.0, 40.0); // North-pointing RTVector3 pose = RTMath::poseFromAccelMag(accel, mag); printf("Pose from accel+mag: %s\n", RTMath::displayDegrees("Pose", pose)); // Display helpers for debugging RTVector3 gyro(0.01, -0.02, 0.005); printf("%s\n", RTMath::displayRadians("Gyro rates", gyro)); printf("%s\n", RTMath::displayDegrees("Gyro rates", gyro)); RTQuaternion quat(0.707, 0.0, 0.707, 0.0); printf("%s\n", RTMath::display("Quaternion", quat)); // Convert raw sensor bytes to vector (for driver development) unsigned char rawData[6] = {0x01, 0x00, 0x02, 0x00, 0x03, 0x00}; RTVector3 vec; RTFLOAT scale = 1.0 / 16384.0; // MPU9150 accel scale RTMath::convertToVector(rawData, vec, scale, false); printf("Converted vector: %s\n", vec.display()); // Expected output: // Current timestamp: 1712505600000000 us // Pose from accel+mag: Pose: roll=0.00, pitch=0.00, yaw=26.57 // Gyro rates: x=0.010000, y=-0.020000, z=0.005000 rads // Gyro rates: roll=0.57, pitch=-1.15, yaw=0.29 } ``` -------------------------------- ### Enable I2C Modules Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Add these lines to /etc/modules to enable I2C support on the Raspberry Pi. Ensure the I2C bus is not blacklisted. ```bash i2c-bcm2708 i2c-dev ``` -------------------------------- ### Configure 400KHz I2C Bus Speed Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Create this configuration file to set the I2C bus speed to 400KHz, which can significantly increase the sample rate. A reboot is recommended after creating this file. ```bash options i2c_bcm2708 baudrate=400000 ``` -------------------------------- ### IMUInit - Initialize IMU Hardware Source: https://context7.com/smukkejohan/rtimulib/llms.txt Initializes the IMU hardware, configuring I2C communication, sample rates, filters, and ranges. Must be called before reading sensor data. ```APIDOC ## IMUInit - Initialize IMU Hardware ### Description The `IMUInit()` method initializes the IMU hardware, configures I2C communication, sets up sample rates, low-pass filters, and full-scale ranges. It must be called before reading sensor data. The method returns `true` on success, `false` on failure. ### Method Instance Method ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include "RTIMULib.h" int main() { RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL) { printf("No IMU found\n"); exit(1); } // Initialize the IMU - configures hardware and starts sampling if (!imu->IMUInit()) { printf("IMU initialization failed\n"); exit(1); } printf("IMU initialized successfully\n"); printf("Recommended poll interval: %d ms\n", imu->IMUGetPollInterval()); // Expected output: // Using Kalman STATE4 // IMU initialized successfully // Recommended poll interval: 20 ms delete imu; delete settings; return 0; } ``` ### Response #### Success Response (200) - **true** - Indicates successful initialization. #### Error Response (Failure) - **false** - Indicates initialization failure. #### Response Example ``` IMU initialized successfully Recommended poll interval: 20 ms ``` ``` -------------------------------- ### Blacklist I2C Module Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Comment out this line in /etc/modprobe.d/raspi-blacklist.conf to allow the I2C module to load. ```bash # blacklist i2c-bcm2708 ``` -------------------------------- ### Manage IMU Configuration with RTIMUSettings Source: https://context7.com/smukkejohan/rtimulib/llms.txt Configures IMU parameters and persists them to an INI file. Settings are loaded via loadSettings() and saved via saveSettings(). ```cpp #include "RTIMULib.h" int main() { // Create settings with custom product name (creates RTIMULib.ini) RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); // Load settings from INI file (or use defaults) settings->loadSettings(); // Configure IMU type // RTIMU_TYPE_AUTODISCOVER (0) - Auto-detect // RTIMU_TYPE_MPU9150 (2) - Force MPU9150 settings->m_imuType = RTIMU_TYPE_AUTODISCOVER; // I2C configuration settings->m_I2CBus = 1; // /dev/i2c-1 for Raspberry Pi settings->m_I2CSlaveAddress = 0x68; // MPU9150 default address // Fusion algorithm selection // RTFUSION_TYPE_NULL (0) - No fusion // RTFUSION_TYPE_KALMANSTATE4 (1) - Kalman with quaternion state settings->m_fusionType = RTFUSION_TYPE_KALMANSTATE4; // MPU9150-specific settings settings->m_MPU9150GyroAccelSampleRate = 50; // 5-1000 samples/sec settings->m_MPU9150CompassSampleRate = 25; // 1-100 samples/sec settings->m_MPU9150GyroAccelLpf = 4; // LPF: 20Hz gyro, 21Hz accel settings->m_MPU9150GyroFsr = 16; // +/- 1000 deg/sec settings->m_MPU9150AccelFsr = 16; // +/- 8g // Compass calibration (normally set via RTIMULibDemo) settings->m_compassCalValid = true; settings->m_compassCalMin = RTVector3(-50.0, -45.0, -40.0); settings->m_compassCalMax = RTVector3(55.0, 48.0, 52.0); // Save settings to INI file settings->saveSettings(); // INI file format: // IMUType=0 // FusionType=1 // I2CBus=1 // I2CSlaveAddress=104 // CompassCalValid=true // CompassCalMinX=-50.000000 // ... delete settings; return 0; } ``` -------------------------------- ### RTIMU::createIMU - Create IMU Instance Source: https://context7.com/smukkejohan/rtimulib/llms.txt Factory method to create an appropriate IMU driver instance based on settings. Supports automatic IMU discovery by scanning I2C addresses. ```APIDOC ## RTIMU::createIMU - Create IMU Instance ### Description The factory method `RTIMU::createIMU()` creates the appropriate IMU driver instance based on settings configuration. It supports automatic IMU discovery, scanning I2C addresses to detect connected sensors and automatically configuring the correct driver. ### Method Factory Method ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include "RTIMULib.h" int main() { // Create settings object - uses RTIMULib.ini for configuration RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); // Create IMU instance with auto-detection // Returns NULL if no IMU found RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL) { printf("No IMU found\n"); exit(1); } // IMU type codes: // RTIMU_TYPE_AUTODISCOVER (0) - Auto-detect IMU // RTIMU_TYPE_NULL (1) - No physical hardware // RTIMU_TYPE_MPU9150 (2) - InvenSense MPU9150 // RTIMU_TYPE_GD20M303 (3) - STM L3GD20H/LSM303D printf("IMU type %d detected at address 0x%02x\n", settings->m_imuType, settings->m_I2CSlaveAddress); // Cleanup delete imu; delete settings; return 0; } ``` ### Response #### Success Response (Instance) - **imu** (RTIMU*) - Pointer to the created IMU driver instance. Returns NULL if no IMU is found. #### Response Example (See Request Example for output indicating IMU type and address) ``` -------------------------------- ### Clone RTIMULib Repository Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Use this command to download the RTIMULib source code from GitHub. ```bash git clone https://github.com/richards-tech/RTIMULib.git ``` -------------------------------- ### Detect I2C Devices Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Use this command to detect devices on I2C bus 1. The MPU9150 should appear at address 0x68 by default. ```bash sudo i2cdetect -y 1 ``` -------------------------------- ### RTIMUSettings - Configuration Management API Source: https://context7.com/smukkejohan/rtimulib/llms.txt Manages IMU configuration via an INI file, allowing selection of IMU type, I2C settings, sensor parameters, compass calibration data, and fusion algorithm. Settings are persisted across sessions. ```APIDOC ## RTIMUSettings - Configuration Management ### Description The `RTIMUSettings` class manages IMU configuration via an INI file, supporting IMU type selection, I2C settings, sensor parameters, compass calibration data, and fusion algorithm selection. Settings persist across sessions. ### Method POST/PUT (conceptual, for loading/saving settings) ### Endpoint N/A (This is a library class, not a network endpoint) ### Parameters #### Initialization - **productName** (string) - Required - A name for the product to create/load the RTIMULib.ini file. #### Settings (Members of RTIMUSettings) - **m_imuType** (int) - Optional - IMU type selection (e.g., RTIMU_TYPE_AUTODISCOVER, RTIMU_TYPE_MPU9150). - **m_I2CBus** (int) - Optional - I2C bus number (e.g., 1 for /dev/i2c-1). - **m_I2CSlaveAddress** (int) - Optional - I2C slave address of the IMU. - **m_fusionType** (int) - Optional - Fusion algorithm selection (e.g., RTFUSION_TYPE_NULL, RTFUSION_TYPE_KALMANSTATE4). - **m_MPU9150GyroAccelSampleRate** (int) - Optional - MPU9150 Gyro/Accel sample rate (5-1000 samples/sec). - **m_MPU9150CompassSampleRate** (int) - Optional - MPU9150 Compass sample rate (1-100 samples/sec). - **m_MPU9150GyroAccelLpf** (int) - Optional - MPU9150 Gyro/Accel Low Pass Filter setting. - **m_MPU9150GyroFsr** (int) - Optional - MPU9150 Gyro Full Scale Range (+/- 1000 deg/sec). - **m_MPU9150AccelFsr** (int) - Optional - MPU9150 Accelerometer Full Scale Range (+/- 8g). - **m_compassCalValid** (bool) - Optional - Indicates if compass calibration data is valid. - **m_compassCalMin** (RTVector3) - Optional - Minimum values for compass calibration. - **m_compassCalMax** (RTVector3) - Optional - Maximum values for compass calibration. ### Request Example ```cpp #include "RTIMULib.h" RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); settings->loadSettings(); // Modify settings as needed settings->m_imuType = RTIMU_TYPE_AUTODISCOVER; settings->m_I2CBus = 1; settings->m_fusionType = RTFUSION_TYPE_KALMANSTATE4; settings->saveSettings(); ``` ### Response #### Success Response (void) Settings are saved to the INI file. #### Response Example ```ini # RTIMULib.ini example IMUType=0 FusionType=1 I2CBus=1 I2CSlaveAddress=104 CompassCalValid=true CompassCalMinX=-50.000000 CompassCalMinY=-45.000000 CompassCalMinZ=-40.000000 CompassCalMaxX=55.000000 CompassCalMaxY=48.000000 CompassCalMaxZ=52.000000 ``` ``` -------------------------------- ### Read Sensor Data with IMURead Source: https://context7.com/smukkejohan/rtimulib/llms.txt Polls the IMU for new data and retrieves fused pose information. Should be executed in a loop at the interval specified by IMUGetPollInterval(). ```cpp #include "RTIMULib.h" int main() { RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL || !imu->IMUInit()) { printf("IMU setup failed\n"); exit(1); } int sampleCount = 0; uint64_t startTime = RTMath::currentUSecsSinceEpoch(); while (sampleCount < 100) { // Poll at recommended interval usleep(imu->IMUGetPollInterval() * 1000); // Read returns true when new data is available while (imu->IMURead()) { RTIMU_DATA imuData = imu->getIMUData(); sampleCount++; // Display Euler angles in degrees printf("Roll: %6.2f Pitch: %6.2f Yaw: %6.2f\r", imuData.fusionPose.x() * RTMATH_RAD_TO_DEGREE, imuData.fusionPose.y() * RTMATH_RAD_TO_DEGREE, imuData.fusionPose.z() * RTMATH_RAD_TO_DEGREE); } } uint64_t elapsed = RTMath::currentUSecsSinceEpoch() - startTime; printf("\nSample rate: %.1f samples/sec\n", sampleCount * 1000000.0 / elapsed); // Expected output: // Roll: -2.34 Pitch: 1.56 Yaw: 45.23 // Sample rate: 50.0 samples/sec delete imu; delete settings; return 0; } ``` -------------------------------- ### RTIMUSettings::discoverIMU Source: https://context7.com/smukkejohan/rtimulib/llms.txt Scans the I2C bus to detect supported IMU chips and retrieve their type and I2C address. ```APIDOC ## RTIMUSettings::discoverIMU ### Description Scans the I2C bus to find supported IMU chips, returning the detected type and I2C address. This enables plug-and-play operation with multiple IMU types. ### Parameters - **imuType** (int&) - Required - Reference to store the detected IMU type. - **slaveAddress** (unsigned char&) - Required - Reference to store the detected I2C slave address. ### Response - **Returns** (bool) - Returns true if a supported IMU is found, false otherwise. ``` -------------------------------- ### Set I2C Device Permissions Source: https://github.com/smukkejohan/rtimulib/blob/master/README.md Create this udev rule to grant read/write access to I2C devices for all users. The Raspberry Pi needs to be rebooted for this change to take effect. ```bash KERNEL=="i2c-[0-7]",MODE="0666" ``` -------------------------------- ### Control Sensor Enablement for Fusion Source: https://context7.com/smukkejohan/rtimulib/llms.txt Use setGyroEnable(), setAccelEnable(), and setCompassEnable() to include or exclude sensors from the fusion algorithm. This allows for experimentation with different sensor combinations or handling sensor failures. ```cpp #include "RTIMULib.h" void demonstrateSensorControls(RTIMU *imu) { // Default: all sensors enabled imu->setGyroEnable(true); imu->setAccelEnable(true); imu->setCompassEnable(true); printf("All sensors enabled - full 9-DOF fusion\n"); readSamples(imu, 50); // Gyro-only mode (dead reckoning) imu->setAccelEnable(false); imu->setCompassEnable(false); printf("Gyro-only mode - will drift over time\n"); readSamples(imu, 50); // Gyro + Accel mode (no heading reference) imu->setAccelEnable(true); imu->setCompassEnable(false); printf("Gyro + Accel mode - no yaw stabilization\n"); readSamples(imu, 50); // Re-enable all sensors and reset fusion imu->setCompassEnable(true); imu->resetFusion(); printf("All sensors re-enabled, fusion reset\n"); } void readSamples(RTIMU *imu, int count) { for (int i = 0; i < count; i++) { usleep(imu->IMUGetPollInterval() * 1000); if (imu->IMURead()) { RTIMU_DATA data = imu->getIMUData(); printf(" Sample %d: Roll=%6.2f Pitch=%6.2f Yaw=%6.2f\n", i, data.fusionPose.x() * RTMATH_RAD_TO_DEGREE, data.fusionPose.y() * RTMATH_RAD_TO_DEGREE, data.fusionPose.z() * RTMATH_RAD_TO_DEGREE); } } } ``` -------------------------------- ### Access Fused Sensor Data with getIMUData Source: https://context7.com/smukkejohan/rtimulib/llms.txt Retrieves the RTIMU_DATA structure containing raw readings and fusion results. Ensure IMURead() is called successfully before accessing the data. ```cpp #include "RTIMULib.h" void processIMUData(RTIMU *imu) { if (!imu->IMURead()) return; // Get the complete IMU data structure const RTIMU_DATA& data = imu->getIMUData(); // RTIMU_DATA structure fields: // timestamp - Microseconds since epoch // fusionPoseValid - True if fusion Euler angles valid // fusionPose - Fused Euler angles (roll, pitch, yaw) in radians // fusionQPoseValid - True if fusion quaternion valid // fusionQPose - Fused quaternion pose // gyroValid - True if gyro data valid // gyro - Gyro rates (x, y, z) in radians/sec // accelValid - True if accelerometer data valid // accel - Acceleration (x, y, z) in g units // compassValid - True if compass data valid // compass - Magnetometer (x, y, z) in uT if (data.fusionPoseValid) { printf("Euler (deg): Roll=%6.2f Pitch=%6.2f Yaw=%6.2f\n", data.fusionPose.x() * RTMATH_RAD_TO_DEGREE, data.fusionPose.y() * RTMATH_RAD_TO_DEGREE, data.fusionPose.z() * RTMATH_RAD_TO_DEGREE); } if (data.fusionQPoseValid) { printf("Quaternion: w=%6.4f x=%6.4f y=%6.4f z=%6.4f\n", data.fusionQPose.scalar(), data.fusionQPose.x(), data.fusionQPose.y(), data.fusionQPose.z()); } if (data.gyroValid) { printf("Gyro (rad/s): x=%6.4f y=%6.4f z=%6.4f\n", data.gyro.x(), data.gyro.y(), data.gyro.z()); } if (data.accelValid) { printf("Accel (g): x=%6.4f y=%6.4f z=%6.4f\n", data.accel.x(), data.accel.y(), data.accel.z()); } if (data.compassValid) { printf("Compass (uT): x=%6.2f y=%6.2f z=%6.2f\n", data.compass.x(), data.compass.y(), data.compass.z()); } // Expected output: // Euler (deg): Roll= -1.23 Pitch= 2.45 Yaw= 127.89 // Quaternion: w=0.8536 x=-0.0107 y=0.0214 z=0.5202 // Gyro (rad/s): x=0.0012 y=-0.0008 z=0.0003 // Accel (g): x=0.0215 y=-0.0428 z=0.9991 // Compass (uT): x= 23.45 y=-12.67 z= 45.23 } ``` -------------------------------- ### IMURead - Read Sensor Data Source: https://context7.com/smukkejohan/rtimulib/llms.txt Reads raw sensor data and processes it through the Kalman filter for fused pose data. Returns true if new data is available. ```APIDOC ## IMURead - Read Sensor Data ### Description The `IMURead()` method reads raw sensor data from the IMU and runs it through the Kalman filter to produce fused pose data. Returns `true` if new data is available, `false` otherwise. Should be called in a polling loop at the interval returned by `IMUGetPollInterval()`. ### Method Instance Method ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include "RTIMULib.h" int main() { RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); RTIMU *imu = RTIMU::createIMU(settings); if (imu == NULL || !imu->IMUInit()) { printf("IMU setup failed\n"); exit(1); } int sampleCount = 0; uint64_t startTime = RTMath::currentUSecsSinceEpoch(); while (sampleCount < 100) { // Poll at recommended interval usleep(imu->IMUGetPollInterval() * 1000); // Read returns true when new data is available while (imu->IMURead()) { RTIMU_DATA imuData = imu->getIMUData(); sampleCount++; // Display Euler angles in degrees printf("Roll: %6.2f Pitch: %6.2f Yaw: %6.2f\r", imuData.fusionPose.x() * RTMATH_RAD_TO_DEGREE, imuData.fusionPose.y() * RTMATH_RAD_TO_DEGREE, imuData.fusionPose.z() * RTMATH_RAD_TO_DEGREE); } } uint64_t elapsed = RTMath::currentUSecsSinceEpoch() - startTime; printf("\nSample rate: %.1f samples/sec\n", sampleCount * 1000000.0 / elapsed); // Expected output: // Roll: -2.34 Pitch: 1.56 Yaw: 45.23 // Sample rate: 50.0 samples/sec delete imu; delete settings; return 0; } ``` ### Response #### Success Response (Data Available) - **true** - Indicates new sensor data is available and has been processed. #### Success Response (No New Data) - **false** - Indicates no new sensor data is available since the last call. #### Response Example ``` Roll: -2.34 Pitch: 1.56 Yaw: 45.23 Sample rate: 50.0 samples/sec ``` ``` -------------------------------- ### RTIMU::setCalibrationData Source: https://context7.com/smukkejohan/rtimulib/llms.txt Configures compass calibration parameters to correct for hard-iron distortions by applying min/max axis readings. ```APIDOC ## RTIMU::setCalibrationData ### Description Configures compass calibration parameters to correct for hard-iron distortions. Calibration involves capturing min/max readings while rotating the IMU through all orientations. ### Parameters - **enable** (bool) - Required - Enables or disables the calibration data. - **min** (RTVector3) - Required - The minimum compass readings observed during calibration. - **max** (RTVector3) - Required - The maximum compass readings observed during calibration. ``` -------------------------------- ### Discover IMU on I2C Bus Source: https://context7.com/smukkejohan/rtimulib/llms.txt Scans the I2C bus to find supported IMU chips and their addresses. Automatically configures the RTIMUSettings with the discovered IMU type and address, then saves these settings. ```cpp #include "RTIMULib.h" int main() { RTIMUSettings *settings = new RTIMUSettings("RTIMULib"); int imuType; unsigned char slaveAddress; // Scan I2C bus for supported IMUs if (settings->discoverIMU(imuType, slaveAddress)) { printf("Found IMU type %d at I2C address 0x%02x\n", imuType, slaveAddress); switch (imuType) { case RTIMU_TYPE_MPU9150: printf("Detected: InvenSense MPU9150\n"); break; case RTIMU_TYPE_GD20M303: printf("Detected: STM L3GD20H/LSM303D\n"); break; } // Update settings with discovered values settings->m_imuType = imuType; settings->m_I2CSlaveAddress = slaveAddress; settings->saveSettings(); } else { printf("No supported IMU found on I2C bus\n"); } // Expected output: // Found IMU type 2 at I2C address 0x68 // Detected: InvenSense MPU9150 delete settings; return 0; } ``` -------------------------------- ### RTVector3 and RTQuaternion Math Operations Source: https://context7.com/smukkejohan/rtimulib/llms.txt Utilize RTVector3 for 3D vectors (Euler angles, sensor data) and RTQuaternion for rotation representation. Supports normalization, conversions, and arithmetic operations. ```cpp #include "RTIMULib.h" void demonstrateMathClasses() { // RTVector3 - 3D vector for Euler angles, sensor data, etc. RTVector3 euler(0.1, 0.2, 0.3); // roll, pitch, yaw in radians printf("Euler angles: %s\n", euler.display()); printf("In degrees: %s\n", euler.displayDegrees()); // Vector operations RTVector3 v1(1.0, 2.0, 3.0); RTVector3 v2(4.0, 5.0, 6.0); float dot = RTVector3::dotProduct(v1, v2); printf("Dot product: %.2f\n", dot); // 32.00 RTVector3 cross; RTVector3::crossProduct(v1, v2, cross); printf("Cross product: %s\n", cross.display()); // Normalize vector v1.normalize(); printf("Normalized v1: %s\n", v1.display()); // RTQuaternion - rotation representation RTQuaternion q; q.fromEuler(euler); // Convert Euler to quaternion printf("Quaternion: %s\n", q.display()); // Quaternion operations q.normalize(); RTQuaternion qConj = q.conjugate(); printf("Conjugate: %s\n", qConj.display()); // Convert back to Euler angles RTVector3 eulerBack; q.toEuler(eulerBack); printf("Back to Euler: %s\n", eulerBack.displayDegrees()); // Quaternion multiplication (combining rotations) RTQuaternion q1(1.0, 0.0, 0.0, 0.0); // Identity RTQuaternion q2; RTVector3 rot90(0, 0, M_PI/2); // 90 deg yaw q2.fromEuler(rot90); RTQuaternion combined = q1 * q2; printf("Combined rotation: %s\n", combined.display()); // Angle-axis representation RTFLOAT angle; RTVector3 axis; combined.toAngleVector(angle, axis); printf("Angle: %.2f deg, Axis: %s\n", angle * RTMATH_RAD_TO_DEGREE, axis.display()); } ``` -------------------------------- ### getIMUData - Access Fused Sensor Data Source: https://context7.com/smukkejohan/rtimulib/llms.txt Retrieves a structure containing raw sensor readings and Kalman-filtered fusion results, including quaternion and Euler angle pose data with timestamps. ```APIDOC ## getIMUData - Access Fused Sensor Data ### Description The `getIMUData()` method returns an `RTIMU_DATA` structure containing all raw sensor readings plus Kalman-filtered fusion results including quaternion and Euler angle pose data with timestamps. ### Method GET (conceptual, as it's a method call within the library) ### Endpoint N/A (This is a library method, not a network endpoint) ### Parameters None ### Request Example ```cpp #include "RTIMULib.h" void processIMUData(RTIMU *imu) { if (!imu->IMURead()) return; const RTIMU_DATA& data = imu->getIMUData(); // ... process data fields ... } ``` ### Response #### Success Response (RTIMU_DATA) - **timestamp** (uint64_t) - Microseconds since epoch - **fusionPoseValid** (bool) - True if fusion Euler angles valid - **fusionPose** (RTVector3) - Fused Euler angles (roll, pitch, yaw) in radians - **fusionQPoseValid** (bool) - True if fusion quaternion valid - **fusionQPose** (RTQuaternion) - Fused quaternion pose - **gyroValid** (bool) - True if gyro data valid - **gyro** (RTVector3) - Gyro rates (x, y, z) in radians/sec - **accelValid** (bool) - True if accelerometer data valid - **accel** (RTVector3) - Acceleration (x, y, z) in g units - **compassValid** (bool) - True if compass data valid - **compass** (RTVector3) - Magnetometer (x, y, z) in uT #### Response Example ```json { "timestamp": 1678886400000000, "fusionPoseValid": true, "fusionPose": {"x": 0.02146, "y": 0.04276, "z": 2.23183}, "fusionQPoseValid": true, "fusionQPose": {"scalar": 0.8536, "x": -0.0107, "y": 0.0214, "z": 0.5202}, "gyroValid": true, "gyro": {"x": 0.0012, "y": -0.0008, "z": 0.0003}, "accelValid": true, "accel": {"x": 0.0215, "y": -0.0428, "z": 0.9991}, "compassValid": true, "compass": {"x": 23.45, "y": -12.67, "z": 45.23} } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.