Exemple #1
0
void IMU::SetYawPitchRoll(float yaw, float pitch, float roll, float compass_heading)
{
        {
                Synchronized sync(cIMUStateSemaphore);

                this->yaw = yaw;
                this->pitch = pitch;
                this->roll = roll;
                this->compass_heading = compass_heading;
        }
        UpdateYawHistory(this->yaw);
}
Exemple #2
0
void IMU::SetYawPitchRoll(float yaw, float pitch, float roll, float compass_heading)
{
	{
		//Synchronized sync(cIMUStateSemaphore);
        std::lock_guard<std::mutex> lock(mutex1);
		
		this->yaw = yaw;
		this->pitch = pitch;
		this->roll = roll;
		this->compass_heading = compass_heading;
	}
	UpdateYawHistory(this->yaw);
}
Exemple #3
0
void IMU::SetYawPitchRoll(float yaw, float pitch, float roll, float compass_heading)
{
    {
        Synchronized sync(cIMUStateSemaphore);

        float last_offset_corrected_yaw = GetYawUnsynchronized();

        float last_yaw = this->yaw + 180.0f;
        float curr_yaw = yaw + 180.0f;
        float delta_yaw = curr_yaw - last_yaw;
        this->last_yaw_rate = delta_yaw;

        yaw_last_direction = 0;
        if ( curr_yaw < last_yaw ) {
            if ( delta_yaw < 180.0f ) {
                yaw_last_direction = -1;
            } else {
                yaw_last_direction = 1;
            }
        } else if ( curr_yaw > last_yaw ) {
            if ( delta_yaw > 180.0f ) {
                yaw_last_direction = -1;
            } else {
                yaw_last_direction = 1;
            }
        }

        this->yaw = yaw;
        this->pitch = pitch;
        this->roll = roll;
        this->compass_heading = compass_heading;

        float curr_offset_corrected_yaw = GetYawUnsynchronized();

        if ( yaw_last_direction < 0 ) {
            if ( ( curr_offset_corrected_yaw < 0.0f ) && ( last_offset_corrected_yaw >= 0.0f ) ) {
                yaw_crossing_count--;
            }
        } else if ( yaw_last_direction > 0 ) {
            if ( ( curr_offset_corrected_yaw >= 0.0f ) && ( last_offset_corrected_yaw < 0.0f ) ) {
                yaw_crossing_count++;
            }
        }

    }
    UpdateYawHistory(this->yaw);
}
Exemple #4
0
void IMUAdvanced::SetQuaternion( int16_t quat1, int16_t quat2, int16_t quat3, int16_t quat4,
					int16_t accel_x, int16_t accel_y, int16_t accel_z,
					int16_t mag_x, int16_t mag_y, int16_t mag_z,
					float temp_c)
{
	{
		float q[4];				// Quaternion from IMU
		float gravity[3];		// Gravity Vector
		//float euler[3];			// Classic euler angle representation of quaternion
		float ypr[3];			// Angles in "Tait-Bryan" (yaw/pitch/roll) format
		float yaw_degrees;
		float pitch_degrees;
		float roll_degrees;
		float linear_acceleration_x;
		float linear_acceleration_y;
		float linear_acceleration_z;
        float q2[4];
        float q_product[4];
		float world_linear_acceleration_x;
		float world_linear_acceleration_y;
		float world_linear_acceleration_z;
        
		// Convert 15-bit signed quaternion integral values to floats
		q[0] = ((float)quat1) / 16384.0f;
		q[1] = ((float)quat2) / 16384.0f;
		q[2] = ((float)quat3) / 16384.0f;
        q[3] = ((float)quat4) / 16384.0f;
        
        // Fixup any quaternion values out of range
        for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];

        // below calculations are necessary for calculation of yaw/pitch/roll, 
        // and tilt-compensated compass heading
        
        // calculate gravity vector
        gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
        gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
        gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
        
        // calculate Euler angles
        // This code is here for reference, and is commented out for performance reasons
        //euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
        //euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
        //euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);

        // calculate yaw/pitch/roll angles
        ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
        ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
        ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));

        // Convert yaw/pitch/roll angles to degreess, and remove calibrated offset
        
        yaw_degrees = ypr[0] * (180.0/3.1415926); 
        pitch_degrees = ypr[1] * (180.0/3.1415926); 
        roll_degrees = ypr[2] * (180.0/3.1415926); 
         
        // Subtract offset, and handle potential 360 degree wrap-around
        yaw_degrees -= yaw_offset_degrees;
        if ( yaw_degrees < -180 ) yaw_degrees += 360;
        if ( yaw_degrees > 180 ) yaw_degrees -= 360;

        // calculate linear acceleration by 
        // removing the gravity component from raw acceleration values
        // Note that this code assumes the acceleration full scale range
        // is +/- 2 degrees
         
        linear_acceleration_x = (float)(((float)accel_x) / (32768.0 / (float)accel_fsr_g)) - gravity[0];
        linear_acceleration_y = (float)(((float)accel_y) / (32768.0 / (float)accel_fsr_g)) - gravity[1];
        linear_acceleration_z = (float)(((float)accel_z) / (32768.0 / (float)accel_fsr_g)) - gravity[2]; 
        
        // Calculate world-frame acceleration
        
        q2[0] = 0;
        q2[1] = linear_acceleration_x;
        q2[2] = linear_acceleration_y;
        q2[3] = linear_acceleration_z;
        
        // Rotate linear acceleration so that it's relative to the world reference frame
        
        // http://www.cprogramming.com/tutorial/3d/quaternions.html
        // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm
        // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
        // ^ or: http://webcache.googleusercontent.com/search?q=cache:xgJAp3bDNhQJ:content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation&hl=en&gl=us&strip=1
    
        // P_out = q * P_in * conj(q)
        // - P_out is the output vector
        // - q is the orientation quaternion
        // - P_in is the input vector (a*aReal)
        // - conj(q) is the conjugate of the orientation quaternion (q=[w,x,y,z], q*=[w,-x,-y,-z])

        // calculate quaternion product
        // Quaternion multiplication is defined by:
        //     (Q1 * Q2).w = (w1w2 - x1x2 - y1y2 - z1z2)
        //     (Q1 * Q2).x = (w1x2 + x1w2 + y1z2 - z1y2)
        //     (Q1 * Q2).y = (w1y2 - x1z2 + y1w2 + z1x2)
        //     (Q1 * Q2).z = (w1z2 + x1y2 - y1x2 + z1w2
        
        q_product[0] = q[0]*q2[0] - q[1]*q2[1] - q[2]*q2[2] - q[3]*q2[3];  // new w
        q_product[1] = q[0]*q2[1] + q[1]*q2[0] + q[2]*q2[3] - q[3]*q2[2];  // new x
        q_product[2] = q[0]*q2[2] - q[1]*q2[3] + q[2]*q2[0] + q[3]*q2[1];  // new y 
        q_product[3] = q[0]*q2[3] + q[1]*q2[2] - q[2]*q2[1] + q[3]*q2[0];  // new z

        float q_conjugate[4];
        
        q_conjugate[0] = q[0];            
        q_conjugate[1] = -q[1];            
        q_conjugate[2] = -q[2];            
        q_conjugate[3] = -q[3];            

        float q_final[4];
        
        q_final[0] = q_product[0]*q_conjugate[0] - q_product[1]*q_conjugate[1] - q_product[2]*q_conjugate[2] - q_product[3]*q_conjugate[3];  // new w
        q_final[1] = q_product[0]*q_conjugate[1] + q_product[1]*q_conjugate[0] + q_product[2]*q_conjugate[3] - q_product[3]*q_conjugate[2];  // new x
        q_final[2] = q_product[0]*q_conjugate[2] - q_product[1]*q_conjugate[3] + q_product[2]*q_conjugate[0] + q_product[3]*q_conjugate[1];  // new y 
        q_final[3] = q_product[0]*q_conjugate[3] + q_product[1]*q_conjugate[2] - q_product[2]*q_conjugate[1] + q_product[3]*q_conjugate[0];  // new z

        world_linear_acceleration_x = q_final[1];
        world_linear_acceleration_y = q_final[2];
        world_linear_acceleration_z = q_final[3];
        
        // Calculate tilt-compensated compass heading
        
        float inverted_pitch = -ypr[1];
        float roll = ypr[2];
        
        float cos_roll = cos(roll);
        float sin_roll = sin(roll);
        float cos_pitch = cos(inverted_pitch);
        float sin_pitch = sin(inverted_pitch);
        
        float MAG_X = mag_x * cos_pitch + mag_z * sin_pitch;
        float MAG_Y = mag_x * sin_roll * sin_pitch + mag_y * cos_roll - mag_z * sin_roll * cos_pitch;
        float tilt_compensated_heading_radians = atan2(MAG_Y,MAG_X);
        float tilt_compensated_heading_degrees = tilt_compensated_heading_radians * (180.0 / 3.1415926);
        
        // Adjust compass for board orientation,
        // and modify range from -180-180 to
        // 0-360 degrees
      
        tilt_compensated_heading_degrees -= 90.0;
        if ( tilt_compensated_heading_degrees < 0 ) {
          tilt_compensated_heading_degrees += 360; 
        }

		this->yaw = yaw_degrees;
		this->pitch = pitch_degrees;
		this->roll = roll_degrees;
		this->compass_heading = tilt_compensated_heading_degrees;
        
		this->world_linear_accel_x = world_linear_acceleration_x;
		this->world_linear_accel_y = world_linear_acceleration_y;
		this->world_linear_accel_z = world_linear_acceleration_z;
		this->temp_c = temp_c;
		
		UpdateYawHistory(this->yaw);
		UpdateWorldLinearAccelHistory( world_linear_acceleration_x, world_linear_acceleration_y, world_linear_acceleration_z);
	}	
}
int AHRS::DecodePacketHandler( char *received_data, int bytes_remaining )
{
        float yaw, pitch, roll, compass_heading;
        float altitude, fused_heading, linear_accel_x, linear_accel_y, linear_accel_z;
        float mpu_temp;
        int16_t raw_mag_x, raw_mag_y, raw_mag_z;
        int16_t cal_mag_x, cal_mag_y, cal_mag_z;
        float mag_norm_ratio, mag_norm_scalar;
        int16_t quat_w, quat_x, quat_y, quat_z;
        float baro_pressure, baro_temp;
        uint8_t op_status, sensor_status;
        uint8_t cal_status, selftest_status;

        int packet_length = AHRSProtocol::decodeAHRSUpdate(     received_data, bytes_remaining,
                                                                                                                yaw,
                                                                                                                pitch,
                                                                                                                roll,
                                                                                                                compass_heading,
                                                                                                                altitude,
                                                                                                                fused_heading,
                                                                                                                linear_accel_x,
                                                                                                                linear_accel_y,
                                                                                                                linear_accel_z,
                                                                                                                mpu_temp,
                                                                                                                raw_mag_x,
                                                                                                                raw_mag_y,
                                                                                                                raw_mag_z,
                                                                                                                cal_mag_x,
                                                                                                                cal_mag_y,
                                                                                                                cal_mag_z,
                                                                                                                mag_norm_ratio,
                                                                                                                mag_norm_scalar,
                                                                                                                quat_w,
                                                                                                                quat_x,
                                                                                                                quat_y,
                                                                                                                quat_z,
                                                                                                                baro_pressure,
                                                                                                                baro_temp,
                                                                                                                op_status,
                                                                                                                sensor_status,
                                                                                                                cal_status,
                                                                                                                selftest_status);
        if (packet_length > 0) {
                /* Update base IMU class variables */

                this->yaw = yaw;
                this->pitch = pitch;
                this->roll = roll;
                this->compass_heading = compass_heading;
                UpdateYawHistory(yaw);

                /* Update AHRS class variables */

                // 9-axis data
                this->fused_heading                     = fused_heading;

                // Gravity-corrected linear acceleration (world-frame)
                this->world_linear_accel_x      = linear_accel_x;
                this->world_linear_accel_y      = linear_accel_y;
                this->world_linear_accel_z      = linear_accel_z;

                // Gyro/Accelerometer Die Temperature
                this->mpu_temp_c                        = mpu_temp;

                // Barometric Pressure/Altitude
                this->altitude                          = altitude;
                this->barometric_pressure       = baro_pressure;
                this->baro_sensor_temp_c        = baro_temp;

                // Magnetometer Data
                this->cal_mag_x                         = cal_mag_x;
                this->cal_mag_y                         = cal_mag_y;
                this->cal_mag_z                         = cal_mag_z;
                this->mag_field_norm_ratio      = mag_field_norm_ratio;

                // Status/Motion Detection
                this->is_moving                                         =
                                (((sensor_status &
                                                NAVX_SENSOR_STATUS_MOVING) != 0)
                                                ? true : false);
                this->is_rotating                                       =
                                (((sensor_status &
                                                NAVX_SENSOR_STATUS_YAW_STABLE) != 0)
                                                ? true : false);
                this->altitude_valid                            =
                                (((sensor_status &
                                                NAVX_SENSOR_STATUS_ALTITUDE_VALID) != 0)
                                                ? true : false);
                this->is_magnetometer_calibrated        =
                                (((cal_status &
                                                NAVX_CAL_STATUS_MAG_CAL_COMPLETE) != 0)
                                                ? true : false);
                this->magnetic_disturbance                      =
                                (((sensor_status &
                                                NAVX_SENSOR_STATUS_MAG_DISTURBANCE) != 0)
                                                ? true : false);

                UpdateDisplacement( this->world_linear_accel_x,
                                this->world_linear_accel_y,
                                update_rate_hz,
                                this->is_moving);
        }
        return packet_length;
}