예제 #1
0
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;
      }
    //}
  }

}
예제 #2
0
파일: csc_xsens.c 프로젝트: 0lri/paparazzi
// 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;
      }
  }
}
예제 #3
0
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;
        }
        //}
    }

}
예제 #4
0
파일: xsens.c 프로젝트: 2seasuav/paparuzzi
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;
    }
  }

}