void parse_ins_msg( void ) { uint8_t offset = 0; if (xsens_id == XSENS_ReqOutputModeAck_ID) { xsens_output_mode = XSENS_ReqOutputModeAck_mode(xsens_msg_buf); } else if (xsens_id == XSENS_ReqOutputSettings_ID) { xsens_output_settings = XSENS_ReqOutputSettingsAck_settings(xsens_msg_buf); } else if (xsens_id == XSENS_ReqMagneticDeclinationAck_ID) { xsens_declination = DegOfRad (XSENS_ReqMagneticDeclinationAck_declination(xsens_msg_buf) ); DOWNLINK_SEND_IMU_MAG_SETTINGS(DefaultChannel,&xsens_declination,&xsens_declination,&xsens_gps_arm_x,&xsens_gps_arm_y,&xsens_gps_arm_z); } else if (xsens_id == XSENS_ReqLeverArmGpsAck_ID) { xsens_gps_arm_x = XSENS_ReqLeverArmGpsAck_x(xsens_msg_buf); xsens_gps_arm_y = XSENS_ReqLeverArmGpsAck_y(xsens_msg_buf); xsens_gps_arm_z = XSENS_ReqLeverArmGpsAck_z(xsens_msg_buf); DOWNLINK_SEND_IMU_MAG_SETTINGS(DefaultChannel,&xsens_declination,&xsens_declination,&xsens_gps_arm_x,&xsens_gps_arm_y,&xsens_gps_arm_z); } else if (xsens_id == XSENS_Error_ID) { xsens_errorcode = XSENS_Error_errorcode(xsens_msg_buf); } #ifdef USE_GPS_XSENS else if (xsens_id == XSENS_GPSStatus_ID) { gps.nb_channels = XSENS_GPSStatus_nch(xsens_msg_buf); gps.num_sv = 0; gps.last_fix_time = cpu_time_sec; uint8_t i; // Do not write outside buffer for(i = 0; i < Min(gps.nb_channels, GPS_NB_CHANNELS); i++) { uint8_t ch = XSENS_GPSStatus_chn(xsens_msg_buf,i); if (ch > gps.nb_channels) continue; gps.svinfos[ch].svid = XSENS_GPSStatus_svid(xsens_msg_buf, i); gps.svinfos[ch].flags = XSENS_GPSStatus_bitmask(xsens_msg_buf, i); gps.svinfos[ch].qi = XSENS_GPSStatus_qi(xsens_msg_buf, i); gps.svinfos[ch].cno = XSENS_GPSStatus_cnr(xsens_msg_buf, i); if (gps.svinfos[ch].flags > 0) { gps.num_sv++; } } } #endif else if (xsens_id == XSENS_MTData_ID) { /* test RAW modes else calibrated modes */ //if ((XSENS_MASK_RAWInertial(xsens_output_mode)) || (XSENS_MASK_RAWGPS(xsens_output_mode))) { if (XSENS_MASK_RAWInertial(xsens_output_mode)) { ins_p = XSENS_DATA_RAWInertial_gyrX(xsens_msg_buf,offset); ins_q = XSENS_DATA_RAWInertial_gyrY(xsens_msg_buf,offset); ins_r = XSENS_DATA_RAWInertial_gyrZ(xsens_msg_buf,offset); offset += XSENS_DATA_RAWInertial_LENGTH; } if (XSENS_MASK_RAWGPS(xsens_output_mode)) { #if defined(USE_GPS_XSENS_RAW_DATA) && defined(USE_GPS_XSENS) #ifdef GPS_LED LED_TOGGLE(GPS_LED); #endif gps.last_fix_time = cpu_time_sec; gps.week = 0; // FIXME gps.tow = XSENS_DATA_RAWGPS_itow(xsens_msg_buf,offset) * 10; gps.lla_pos.lat = RadOfDeg(XSENS_DATA_RAWGPS_lat(xsens_msg_buf,offset)); gps.lla_pos.lon = RadOfDeg(XSENS_DATA_RAWGPS_lon(xsens_msg_buf,offset)); gps.lla_pos.alt = XSENS_DATA_RAWGPS_alt(xsens_msg_buf,offset); /* Set the real UTM zone */ gps.utm_pos.zone = (DegOfRad(gps.lla_pos.lon/1e7)+180) / 6 + 1; lla_f.lat = ((float) gps.lla_pos.lat) / 1e7; lla_f.lon = ((float) gps.lla_pos.lon) / 1e7; utm_f.zone = nav_utm_zone0; /* convert to utm */ utm_of_lla_f(&utm_f, &lla_f); /* copy results of utm conversion */ gps.utm_pos.east = utm_f.east*100; gps.utm_pos.north = utm_f.north*100; gps.utm_pos.alt = gps.lla_pos.alt; ins_x = utm_f.east; ins_y = utm_f.north; // Altitude: Xsens LLH gives ellipsoid height ins_z = -(INS_FORMAT)XSENS_DATA_RAWGPS_alt(xsens_msg_buf,offset) / 1000.; // Compute geoid (MSL) height float hmsl; WGS84_ELLIPSOID_TO_GEOID(lla_f.lat,lla_f.lon,hmsl); gps.hmsl = XSENS_DATA_RAWGPS_alt(xsens_msg_buf,offset) - (hmsl * 1000.0f); ins_vx = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf,offset)) / 100.; ins_vy = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf,offset)) / 100.; ins_vz = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf,offset)) / 100.; gps.ned_vel.x = XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf,offset); gps.ned_vel.y = XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf,offset); gps.ned_vel.z = XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf,offset); gps.pacc = XSENS_DATA_RAWGPS_hacc(xsens_msg_buf,offset) / 100; gps.sacc = XSENS_DATA_RAWGPS_sacc(xsens_msg_buf,offset) / 100; gps.pdop = 5; // FIXME Not output by XSens #endif offset += XSENS_DATA_RAWGPS_LENGTH; } //} else { if (XSENS_MASK_Temp(xsens_output_mode)) { offset += XSENS_DATA_Temp_LENGTH; } if (XSENS_MASK_Calibrated(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_AccOut(xsens_output_settings)) { ins_ax = XSENS_DATA_Calibrated_accX(xsens_msg_buf,offset); ins_ay = XSENS_DATA_Calibrated_accY(xsens_msg_buf,offset); ins_az = XSENS_DATA_Calibrated_accZ(xsens_msg_buf,offset); l++; } if (!XSENS_MASK_GyrOut(xsens_output_settings)) { ins_p = XSENS_DATA_Calibrated_gyrX(xsens_msg_buf,offset); ins_q = XSENS_DATA_Calibrated_gyrY(xsens_msg_buf,offset); ins_r = XSENS_DATA_Calibrated_gyrZ(xsens_msg_buf,offset); l++; } if (!XSENS_MASK_MagOut(xsens_output_settings)) { ins_mx = XSENS_DATA_Calibrated_magX(xsens_msg_buf,offset); ins_my = XSENS_DATA_Calibrated_magY(xsens_msg_buf,offset); ins_mz = XSENS_DATA_Calibrated_magZ(xsens_msg_buf,offset); l++; } offset += l * XSENS_DATA_Calibrated_LENGTH / 3; } if (XSENS_MASK_Orientation(xsens_output_mode)) { if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x00) { float q0 = XSENS_DATA_Quaternion_q0(xsens_msg_buf,offset); float q1 = XSENS_DATA_Quaternion_q1(xsens_msg_buf,offset); float q2 = XSENS_DATA_Quaternion_q2(xsens_msg_buf,offset); float q3 = XSENS_DATA_Quaternion_q3(xsens_msg_buf,offset); float dcm00 = 1.0 - 2 * (q2*q2 + q3*q3); float dcm01 = 2 * (q1*q2 + q0*q3); float dcm02 = 2 * (q1*q3 - q0*q2); float dcm12 = 2 * (q2*q3 + q0*q1); float dcm22 = 1.0 - 2 * (q1*q1 + q2*q2); ins_phi = atan2(dcm12, dcm22); ins_theta = -asin(dcm02); ins_psi = atan2(dcm01, dcm00); offset += XSENS_DATA_Quaternion_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x01) { ins_phi = XSENS_DATA_Euler_roll(xsens_msg_buf,offset) * M_PI / 180; ins_theta = XSENS_DATA_Euler_pitch(xsens_msg_buf,offset) * M_PI / 180; ins_psi = XSENS_DATA_Euler_yaw(xsens_msg_buf,offset) * M_PI / 180; offset += XSENS_DATA_Euler_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x10) { offset += XSENS_DATA_Matrix_LENGTH; } new_ins_attitude = 1; } if (XSENS_MASK_Auxiliary(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_Aux1Out(xsens_output_settings)) { l++; } if (!XSENS_MASK_Aux2Out(xsens_output_settings)) { l++; } offset += l * XSENS_DATA_Auxiliary_LENGTH / 2; } if (XSENS_MASK_Position(xsens_output_mode)) { #if (!defined(USE_GPS_XSENS_RAW_DATA)) && defined(USE_GPS_XSENS) gps.last_fix_time = cpu_time_sec; lla_f.lat = RadOfDeg(XSENS_DATA_Position_lat(xsens_msg_buf,offset)); lla_f.lon = RadOfDeg(XSENS_DATA_Position_lon(xsens_msg_buf,offset)); gps.lla_pos.lat = (int32_t)(lla_f.lat * 1e7); gps.lla_pos.lon = (int32_t)(lla_f.lon * 1e7); gps.utm_pos.zone = (DegOfRad(lla_f.lon)+180) / 6 + 1; /* convert to utm */ utm_of_lla_f(&utm_f, &lla_f); /* copy results of utm conversion */ gps.utm_pos.east = utm_f.east*100; gps.utm_pos.north = utm_f.north*100; ins_x = utm_f.east; ins_y = utm_f.north; ins_z = XSENS_DATA_Position_alt(xsens_msg_buf,offset);//TODO is this hms or above ellipsoid? gps.hmsl = ins_z * 1000; #endif offset += XSENS_DATA_Position_LENGTH; } if (XSENS_MASK_Velocity(xsens_output_mode)) { #if (!defined(USE_GPS_XSENS_RAW_DATA)) && defined(USE_GPS_XSENS) ins_vx = XSENS_DATA_Velocity_vx(xsens_msg_buf,offset); ins_vy = XSENS_DATA_Velocity_vy(xsens_msg_buf,offset); ins_vz = XSENS_DATA_Velocity_vz(xsens_msg_buf,offset); #endif offset += XSENS_DATA_Velocity_LENGTH; } if (XSENS_MASK_Status(xsens_output_mode)) { xsens_msg_status = XSENS_DATA_Status_status(xsens_msg_buf,offset); #ifdef USE_GPS_XSENS if (bit_is_set(xsens_msg_status,2)) gps.fix = GPS_FIX_3D; // gps fix else if (bit_is_set(xsens_msg_status,1)) gps.fix = 0x01; // efk valid else gps.fix = GPS_FIX_NONE; #endif offset += XSENS_DATA_Status_LENGTH; } if (XSENS_MASK_TimeStamp(xsens_output_settings)) { xsens_time_stamp = XSENS_DATA_TimeStamp_ts(xsens_msg_buf,offset); #ifdef USE_GPS_XSENS gps.tow = xsens_time_stamp; #endif offset += XSENS_DATA_TimeStamp_LENGTH; } if (XSENS_MASK_UTC(xsens_output_settings)) { xsens_hour = XSENS_DATA_UTC_hour(xsens_msg_buf,offset); xsens_min = XSENS_DATA_UTC_min(xsens_msg_buf,offset); xsens_sec = XSENS_DATA_UTC_sec(xsens_msg_buf,offset); xsens_nanosec = XSENS_DATA_UTC_nanosec(xsens_msg_buf,offset); xsens_year = XSENS_DATA_UTC_year(xsens_msg_buf,offset); xsens_month = XSENS_DATA_UTC_month(xsens_msg_buf,offset); xsens_day = XSENS_DATA_UTC_day(xsens_msg_buf,offset); offset += XSENS_DATA_UTC_LENGTH; } //} } }
// Called after receipt of valid message to void xsens_parse_msg( uint8_t xsens_id ) { uint8_t buf_slot = xsens_msg_buf_ci[xsens_id]; if (msg_id[xsens_id][buf_slot] == XSENS_ReqOutputModeAck_ID) { xsens_output_mode[xsens_id] = XSENS_ReqOutputModeAck_mode(xsens_msg_buf[xsens_id]); } else if (msg_id[xsens_id][buf_slot] == XSENS_Error_ID) { xsens_errorcode[xsens_id] = XSENS_Error_errorcode(xsens_msg_buf[xsens_id]); } else if (msg_id[xsens_id][buf_slot] == XSENS_MTData_ID) { uint8_t offset = 0; // test RAW modes else calibrated modes if (XSENS_MASK_RAWInertial(xsens_output_mode[xsens_id])){// || (XSENS_MASK_RAWGPS(xsens2_output_mode))) { xsens_raw_accel_x[xsens_id] = XSENS_DATA_RAWInertial_accX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_accel_y[xsens_id] = XSENS_DATA_RAWInertial_accY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_accel_z[xsens_id] = XSENS_DATA_RAWInertial_accZ(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_gyro_x[xsens_id] = XSENS_DATA_RAWInertial_gyrX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_gyro_y[xsens_id] = XSENS_DATA_RAWInertial_gyrY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_gyro_z[xsens_id] = XSENS_DATA_RAWInertial_gyrZ(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_mag_x[xsens_id] = XSENS_DATA_RAWInertial_magX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_mag_y[xsens_id] = XSENS_DATA_RAWInertial_magY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_raw_mag_z[xsens_id] = XSENS_DATA_RAWInertial_magZ(xsens_msg_buf[xsens_id][buf_slot],offset); } if (XSENS_MASK_Temp(xsens_output_mode[xsens_id])) { offset += XSENS_DATA_Temp_LENGTH; } if (XSENS_MASK_Calibrated(xsens_output_mode[xsens_id])) { if (XSENS_MASK_AccOut(xsens_output_settings[xsens_id])) { xsens_accel_x[xsens_id] = XSENS_DATA_Calibrated_accX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_accel_y[xsens_id] = XSENS_DATA_Calibrated_accY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_accel_z[xsens_id] = XSENS_DATA_Calibrated_accZ(xsens_msg_buf[xsens_id][buf_slot],offset); } if (XSENS_MASK_GyrOut(xsens_output_settings[xsens_id])) { xsens_gyro_x[xsens_id] = XSENS_DATA_Calibrated_gyrX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_gyro_y[xsens_id] = XSENS_DATA_Calibrated_gyrY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_gyro_z[xsens_id] = XSENS_DATA_Calibrated_gyrZ(xsens_msg_buf[xsens_id][buf_slot],offset); } if (XSENS_MASK_MagOut(xsens_output_settings[xsens_id])) { xsens_mag_x[xsens_id] = XSENS_DATA_Calibrated_magX(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_mag_y[xsens_id] = XSENS_DATA_Calibrated_magY(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_mag_z[xsens_id] = XSENS_DATA_Calibrated_magZ(xsens_msg_buf[xsens_id][buf_slot],offset); float pitch = xsens_phi[xsens_id]; float roll = -xsens_theta[xsens_id]; float tilt_comp_x = xsens_mag_x[xsens_id] * cos(pitch) + xsens_mag_y[xsens_id] * sin(roll) * sin(pitch) - xsens_mag_z[xsens_id] * cos(roll) * sin(pitch); float tilt_comp_y = xsens_mag_y[xsens_id] * cos(roll) + xsens_mag_z[xsens_id] * sin(roll); xsens_mag_heading[xsens_id] = -atan2( tilt_comp_y, tilt_comp_x); } offset += XSENS_DATA_Calibrated_LENGTH; } if (XSENS_MASK_Orientation(xsens_output_mode[xsens_id])) { if (XSENS_MASK_OrientationMode(xsens_output_settings[xsens_id]) == 0x0) { offset += XSENS_DATA_Quaternion_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings[xsens_id]) == 0x1) { xsens_phi[xsens_id] = XSENS_DATA_Euler_roll(xsens_msg_buf[xsens_id][buf_slot],offset) * M_PI/180; xsens_theta[xsens_id] =XSENS_DATA_Euler_pitch(xsens_msg_buf[xsens_id][buf_slot],offset) * M_PI/180; xsens_psi[xsens_id] = XSENS_DATA_Euler_yaw(xsens_msg_buf[xsens_id][buf_slot],offset) * M_PI/180; offset += XSENS_DATA_Euler_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings[xsens_id]) == 0x2) { xsens_rmat[xsens_id].m[0] = XSENS_DATA_Matrix_a(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[1] = XSENS_DATA_Matrix_b(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[2] = XSENS_DATA_Matrix_c(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[3] = XSENS_DATA_Matrix_d(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[4] = XSENS_DATA_Matrix_e(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[5] = XSENS_DATA_Matrix_f(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[6] = XSENS_DATA_Matrix_g(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[7] = XSENS_DATA_Matrix_h(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_rmat[xsens_id].m[8] = XSENS_DATA_Matrix_i(xsens_msg_buf[xsens_id][buf_slot],offset); /* // FLOAT_RMAT_COMP_INV(xsens_rmat_adj[xsens_id], xsens_rmat_neutral[xsens_id], xsens_rmat[xsens_id]); */ struct FloatRMat xsens_rmat_temp[XSENS_COUNT]; FLOAT_RMAT_INV(xsens_rmat_temp[xsens_id], xsens_rmat[xsens_id]); FLOAT_RMAT_COMP(xsens_rmat_adj[xsens_id], xsens_rmat_temp[xsens_id], xsens_rmat_neutral[xsens_id]); xsens_phi[xsens_id] = -atan2(xsens_rmat_adj[xsens_id].m[7], xsens_rmat_adj[xsens_id].m[8]); xsens_theta[xsens_id] = asin(xsens_rmat_adj[xsens_id].m[6]); xsens_psi[xsens_id] = atan2(xsens_rmat_adj[xsens_id].m[3], xsens_rmat_adj[xsens_id].m[0]); xsens_psi[xsens_id] -= RadOfDeg(xsens_psi_offset[xsens_id]); /* FLOAT_RMAT_COMP(xsens_rmat_adj[xsens_id], xsens_rmat_neutral[xsens_id], xsens_rmat[xsens_id]); */ /* // Calculate roll, pitch, yaw from rotation matrix ( p 31-33 MTi-G USer Man and Tech Doc) */ /* xsens_phi[xsens_id] = -atan2 (xsens_rmat_adj[xsens_id].m[7], xsens_rmat_adj[xsens_id].m[8]); */ /* xsens_theta[xsens_id] = asin (xsens_rmat_adj[xsens_id].m[6]); */ /* xsens_psi[xsens_id] = atan2 (xsens_rmat_adj[xsens_id].m[3], xsens_rmat_adj[xsens_id].m[0]); */ offset += XSENS_DATA_Matrix_LENGTH; } } if (XSENS_MASK_Status(xsens_output_mode[xsens_id])) { xsens_msg_status[xsens_id] = XSENS_DATA_Status_status(xsens_msg_buf[xsens_id][buf_slot],offset); xsens_mode[xsens_id] = xsens_msg_status[xsens_id]; offset += XSENS_DATA_Status_LENGTH; } if (XSENS_MASK_TimeStamp(xsens_output_settings[xsens_id])) { uint16_t ts = XSENS_DATA_TimeStamp_ts(xsens_msg_buf[xsens_id][buf_slot],offset); if (xsens_time_stamp[xsens_id] + 1 != ts) //xsens_err_count[xsens_id]++; xsens_time_stamp[xsens_id] = ts; offset += XSENS_DATA_TimeStamp_LENGTH; } } }
void parse_ins_msg( void ) { uint8_t offset = 0; if (xsens_id == XSENS_ReqOutputModeAck_ID) { xsens_output_mode = XSENS_ReqOutputModeAck_mode(xsens_msg_buf); } else if (xsens_id == XSENS_ReqOutputSettings_ID) { xsens_output_settings = XSENS_ReqOutputSettingsAck_settings(xsens_msg_buf); } else if (xsens_id == XSENS_Error_ID) { xsens_errorcode = XSENS_Error_errorcode(xsens_msg_buf); } #ifdef USE_GPS_XSENS else if (xsens_id == XSENS_GPSStatus_ID) { gps_nb_channels = XSENS_GPSStatus_nch(xsens_msg_buf); gps_numSV = gps_nb_channels; uint8_t i; for(i = 0; i < Min(gps_nb_channels, GPS_NB_CHANNELS); i++) { uint8_t ch = XSENS_GPSStatus_chn(xsens_msg_buf,i); if (ch > GPS_NB_CHANNELS) continue; gps_svinfos[ch].svid = XSENS_GPSStatus_svid(xsens_msg_buf, i); gps_svinfos[ch].flags = XSENS_GPSStatus_bitmask(xsens_msg_buf, i); gps_svinfos[ch].qi = XSENS_GPSStatus_qi(xsens_msg_buf, i); gps_svinfos[ch].cno = XSENS_GPSStatus_cnr(xsens_msg_buf, i); } } #endif else if (xsens_id == XSENS_MTData_ID) { /* test RAW modes else calibrated modes */ //if ((XSENS_MASK_RAWInertial(xsens_output_mode)) || (XSENS_MASK_RAWGPS(xsens_output_mode))) { if (XSENS_MASK_RAWInertial(xsens_output_mode)) { ins_p = XSENS_DATA_RAWInertial_gyrX(xsens_msg_buf,offset); ins_q = XSENS_DATA_RAWInertial_gyrY(xsens_msg_buf,offset); ins_r = XSENS_DATA_RAWInertial_gyrZ(xsens_msg_buf,offset); offset += XSENS_DATA_RAWInertial_LENGTH; } if (XSENS_MASK_RAWGPS(xsens_output_mode)) { #if defined(USE_GPS_XSENS_RAW_DATA) && defined(USE_GPS_XSENS) gps_week = 0; // FIXME gps_itow = XSENS_DATA_RAWGPS_itow(xsens_msg_buf,offset) * 10; gps_lat = XSENS_DATA_RAWGPS_lat(xsens_msg_buf,offset); gps_lon = XSENS_DATA_RAWGPS_lon(xsens_msg_buf,offset); /* Set the real UTM zone */ gps_utm_zone = (gps_lon/1e7+180) / 6 + 1; latlong_utm_of(RadOfDeg(gps_lat/1e7), RadOfDeg(gps_lon/1e7), gps_utm_zone); /* utm */ gps_utm_east = latlong_utm_x * 100; gps_utm_north = latlong_utm_y * 100; ins_x = latlong_utm_x; ins_y = latlong_utm_y; gps_alt = XSENS_DATA_RAWGPS_alt(xsens_msg_buf,offset) / 10; ins_z = -(INS_FORMAT)gps_alt / 100.; ins_vx = (INS_FORMAT)XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf,offset) / 100.; ins_vy = (INS_FORMAT)XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf,offset) / 100.; ins_vz = (INS_FORMAT)XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf,offset) / 100.; gps_climb = -XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf,offset) / 10; gps_Pacc = XSENS_DATA_RAWGPS_hacc(xsens_msg_buf,offset) / 100; gps_Sacc = XSENS_DATA_RAWGPS_sacc(xsens_msg_buf,offset) / 100; gps_PDOP = 5; #endif offset += XSENS_DATA_RAWGPS_LENGTH; } //} else { if (XSENS_MASK_Temp(xsens_output_mode)) { offset += XSENS_DATA_Temp_LENGTH; } if (XSENS_MASK_Calibrated(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_AccOut(xsens_output_settings)) { ins_ax = XSENS_DATA_Calibrated_accX(xsens_msg_buf,offset); ins_ay = XSENS_DATA_Calibrated_accY(xsens_msg_buf,offset); ins_az = XSENS_DATA_Calibrated_accZ(xsens_msg_buf,offset); l++; } if (!XSENS_MASK_GyrOut(xsens_output_settings)) { ins_p = XSENS_DATA_Calibrated_gyrX(xsens_msg_buf,offset); ins_q = XSENS_DATA_Calibrated_gyrY(xsens_msg_buf,offset); ins_r = XSENS_DATA_Calibrated_gyrZ(xsens_msg_buf,offset); l++; } if (!XSENS_MASK_MagOut(xsens_output_settings)) { ins_mx = XSENS_DATA_Calibrated_magX(xsens_msg_buf,offset); ins_my = XSENS_DATA_Calibrated_magY(xsens_msg_buf,offset); ins_mz = XSENS_DATA_Calibrated_magZ(xsens_msg_buf,offset); l++; } offset += l * XSENS_DATA_Calibrated_LENGTH / 3; } if (XSENS_MASK_Orientation(xsens_output_mode)) { if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x00) { float q0 = XSENS_DATA_Quaternion_q0(xsens_msg_buf,offset); float q1 = XSENS_DATA_Quaternion_q1(xsens_msg_buf,offset); float q2 = XSENS_DATA_Quaternion_q2(xsens_msg_buf,offset); float q3 = XSENS_DATA_Quaternion_q3(xsens_msg_buf,offset); float dcm00 = 1.0 - 2 * (q2*q2 + q3*q3); float dcm01 = 2 * (q1*q2 + q0*q3); float dcm02 = 2 * (q1*q3 - q0*q2); float dcm12 = 2 * (q2*q3 + q0*q1); float dcm22 = 1.0 - 2 * (q1*q1 + q2*q2); ins_phi = atan2(dcm12, dcm22); ins_theta = -asin(dcm02); ins_psi = atan2(dcm01, dcm00); offset += XSENS_DATA_Quaternion_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x01) { ins_phi = XSENS_DATA_Euler_roll(xsens_msg_buf,offset) * M_PI / 180; ins_theta = XSENS_DATA_Euler_pitch(xsens_msg_buf,offset) * M_PI / 180; ins_psi = XSENS_DATA_Euler_yaw(xsens_msg_buf,offset) * M_PI / 180; offset += XSENS_DATA_Euler_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x10) { offset += XSENS_DATA_Matrix_LENGTH; } } if (XSENS_MASK_Auxiliary(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_Aux1Out(xsens_output_settings)) { l++; } if (!XSENS_MASK_Aux2Out(xsens_output_settings)) { l++; } offset += l * XSENS_DATA_Auxiliary_LENGTH / 2; } if (XSENS_MASK_Position(xsens_output_mode)) { #if (!defined(USE_GPS_XSENS_RAW_DATA)) && defined(USE_GPS_XSENS) xsens_lat = XSENS_DATA_Position_lat(xsens_msg_buf,offset); xsens_lon = XSENS_DATA_Position_lon(xsens_msg_buf,offset); gps_lat = (int32_t)(xsens_lat * 1e7); gps_lon = (int32_t)(xsens_lon * 1e7); gps_utm_zone = (xsens_lon+180) / 6 + 1; latlong_utm_of(RadOfDeg(xsens_lat), RadOfDeg(xsens_lon), gps_utm_zone); ins_x = latlong_utm_x; ins_y = latlong_utm_y; gps_utm_east = ins_x * 100; gps_utm_north = ins_y * 100; ins_z = XSENS_DATA_Position_alt(xsens_msg_buf,offset); gps_alt = ins_z * 100; #endif offset += XSENS_DATA_Position_LENGTH; } if (XSENS_MASK_Velocity(xsens_output_mode)) { #if (!defined(USE_GPS_XSENS_RAW_DATA)) && defined(USE_GPS_XSENS) ins_vx = XSENS_DATA_Velocity_vx(xsens_msg_buf,offset); ins_vy = XSENS_DATA_Velocity_vy(xsens_msg_buf,offset); ins_vz = XSENS_DATA_Velocity_vz(xsens_msg_buf,offset); #endif offset += XSENS_DATA_Velocity_LENGTH; } if (XSENS_MASK_Status(xsens_output_mode)) { xsens_msg_status = XSENS_DATA_Status_status(xsens_msg_buf,offset); #ifdef USE_GPS_XSENS if (bit_is_set(xsens_msg_status,2)) gps_mode = 0x03; // gps fix else if (bit_is_set(xsens_msg_status,1)) gps_mode = 0x01; // efk valid else gps_mode = 0; #endif offset += XSENS_DATA_Status_LENGTH; } if (XSENS_MASK_TimeStamp(xsens_output_settings)) { xsens_time_stamp = XSENS_DATA_TimeStamp_ts(xsens_msg_buf,offset); #ifdef USE_GPS_XSENS gps_itow = xsens_time_stamp; #endif offset += XSENS_DATA_TimeStamp_LENGTH; } if (XSENS_MASK_UTC(xsens_output_settings)) { xsens_hour = XSENS_DATA_UTC_hour(xsens_msg_buf,offset); xsens_min = XSENS_DATA_UTC_min(xsens_msg_buf,offset); xsens_sec = XSENS_DATA_UTC_sec(xsens_msg_buf,offset); xsens_nanosec = XSENS_DATA_UTC_nanosec(xsens_msg_buf,offset); xsens_year = XSENS_DATA_UTC_year(xsens_msg_buf,offset); xsens_month = XSENS_DATA_UTC_month(xsens_msg_buf,offset); xsens_day = XSENS_DATA_UTC_day(xsens_msg_buf,offset); offset += XSENS_DATA_UTC_LENGTH; } //} } }
void parse_xsens_msg(void) { uint8_t offset = 0; if (xsens_id == XSENS_ReqOutputModeAck_ID) { xsens_output_mode = XSENS_ReqOutputModeAck_mode(xsens_msg_buf); } else if (xsens_id == XSENS_ReqOutputSettings_ID) { xsens_output_settings = XSENS_ReqOutputSettingsAck_settings(xsens_msg_buf); } else if (xsens_id == XSENS_ReqMagneticDeclinationAck_ID) { xsens_declination = DegOfRad(XSENS_ReqMagneticDeclinationAck_declination(xsens_msg_buf)); DOWNLINK_SEND_IMU_MAG_SETTINGS(DefaultChannel, DefaultDevice, &xsens_declination, &xsens_declination, &xsens_gps_arm_x, &xsens_gps_arm_y, &xsens_gps_arm_z); } else if (xsens_id == XSENS_ReqLeverArmGpsAck_ID) { xsens_gps_arm_x = XSENS_ReqLeverArmGpsAck_x(xsens_msg_buf); xsens_gps_arm_y = XSENS_ReqLeverArmGpsAck_y(xsens_msg_buf); xsens_gps_arm_z = XSENS_ReqLeverArmGpsAck_z(xsens_msg_buf); DOWNLINK_SEND_IMU_MAG_SETTINGS(DefaultChannel, DefaultDevice, &xsens_declination, &xsens_declination, &xsens_gps_arm_x, &xsens_gps_arm_y, &xsens_gps_arm_z); } else if (xsens_id == XSENS_Error_ID) { xsens_errorcode = XSENS_Error_errorcode(xsens_msg_buf); } #if USE_GPS_XSENS else if (xsens_id == XSENS_GPSStatus_ID) { xsens.gps.nb_channels = XSENS_GPSStatus_nch(xsens_msg_buf); xsens.gps.num_sv = 0; uint8_t i; // Do not write outside buffer for (i = 0; i < Min(xsens.gps.nb_channels, GPS_NB_CHANNELS); i++) { uint8_t ch = XSENS_GPSStatus_chn(xsens_msg_buf, i); if (ch > xsens.gps.nb_channels) { continue; } xsens.gps.svinfos[ch].svid = XSENS_GPSStatus_svid(xsens_msg_buf, i); xsens.gps.svinfos[ch].flags = XSENS_GPSStatus_bitmask(xsens_msg_buf, i); xsens.gps.svinfos[ch].qi = XSENS_GPSStatus_qi(xsens_msg_buf, i); xsens.gps.svinfos[ch].cno = XSENS_GPSStatus_cnr(xsens_msg_buf, i); if (xsens.gps.svinfos[ch].flags > 0) { xsens.gps.num_sv++; } } } #endif else if (xsens_id == XSENS_MTData_ID) { /* test RAW modes else calibrated modes */ //if ((XSENS_MASK_RAWInertial(xsens_output_mode)) || (XSENS_MASK_RAWGPS(xsens_output_mode))) { if (XSENS_MASK_RAWInertial(xsens_output_mode)) { /* should we write raw data to separate struct? */ xsens.gyro.p = XSENS_DATA_RAWInertial_gyrX(xsens_msg_buf, offset); xsens.gyro.q = XSENS_DATA_RAWInertial_gyrY(xsens_msg_buf, offset); xsens.gyro.r = XSENS_DATA_RAWInertial_gyrZ(xsens_msg_buf, offset); xsens.gyro_available = TRUE; offset += XSENS_DATA_RAWInertial_LENGTH; } if (XSENS_MASK_RAWGPS(xsens_output_mode)) { #if USE_GPS_XSENS_RAW_DATA && USE_GPS_XSENS xsens.gps.week = 0; // FIXME xsens.gps.tow = XSENS_DATA_RAWGPS_itow(xsens_msg_buf, offset) * 10; xsens.gps.lla_pos.lat = XSENS_DATA_RAWGPS_lat(xsens_msg_buf, offset); xsens.gps.lla_pos.lon = XSENS_DATA_RAWGPS_lon(xsens_msg_buf, offset); xsens.gps.lla_pos.alt = XSENS_DATA_RAWGPS_alt(xsens_msg_buf, offset); SetBit(xsens.gps.valid_fields, GPS_VALID_POS_LLA_BIT); // Compute geoid (MSL) height float hmsl = wgs84_ellipsoid_to_geoid_i(xsens.gps.lla_pos.lat, xsens.gps.lla_pos.lon); xsens.gps.hmsl = XSENS_DATA_RAWGPS_alt(xsens_msg_buf, offset) - (hmsl * 1000.0f); SetBit(gps.valid_fields, GPS_VALID_HMSL_BIT); xsens.gps.ned_vel.x = XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf, offset); xsens.gps.ned_vel.y = XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf, offset); xsens.gps.ned_vel.z = XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf, offset); SetBit(gps.valid_fields, GPS_VALID_VEL_NED_BIT); xsens.gps.pacc = XSENS_DATA_RAWGPS_hacc(xsens_msg_buf, offset) / 100; xsens.gps.sacc = XSENS_DATA_RAWGPS_sacc(xsens_msg_buf, offset) / 100; xsens.gps.pdop = 5; // FIXME Not output by XSens xsens.gps_available = TRUE; #endif offset += XSENS_DATA_RAWGPS_LENGTH; } //} else { if (XSENS_MASK_Temp(xsens_output_mode)) { offset += XSENS_DATA_Temp_LENGTH; } if (XSENS_MASK_Calibrated(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_AccOut(xsens_output_settings)) { xsens.accel.x = XSENS_DATA_Calibrated_accX(xsens_msg_buf, offset); xsens.accel.y = XSENS_DATA_Calibrated_accY(xsens_msg_buf, offset); xsens.accel.z = XSENS_DATA_Calibrated_accZ(xsens_msg_buf, offset); xsens.accel_available = TRUE; l++; } if (!XSENS_MASK_GyrOut(xsens_output_settings)) { xsens.gyro.p = XSENS_DATA_Calibrated_gyrX(xsens_msg_buf, offset); xsens.gyro.q = XSENS_DATA_Calibrated_gyrY(xsens_msg_buf, offset); xsens.gyro.r = XSENS_DATA_Calibrated_gyrZ(xsens_msg_buf, offset); xsens.gyro_available = TRUE; l++; } if (!XSENS_MASK_MagOut(xsens_output_settings)) { xsens.mag.x = XSENS_DATA_Calibrated_magX(xsens_msg_buf, offset); xsens.mag.y = XSENS_DATA_Calibrated_magY(xsens_msg_buf, offset); xsens.mag.z = XSENS_DATA_Calibrated_magZ(xsens_msg_buf, offset); xsens.mag_available = TRUE; l++; } offset += l * XSENS_DATA_Calibrated_LENGTH / 3; } if (XSENS_MASK_Orientation(xsens_output_mode)) { if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x00) { xsens.quat.qi = XSENS_DATA_Quaternion_q0(xsens_msg_buf, offset); xsens.quat.qx = XSENS_DATA_Quaternion_q1(xsens_msg_buf, offset); xsens.quat.qy = XSENS_DATA_Quaternion_q2(xsens_msg_buf, offset); xsens.quat.qz = XSENS_DATA_Quaternion_q3(xsens_msg_buf, offset); //float_eulers_of_quat(&xsens.euler, &xsens.quat); offset += XSENS_DATA_Quaternion_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x01) { xsens.euler.phi = XSENS_DATA_Euler_roll(xsens_msg_buf, offset) * M_PI / 180; xsens.euler.theta = XSENS_DATA_Euler_pitch(xsens_msg_buf, offset) * M_PI / 180; xsens.euler.psi = XSENS_DATA_Euler_yaw(xsens_msg_buf, offset) * M_PI / 180; offset += XSENS_DATA_Euler_LENGTH; } if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x10) { offset += XSENS_DATA_Matrix_LENGTH; } xsens.new_attitude = TRUE; } if (XSENS_MASK_Auxiliary(xsens_output_mode)) { uint8_t l = 0; if (!XSENS_MASK_Aux1Out(xsens_output_settings)) { l++; } if (!XSENS_MASK_Aux2Out(xsens_output_settings)) { l++; } offset += l * XSENS_DATA_Auxiliary_LENGTH / 2; } if (XSENS_MASK_Position(xsens_output_mode)) { xsens.lla_f.lat = RadOfDeg(XSENS_DATA_Position_lat(xsens_msg_buf, offset)); xsens.lla_f.lon = RadOfDeg(XSENS_DATA_Position_lon(xsens_msg_buf, offset)); xsens.lla_f.alt = XSENS_DATA_Position_alt(xsens_msg_buf, offset); offset += XSENS_DATA_Position_LENGTH; #if (! USE_GPS_XSENS_RAW_DATA) && USE_GPS_XSENS LLA_BFP_OF_REAL(xsens.gps.lla_pos, xsens.lla_f); SetBit(gps.valid_fields, GPS_VALID_POS_LLA_BIT); xsens.gps_available = TRUE; #endif } if (XSENS_MASK_Velocity(xsens_output_mode)) { xsens.vel.x = XSENS_DATA_Velocity_vx(xsens_msg_buf, offset); xsens.vel.y = XSENS_DATA_Velocity_vy(xsens_msg_buf, offset); xsens.vel.z = XSENS_DATA_Velocity_vz(xsens_msg_buf, offset); offset += XSENS_DATA_Velocity_LENGTH; } if (XSENS_MASK_Status(xsens_output_mode)) { xsens_msg_status = XSENS_DATA_Status_status(xsens_msg_buf, offset); #if USE_GPS_XSENS if (bit_is_set(xsens_msg_status, 2)) { xsens.gps.fix = GPS_FIX_3D; } // gps fix else if (bit_is_set(xsens_msg_status, 1)) { xsens.gps.fix = 0x01; } // efk valid else { xsens.gps.fix = GPS_FIX_NONE; } #ifdef GPS_LED if (xsens.gps.fix == GPS_FIX_3D) { LED_ON(GPS_LED); } else { LED_TOGGLE(GPS_LED); } #endif // GPS_LED #endif // USE_GPS_XSENS offset += XSENS_DATA_Status_LENGTH; } if (XSENS_MASK_TimeStamp(xsens_output_settings)) { xsens.time_stamp = XSENS_DATA_TimeStamp_ts(xsens_msg_buf, offset); offset += XSENS_DATA_TimeStamp_LENGTH; } if (XSENS_MASK_UTC(xsens_output_settings)) { xsens.time.hour = XSENS_DATA_UTC_hour(xsens_msg_buf, offset); xsens.time.min = XSENS_DATA_UTC_min(xsens_msg_buf, offset); xsens.time.sec = XSENS_DATA_UTC_sec(xsens_msg_buf, offset); xsens.time.nanosec = XSENS_DATA_UTC_nanosec(xsens_msg_buf, offset); xsens.time.year = XSENS_DATA_UTC_year(xsens_msg_buf, offset); xsens.time.month = XSENS_DATA_UTC_month(xsens_msg_buf, offset); xsens.time.day = XSENS_DATA_UTC_day(xsens_msg_buf, offset); offset += XSENS_DATA_UTC_LENGTH; } } }