示例#1
0
/// get the relevant data from the packet and sent it as Ivy message
void decode_and_send_to_ivy() {

  // check packet integrity
  char expected[] = "LOO";
  if (strncmp((char *)packet, expected, 3) != 0) {
    fprintf(stderr, "Received packet from the weather station which does not match the expected format\n");
    reset_station();
    return;
  }

  // TODO CRC checking (is rather involved for the Davis protocol)

  // get relevant data and convert to SI units
  // see chapter IX.1 of the protocol definition
  float
    pstatic_Pa = (packet[7] | packet[8] << 8)*3.386388640341, // original is inches Hg / 1000
    temp_degC = ((packet[12] | packet[13] << 8)/10.0 - 32.0)*5.0/9.0, // original is deg F / 10
    windspeed_mps = packet[14]*0.44704, // original is miles per hour
    winddir_deg = packet[16] | packet[17] << 8,
    rel_humidity = -1.; // TODO Get the real humidity value from message


  // TODO get the real MD5 for the aircraft id
  if (want_alive_msg)
    IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ac_id);

  // format has to match declaration in conf/messages.xml
  IvySendMsg("%d WEATHER %f %f %f %f %f\n",
    ac_id, pstatic_Pa, temp_degC, windspeed_mps, winddir_deg, rel_humidity);
}
gboolean timeout_callback(gpointer data) {

  for (int i=0; i<20; i++) {
    aos_compute_state();
    aos_compute_sensors();
#ifndef DISABLE_PROPAGATE
    ahrs_propagate();
#endif
#ifndef DISABLE_ACCEL_UPDATE
    ahrs_update_accel();
#endif
#ifndef DISABLE_MAG_UPDATE
    if (!(i%5)) ahrs_update_mag();
#endif
  }

#if AHRS_TYPE == AHRS_TYPE_ICE || AHRS_TYPE == AHRS_TYPE_ICQ
    EULERS_FLOAT_OF_BFP(ahrs_float.ltp_to_imu_euler, ahrs.ltp_to_imu_euler);
#endif

#if AHRS_TYPE == AHRS_TYPE_ICQ
    IvySendMsg("183 BOOZ_AHRS_BIAS %d %d %d", 
	       ahrs_impl.gyro_bias.p,
	       ahrs_impl.gyro_bias.q,
	       ahrs_impl.gyro_bias.r);
#endif
#if AHRS_TYPE == AHRS_TYPE_FLQ || AHRS_TYPE == AHRS_TYPE_FCR2
    struct Int32Rates bias_i;
    RATES_BFP_OF_REAL(bias_i, ahrs_impl.gyro_bias);
    IvySendMsg("183 BOOZ_AHRS_BIAS %d %d %d", 
	       bias_i.p,
	       bias_i.q,
	       bias_i.r);
#endif

  IvySendMsg("183 AHRS_EULER %f %f %f", 
	     ahrs_float.ltp_to_imu_euler.phi,
	     ahrs_float.ltp_to_imu_euler.theta,
	     ahrs_float.ltp_to_imu_euler.psi);

  IvySendMsg("183 BOOZ_SIM_RATE_ATTITUDE %f %f %f %f %f %f",
	     DegOfRad(aos.imu_rates.p), 
	     DegOfRad(aos.imu_rates.q), 
	     DegOfRad(aos.imu_rates.r),
	     DegOfRad(aos.ltp_to_imu_euler.phi), 
	     DegOfRad(aos.ltp_to_imu_euler.theta),
	     DegOfRad(aos.ltp_to_imu_euler.psi));

  IvySendMsg("183 BOOZ_SIM_GYRO_BIAS %f %f %f",
	     DegOfRad(aos.gyro_bias.p), 
	     DegOfRad(aos.gyro_bias.q), 
	     DegOfRad(aos.gyro_bias.r));

  return TRUE;
}
示例#3
0
/// Get the relevant data from the packet and sent it as Ivy message
void decode_and_send_to_ivy() {
  // get relevant data and convert to SI units

  // contents of the kestrel S message response:
  // DT,  MG,  TR,  WS,  CW,  HW, TP, WC, RH, HI, DP, WB,  BP,  AL, DA
  //  s, Mag, True, mph, mph, mph, F,  F,  %,  F,  F,  F, inHg, ft, ft
  //
  // where:
  //
  //   DT is the date and time in seconds since 1st January 2000, 
  //   AV is air velocity 
  //   AF is air flow
  //   MG is the compass magnetic direction
  //   TR is the compass true direction
  //   WS is the wind speed
  //   CW is the crosswind
  //   HW is the headwind
  //   TP is the temperature, 
  //   WC is the wind chill,
  //   RH is the humidity,
  //   EV is the evaporation rate
  //   CT is the concrete temperature
  //   HR, MO (moisture) are the humidity ratio
  //   HI is the heat index,
  //   DP is the dew point,
  //   WB is the wet bulb
  //   AP is absolute pressure
  //   BP is the pressure,   
  //   AL is the altitude,     
  //   DA is the density altitude
  //   AD is air density
  //   RA is relative air density


  float values[NUM_PARAMS];
  float pstatic_Pa, temp_degC, windspeed_mps, winddir_deg;

  if (want_alive_msg)
    IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ac_id);

  if (getValues(packet + MIN_PACKET_LENGTH, values)){
    pstatic_Pa    = values[BP] * 3386.4;            // original is inches Hg
    temp_degC     = (values[TP] - 32.0) * 5.0/9.0;  // original is deg F
    windspeed_mps = values[WS] * 0.44704;           // original is miles per hour
    winddir_deg   = values[MG];
    
    // format has to match declaration in conf/messages.xml
    IvySendMsg("%d WEATHER %f %f %f %f\n",
	       ac_id, pstatic_Pa, temp_degC, windspeed_mps, winddir_deg);
  }
}
示例#4
0
static void on_sync_clicked(GtkButton *button, gpointer user_data) {

  static uint8_t syncID = 1;
  char *msg;

  if (asprintf(&msg, "Aircraft %d, video synchronisation %d", airframeID, syncID) > 0) {
    say(msg);
    free(msg);
  }
  else {
    fprintf(stderr, "Could not allocate mem for msg string\n");
  }

  IvySendMsg("%d VIDEO_SYNC %d", airframeID, syncID);  //TODO : get the current airframe ID

  // create a flashing window in full screen for the camera to see
  flashWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  GdkColor white;
  white.red = 0xFFFF;
  white.green = 0xFFFF;
  white.blue = 0xFFFF;
  gtk_widget_modify_bg(flashWindow, GTK_STATE_NORMAL, &white);

  gtk_hbox_new(FALSE, 0);
  gtk_window_fullscreen((GtkWindow*)flashWindow);
  gtk_widget_show_all(flashWindow);

  g_timeout_add(100 , __timeout_flashing_window , ml);

  syncID++;
}
示例#5
0
static void update_gps(struct gps_data_t *gpsdata,
                       char *message,
                       size_t len)
{
    static double fix_time = 0;
    double fix_track = 0;
    double fix_speed = 0;
    double fix_altitude = 0;
    double fix_climb = 0;

    if ((isnan(gpsdata->fix.latitude) == 0) &&
        (isnan(gpsdata->fix.longitude) == 0) &&
        (isnan(gpsdata->fix.time) == 0) &&
        (gpsdata->fix.mode >= MODE_2D) &&
        (gpsdata->fix.time != fix_time))
    {
        if (!isnan(gpsdata->fix.track))
            fix_track = gpsdata->fix.track;
        if (!isnan(gpsdata->fix.speed))
            fix_speed = gpsdata->fix.speed;

        if (gpsdata->fix.mode >= MODE_3D)
        {
            if (!isnan(gpsdata->fix.altitude))
                fix_altitude = gpsdata->fix.altitude;
            if (!isnan(gpsdata->fix.climb))
                fix_climb = gpsdata->fix.climb;
        }

        if (verbose)
            printf("sending gps info viy Ivy: lat %g, lon %g, speed %g, course %g, alt %g, climb %g\n",
                   gpsdata->fix.latitude, gpsdata->fix.longitude, fix_speed, fix_track, fix_altitude, fix_climb);

        IvySendMsg("%s %s %s %f %f %f %f %f %f %f %f %f %f %f %d",
                MSG_DEST,
                MSG_NAME,
                MSG_ID, // ac_id
                0.0, // roll,
                0.0, // pitch,
                0.0, // heading
                gpsdata->fix.latitude,
                gpsdata->fix.longitude,
                fix_speed,
                fix_track, // course
                fix_altitude,
                fix_climb,
                0.0, // agl
                gpsdata->fix.time,
                0); // itow

        fix_time = gpsdata->fix.time;
    }
    else
    {
        if (verbose)
            printf("ignoring gps data: lat %f, lon %f, mode %d, time %f\n", gpsdata->fix.latitude,
                   gpsdata->fix.longitude, gpsdata->fix.mode, gpsdata->fix.time);
    }
}
示例#6
0
static void on_as_addr_changed (GtkRadioButton  *radiobutton, gpointer user_data) {
#ifdef ASTECH
  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)))
    return;
  guint new_addr = (guint)user_data;
  IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_TWI_CONTROLLER_ASCTECH_ADDR, new_addr);
#endif
}
示例#7
0
/* Called by clicking a button */
void init_river_tracking( GtkWidget *widget, gpointer data )
{
    fprintf(stderr, "initializing river tracking...\n");
    /* Call function get_next_waypoint (defined in nexcwp.c)
     * which returns a waypoint. */
    Waypoint new_wp = get_next_waypoint();
    IvySendMsg("gcs MOVE_WAYPOINT %d %d %f %f %f", \
            new_wp.ac_id, 4, new_wp.lat, new_wp.lon, new_wp.alt);
}
static gboolean periodic(gpointer data __attribute__ ((unused))) {
  int roll, pitch;
  counter++;
  pitch = 0;
  roll = STEP_VAL;
  if ((counter%6) >=3) roll = -roll;
    
  IvySendMsg("dl COMMANDS_RAW %d %d,%d", aircraft_id, roll, pitch);
  return TRUE;
}
示例#9
0
void request_ac_config(int ac_id_req) {

  RequestID++;
  IvySendMsg("app_server %d_%d CONFIG_REQ %d" ,ProcessID, RequestID ,ac_id_req );
  //AC config requested..

  if (verbose) {
    printf("AC(id= %d) config requested.\n",ac_id_req);
    fflush(stdout);
  }
}
示例#10
0
// Deuxième partie de la fonction d'envoi d'un SMS
void Reception_SMS_Continue(int handle)
{
    char buffer_SMS_recu[250];

    strcpy(buffer_SMS_recu, GSM_Line);

    Remplissage_SMS(buffer_SMS_recu);

    if (Verification(expediteur) == 1)// Le SMS provient bien de l'avion
    {
        printf("Nouveau message recu de l'avion\n");

        /* Stockage du message dans un fichier de log */
        Save_SMS_In_Log();

        /* Vérification de l'index (pour ne pas en laisser passer un)*/
        if (Check_index(index_msg) == 0) /*on a laissé passer qqch*/
        {
            printf("Attention perte d'un ou plusieurs messages...\n");
        }

        printf("Contenu du message :%s\n", data);



        // Découpage prévu du SMS recu
        decoupage(data);

        /* Envoi sur le bus Ivy */
        IvySendMsg("16 GPS 3 %s %s %s %s %s %s 0 335297960 31 0", extr_gps_utm_east, extr_gps_utm_north, extr_gps_course, extr_gps_alt, extr_gps_gspeed, extr_gps_climb);
        IvySendMsg("16 FBW_STATUS 0 1 %s 0",extr_vsupply);


        /* Suppression du message de la carte SIM */
        Suppr_SMS(handle, index_msg);
    }

    fflush(stdout);
}
示例#11
0
/* Called when aircraft reaches "Block 1" (the second
 * block defined in the flight plan)
 */
void start_track(IvyClientPtr app, void *data, int argc, char **argv)
{
    fprintf(stderr, ".");
    /* Call function get_next_waypoint (defined in nexcwp.c)
     * which returns a waypoint. */
    Waypoint new_wp = get_next_waypoint();

    if(CONTINUE) {
        IvySendMsg("gcs MOVE_WAYPOINT %d %d %f %f %f", \
                new_wp.ac_id, 4, new_wp.lat, new_wp.lon, new_wp.alt); //Always move waypoint 4
    }
    /* else we've reached the end (we've seen the "end" waypoint in the
     * picture), so don't send any message.
     */
}
示例#12
0
文件: tcp2ivy.c 项目: AshuLara/lisa
static gboolean alive(gpointer data __attribute__ ((unused))) {
/*
   <message name="ALIVE" id="2">
     <field name="md5sum" type="uint8[]"/>
   </message>
*/
  IvySendMsg("%d ALIVE %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,",
             AC_ID,
             md5[0], md5[1], md5[2], md5[3],
             md5[4], md5[5], md5[6], md5[7],
             md5[8], md5[9], md5[10], md5[11],
             md5[12], md5[13], md5[14], md5[15]);

  return 1;
}
示例#13
0
static int
IvySendCmd(ClientData	clientData,
	   Tcl_Interp	*interp,
	   int		argc,
	   const char	**argv)
{
  if (argc != 2) {
    Tcl_AppendResult(interp, "wrong # of args: \"",
		     argv[0], " msg\"", (char *) NULL);
    return TCL_ERROR;
  }

  IvySendMsg(argv[1], NULL);
  
  return TCL_OK;
}
示例#14
0
static void update_gps(struct gps_data_t *gpsdata,
                       char *message,
                       size_t len)
{
    static double fix_time = 0;
    double fix_track = 0;
    double fix_speed = 0;
    double fix_altitude = 0;
    double fix_climb = 0;

    if ((isnan(gpsdata->fix.latitude) == 0) &&
        (isnan(gpsdata->fix.longitude) == 0) &&
        (isnan(gpsdata->fix.time) == 0) &&
        (gpsdata->fix.mode >= MODE_2D) &&
        (gpsdata->fix.time != fix_time))
    {
        if (isnan(gpsdata->fix.track) != 0) fix_track = gpsdata->fix.track;
        if (isnan(gpsdata->fix.speed) != 0) fix_speed = gpsdata->fix.speed;

        if (gpsdata->fix.mode >= MODE_3D)
        {
            if (isnan(gpsdata->fix.altitude) != 0) fix_altitude = gpsdata->fix.altitude;
            if (isnan(gpsdata->fix.climb) != 0) fix_climb = gpsdata->fix.climb;
        }

        IvySendMsg("%s %s %s %f %f %f %f %f %f %f %f %f %f %f %d",
                MSG_DEST,
                MSG_NAME,
                MSG_ID, // ac_id
                0.0, // roll,
                0.0, // pitch,
                0.0, // heading
                gpsdata->fix.latitude,
                gpsdata->fix.longitude,
                fix_speed,
                fix_track, // course
                fix_altitude,
                fix_climb,
                0.0, // agl
                gpsdata->fix.time,
                0); // itow

        fix_time = gpsdata->fix.time;
    }
}
示例#15
0
void on_mode_changed (GtkRadioButton  *radiobutton, gpointer user_data) {
  mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)) ? MANUAL : AUTO;
  IvySendMsg("1ME RAW_DATALINK 80 SETTING;0;0;%d", mode);
  g_message("Mode changed to %d" , mode);
}
示例#16
0
static void on_mode_changed (GtkRadioButton  *radiobutton, gpointer user_data) {
  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)))
    return;
  guint mode = (guint)user_data;
  IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_MODES_MODE, mode);
}
示例#17
0
static void on_as_reverse_button_clicked (GtkWidget *widget, gpointer data) {
#ifdef ASTECH
  IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_TWI_CONTROLLER_ASCTECH_COMMAND_TYPE, AS_CMD_REVERSE);
#endif
}
示例#18
0
gboolean request_ac_list(gpointer data) {
  RequestID++;
  IvySendMsg("app_server %d_%d AIRCRAFTS_REQ" ,ProcessID, RequestID);
  return FALSE;
}
示例#19
0
/* callback associated to "Hello" messages */
void textCallback(IvyClientPtr app, void *data, int argc, char **argv)
{
    const char* arg = (argc < 1) ? "" : argv[0];
    IvySendMsg("Alo ai%s", arg);
}
示例#20
0
void on_scale_value_changed (GtkScale  *scale, gpointer user_data) {
  gfloat cf = gtk_range_get_value(GTK_RANGE(scale));
  gint c = round(cf);
  g_message("foo %d %f", user_data, c);
  IvySendMsg("ME RAW_DATALINK 16 SETTING;%d;0;%d", (gint)user_data, c);
}
示例#21
0
/**
 * Get the relevant data from the packet and send it as Ivy message
 */
void decode_and_send_to_ivy() {
  // get relevant data and convert to SI units

  // contents of the kestrel S message response in imperial units:
  // DT,  MG,  TR,  WS,  CW,  HW, TP, WC, RH, HI, DP, WB,  BP,  AL, DA
  //  s, Mag, True, mph, mph, mph, F,  F,  %,  F,  F,  F, inHg, ft, ft
  // in metric units:
  //  s,Mag,True,km/h,km/h,km/h,�C,�C,%,�C,�C,�C,hPa,m,m
  //
  // Sample packet in metric units:
  // S
  // > DT,MG,TR,WS,CW,HW,TP,WC,RH,HI,DP,WB,BP,AL,DA
  // s,Mag,True,km/h,km/h,km/h,�C,�C,%,�C,�C,�C,hPa,m,m
  // 399124138,000,000,0.0,0.0,0.0,22.5,22.5,37.6,21.4,7.3,13.5,931.5,701,1171
  // >
  //
  // where:
  //
  //   DT is the date and time in seconds since 1st January 2000,
  //   AV is air velocity
  //   AF is air flow
  //   MG is the compass magnetic direction
  //   TR is the compass true direction
  //   WS is the wind speed
  //   CW is the crosswind
  //   HW is the headwind
  //   TP is the temperature,
  //   WC is the wind chill,
  //   RH is the relative humidity,
  //   EV is the evaporation rate
  //   CT is the concrete temperature
  //   HR, MO (moisture) are the humidity ratio
  //   HI is the heat index,
  //   DP is the dew point,
  //   WB is the wet bulb
  //   AP is absolute pressure
  //   BP is the pressure,
  //   AL is the altitude,
  //   DA is the density altitude
  //   AD is air density
  //   RA is relative air density

  float values[NUM_PARAMS];
  float pstatic_Pa, temp_degC, windspeed_mps, winddir_deg, rel_humidity;

  if (want_alive_msg)
    IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ac_id);

  if (getValues(packet + MIN_PACKET_LENGTH, values)){
    if (metric_input) {
      //If the unit outputs are set for SI (or closest match), use these conversions
      pstatic_Pa     = values[BP] * 100.0;             // original is hPa
      temp_degC      = values[TP];                     // original is deg C
      windspeed_mps  = values[WS] * 0.2778;            // original is km/h
      winddir_deg    = values[MG];
      rel_humidity   = values[RH];
    } else {
      //Otherwise use the default imperial units and convert to SI
      pstatic_Pa     = values[BP] * 3386.4;            // original is inches Hg
      temp_degC      = (values[TP] - 32.0) * 5.0/9.0;  // original is deg F
      windspeed_mps  = values[WS] * 0.44704;           // original is miles per hour
      winddir_deg    = values[MG];
      rel_humidity   = values[RH];
    }

    // format has to match declaration in var/messages.xml
    IvySendMsg("%d WEATHER %f %f %f %f %f\n",
	       ac_id, pstatic_Pa, temp_degC, windspeed_mps, winddir_deg, rel_humidity);
  }
}
示例#22
0
/** The transmitter periodic function */
gboolean timeout_transmit_callback(gpointer data)
{
  int i;

  // Loop trough all the available rigidbodies (TODO: optimize)
  for (i = 0; i < MAX_RIGIDBODIES; i++) {
    // Check if ID's are correct
    if (rigidBodies[i].id >= MAX_RIGIDBODIES) {
      fprintf(stderr,
              "Could not parse rigid body %d from NatNet, because ID is higher then or equal to %d (MAX_RIGIDBODIES-1).\r\n",
              rigidBodies[i].id, MAX_RIGIDBODIES - 1);
      exit(EXIT_FAILURE);
    }

    // Check if we want to transmit (follow) this rigid
    if (aircrafts[rigidBodies[i].id].ac_id == 0) {
      continue;
    }

    // When we don track anymore and timeout or start tracking
    if (rigidBodies[i].nSamples < 1
        && aircrafts[rigidBodies[i].id].connected
        && (natnet_latency - aircrafts[rigidBodies[i].id].lastSample) > CONNECTION_TIMEOUT) {
      aircrafts[rigidBodies[i].id].connected = FALSE;
      fprintf(stderr, "#error Lost tracking rigid id %d, aircraft id %d.\n",
              rigidBodies[i].id, aircrafts[rigidBodies[i].id].ac_id);
    } else if (rigidBodies[i].nSamples > 0 && !aircrafts[rigidBodies[i].id].connected) {
      fprintf(stderr, "#pragma message: Now tracking rigid id %d, aircraft id %d.\n",
              rigidBodies[i].id, aircrafts[rigidBodies[i].id].ac_id);
    }

    // Check if we still track the rigid
    if (rigidBodies[i].nSamples < 1) {
      continue;
    }

    // Update the last tracked
    aircrafts[rigidBodies[i].id].connected = TRUE;
    aircrafts[rigidBodies[i].id].lastSample = natnet_latency;

    // Defines to make easy use of paparazzi math
    struct EnuCoor_d pos, speed;
    struct EcefCoor_d ecef_pos;
    struct LlaCoor_d lla_pos;
    struct DoubleQuat orient;
    struct DoubleEulers orient_eulers;

    // Add the Optitrack angle to the x and y positions
    pos.x = cos(tracking_offset_angle) * rigidBodies[i].x - sin(tracking_offset_angle) * rigidBodies[i].y;
    pos.y = sin(tracking_offset_angle) * rigidBodies[i].x + cos(tracking_offset_angle) * rigidBodies[i].y;
    pos.z = rigidBodies[i].z;

    // Convert the position to ecef and lla based on the Optitrack LTP
    ecef_of_enu_point_d(&ecef_pos , &tracking_ltp , &pos);
    lla_of_ecef_d(&lla_pos, &ecef_pos);

    // Check if we have enough samples to estimate the velocity
    rigidBodies[i].nVelocityTransmit++;
    if (rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
      // Calculate the derevative of the sum to get the correct velocity     (1 / freq_transmit) * (samples / total_samples)
      double sample_time = //((double)rigidBodies[i].nVelocitySamples / (double)rigidBodies[i].totalVelocitySamples) /
        ((double)rigidBodies[i].nVelocityTransmit / (double)freq_transmit);
      rigidBodies[i].vel_x = rigidBodies[i].vel_x / sample_time;
      rigidBodies[i].vel_y = rigidBodies[i].vel_y / sample_time;
      rigidBodies[i].vel_z = rigidBodies[i].vel_z / sample_time;

      // Add the Optitrack angle to the x and y velocities
      speed.x = cos(tracking_offset_angle) * rigidBodies[i].vel_x - sin(tracking_offset_angle) * rigidBodies[i].vel_y;
      speed.y = sin(tracking_offset_angle) * rigidBodies[i].vel_x + cos(tracking_offset_angle) * rigidBodies[i].vel_y;
      speed.z = rigidBodies[i].vel_z;

      // Conver the speed to ecef based on the Optitrack LTP
      ecef_of_enu_vect_d(&rigidBodies[i].ecef_vel , &tracking_ltp , &speed);
    }

    // Copy the quaternions and convert to euler angles for the heading
    orient.qi = rigidBodies[i].qw;
    orient.qx = rigidBodies[i].qx;
    orient.qy = rigidBodies[i].qy;
    orient.qz = rigidBodies[i].qz;
    double_eulers_of_quat(&orient_eulers, &orient);

    // Calculate the heading by adding the Natnet offset angle and normalizing it
    double heading = -orient_eulers.psi + 90.0 / 57.6 -
                     tracking_offset_angle; //the optitrack axes are 90 degrees rotated wrt ENU
    NormRadAngle(heading);

    printf_debug("[%d -> %d]Samples: %d\t%d\t\tTiming: %3.3f latency\n", rigidBodies[i].id,
                 aircrafts[rigidBodies[i].id].ac_id
                 , rigidBodies[i].nSamples, rigidBodies[i].nVelocitySamples, natnet_latency);
    printf_debug("    Heading: %f\t\tPosition: %f\t%f\t%f\t\tVelocity: %f\t%f\t%f\n", DegOfRad(heading),
                 rigidBodies[i].x, rigidBodies[i].y, rigidBodies[i].z,
                 rigidBodies[i].ecef_vel.x, rigidBodies[i].ecef_vel.y, rigidBodies[i].ecef_vel.z);


    /* Construct time of time of week (tow) */
    time_t now;
    time(&now);
    struct tm *ts = localtime(&now);
    
    uint32_t tow = (ts->tm_wday - 1)*(24*60*60*1000) + ts->tm_hour*(60*60*1000) + ts->tm_min*(60*1000) + ts->tm_sec*1000;

    // Transmit the REMOTE_GPS packet on the ivy bus (either small or big)
    if (small_packets) {
      /* The local position is an int32 and the 11 LSBs of the (signed) x and y axis are compressed into
       * a single integer. The z axis is considered unsigned and only the latter 10 LSBs are
       * used.
       */

      uint32_t pos_xyz = 0;
      // check if position within limits
      if (fabs(pos.x * 100.) < pow(2, 10)) {
        pos_xyz = (((uint32_t)(pos.x * 100.0)) & 0x7FF) << 21;                     // bits 31-21 x position in cm
      } else {
        fprintf(stderr, "Warning!! X position out of maximum range of small message (±%.2fm): %.2f", pow(2, 10) / 100, pos.x);
        pos_xyz = (((uint32_t)(pow(2, 10) * pos.x / fabs(pos.x))) & 0x7FF) << 21;  // bits 31-21 x position in cm
      }

      if (fabs(pos.y * 100.) < pow(2, 10)) {
        pos_xyz |= (((uint32_t)(pos.y * 100.0)) & 0x7FF) << 10;                    // bits 20-10 y position in cm
      } else {
        fprintf(stderr, "Warning!! Y position out of maximum range of small message (±%.2fm): %.2f", pow(2, 10) / 100, pos.y);
        pos_xyz |= (((uint32_t)(pow(2, 10) * pos.y / fabs(pos.y))) & 0x7FF) << 10; // bits 20-10 y position in cm
      }

      if (pos.z * 100. < pow(2, 10) && pos.z > 0.) {
        pos_xyz |= (((uint32_t)(fabs(pos.z) * 100.0)) & 0x3FF);                          // bits 9-0 z position in cm
      } else if (pos.z > 0.) {
        fprintf(stderr, "Warning!! Z position out of maximum range of small message (%.2fm): %.2f", pow(2, 10) / 100, pos.z);
        pos_xyz |= (((uint32_t)(pow(2, 10))) & 0x3FF);                             // bits 9-0 z position in cm
      }
      // printf("ENU Pos: %u (%.2f, %.2f, %.2f)\n", pos_xyz, pos.x, pos.y, pos.z);

      /* The speed is an int32 and the 11 LSBs of the x and y axis and 10 LSBs of z (all signed) are compressed into
       * a single integer.
       */
      uint32_t speed_xyz = 0;
      // check if speed within limits
      if (fabs(speed.x * 100) < pow(2, 10)) {
        speed_xyz = (((uint32_t)(speed.x * 100.0)) & 0x7FF) << 21;                       // bits 31-21 speed x in cm/s
      } else {
        fprintf(stderr, "Warning!! X Speed out of maximum range of small message (±%.2fm/s): %.2f", pow(2, 10) / 100, speed.x);
        speed_xyz = (((uint32_t)(pow(2, 10) * speed.x / fabs(speed.x))) & 0x7FF) << 21;  // bits 31-21 speed x in cm/s
      }

      if (fabs(speed.y * 100) < pow(2, 10)) {
        speed_xyz |= (((uint32_t)(speed.y * 100.0)) & 0x7FF) << 10;                      // bits 20-10 speed y in cm/s
      } else {
        fprintf(stderr, "Warning!! Y Speed out of maximum range of small message (±%.2fm/s): %.2f", pow(2, 10) / 100, speed.y);
        speed_xyz |= (((uint32_t)(pow(2, 10) * speed.y / fabs(speed.y))) & 0x7FF) << 10; // bits 20-10 speed y in cm/s
      }

      if (fabs(speed.z * 100) < pow(2, 9)) {
        speed_xyz |= (((uint32_t)(speed.z * 100.0)) & 0x3FF);                            // bits 9-0 speed z in cm/s
      } else {
        fprintf(stderr, "Warning!! Z Speed out of maximum range of small message (±%.2fm/s): %.2f", pow(2, 9) / 100, speed.z);
        speed_xyz |= (((uint32_t)(pow(2, 9) * speed.z / fabs(speed.z))) & 0x3FF);       // bits 9-0 speed z in cm/s
      }

      /* The gps_small msg should always be less than 20 bytes including the pprz header of 6 bytes
       * This is primarily due to the maximum packet size of the bluetooth msgs of 19 bytes
       * increases the probability that a complete message will be accepted
       */
      IvySendMsg("0 REMOTE_GPS_SMALL %d %d %d %d %d",
                (int16_t)(heading * 10000),       // int16_t heading in rad*1e4 (2 bytes)
                pos_xyz,                          // uint32 ENU X, Y and Z in CM (4 bytes)
                speed_xyz,                        // uint32 ENU velocity X, Y, Z in cm/s (4 bytes)
                tow,                              // uint32_t time of day
                aircrafts[rigidBodies[i].id].ac_id); // uint8 rigid body ID (1 byte)

    } else {
      IvySendMsg("0 REMOTE_GPS %d %d %d %d %d %d %d %d %d %d %d %d %d %d", aircrafts[rigidBodies[i].id].ac_id,
                 rigidBodies[i].nMarkers,                //uint8 Number of markers (sv_num)
                 (int)(ecef_pos.x * 100.0),              //int32 ECEF X in CM
                 (int)(ecef_pos.y * 100.0),              //int32 ECEF Y in CM
                 (int)(ecef_pos.z * 100.0),              //int32 ECEF Z in CM
                 (int)(DegOfRad(lla_pos.lat) * 10000000.0),        //int32 LLA latitude in deg*1e7
                 (int)(DegOfRad(lla_pos.lon) * 10000000.0),        //int32 LLA longitude in deg*1e7
                 (int)(lla_pos.alt * 1000.0),            //int32 LLA altitude in mm above elipsoid
                 (int)(rigidBodies[i].z * 1000.0),       //int32 HMSL height above mean sea level in mm
                 (int)(rigidBodies[i].ecef_vel.x * 100.0), //int32 ECEF velocity X in cm/s
                 (int)(rigidBodies[i].ecef_vel.y * 100.0), //int32 ECEF velocity Y in cm/s
                 (int)(rigidBodies[i].ecef_vel.z * 100.0), //int32 ECEF velocity Z in cm/s
                 tow,
                 (int)(heading * 10000000.0));           //int32 Course in rad*1e7
    }
    if (must_log) {
      if (log_exists == 0) {
        fp = fopen(nameOfLogfile, "w");
        log_exists = 1;
      }

      if (fp == NULL) {
        printf("I couldn't open file for writing.\n");
        exit(0);
      } else {
        struct timeval cur_time;
        gettimeofday(&cur_time, NULL);
        fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", aircrafts[rigidBodies[i].id].ac_id,
                rigidBodies[i].nMarkers,                //uint8 Number of markers (sv_num)
                (int)(ecef_pos.x * 100.0),              //int32 ECEF X in CM
                (int)(ecef_pos.y * 100.0),              //int32 ECEF Y in CM
                (int)(ecef_pos.z * 100.0),              //int32 ECEF Z in CM
                (int)(DegOfRad(lla_pos.lat) * 1e7),     //int32 LLA latitude in deg*1e7
                (int)(DegOfRad(lla_pos.lon) * 1e7),     //int32 LLA longitude in deg*1e7
                (int)(lla_pos.alt*1000.0),              //int32 LLA altitude in mm above elipsoid
                (int)(rigidBodies[i].z * 1000.0),       //int32 HMSL height above mean sea level in mm
                (int)(rigidBodies[i].ecef_vel.x * 100.0), //int32 ECEF velocity X in cm/s
                (int)(rigidBodies[i].ecef_vel.y * 100.0), //int32 ECEF velocity Y in cm/s
                (int)(rigidBodies[i].ecef_vel.z * 100.0), //int32 ECEF velocity Z in cm/s
                (int)(heading * 10000000.0),            //int32 Course in rad*1e7
                (int)cur_time.tv_sec,
                (int)cur_time.tv_usec);
      }
    }





    // Reset the velocity differentiator if we calculated the velocity
    if (rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
      rigidBodies[i].vel_x = 0;
      rigidBodies[i].vel_y = 0;
      rigidBodies[i].vel_z = 0;
      rigidBodies[i].nVelocitySamples = 0;
      rigidBodies[i].totalVelocitySamples = 0;
      rigidBodies[i].nVelocityTransmit = 0;
    }

    rigidBodies[i].nSamples = 0;
  }

  return TRUE;
}
示例#23
0
void myMotifCallback(Widget w,XtPointer client_d,XtPointer call_d){
  // sends the string on the bus
  IvySendMsg (*((char**)client_d));
}
示例#24
0
/* callback associated to "Hello" messages */
void HelloCallback (IvyClientPtr app, void *data, int argc, char **argv)
{
	const char* arg = (argc < 1) ? "" : argv[0];
	IvySendMsg ("Bonjour%s", arg);
}
示例#25
0
static gboolean read_data(GIOChannel *chan, GIOCondition cond, gpointer data) {
  int count;
  char buf[BUFSIZE];

  /* receive data packet containing formatted data */
  count = recv(sock, buf, sizeof(buf), 0);
  if (count > 0) {
    if (count == 23) {
      //    FillBufWith32bit(com_trans.buf, 1, gps_lat);
      gps_lat = buf2uint(&buf[0]);
      //    FillBufWith32bit(com_trans.buf, 5, gps_lon);
      gps_lon = buf2uint(&buf[4]);
      //    FillBufWith16bit(com_trans.buf, 9, (int16_t)(gps_alt/100)); // meters
      gps_alt = buf2ushort(&buf[8]);
      //    FillBufWith16bit(com_trans.buf, 11, gps_gspeed); // ground speed
      gps_gspeed = buf2ushort(&buf[10]);
      //    FillBufWith16bit(com_trans.buf, 13, gps_course); // course
      gps_course = buf2ushort(&buf[12]);
      //    FillBufWith16bit(com_trans.buf, 15, (uint16_t)(estimator_airspeed*100)); // TAS (cm/s)
      estimator_airspeed = buf2ushort(&buf[14]);
      //    com_trans.buf[17] = electrical.vsupply; // decivolt
      //FIXME: electrical.vsupply is now a uint16
      electrical_vsupply = buf[16];
      //    com_trans.buf[18] = (uint8_t)(energy / 100); // deciAh
      energy = buf[17];
      //    com_trans.buf[19] = (uint8_t)(ap_state->commands[COMMAND_THROTTLE]*100/MAX_PPRZ);
      throttle = buf[18];
      //    com_trans.buf[20] = pprz_mode;
      pprz_mode = buf[19];
      //    com_trans.buf[21] = nav_block;
      nav_block = buf[20];
      //    FillBufWith16bit(com_trans.buf, 22, autopilot_flight_time);
      autopilot_flight_time = buf2ushort(&buf[21]);

#if 0
      gps_lat = 52.2648312 * 1e7;
      gps_lon =  9.9939456 * 1e7;
      gps_alt = 169 * 1000;
      gps_gspeed = 13 * 100;
      gps_course = 60 * 10;
      estimator_airspeed = 15 * 100;
      electrical_vsupply = 126;
      energy = 9;
      throttle = 51;
      pprz_mode = 2;
      nav_block = 1;
      autopilot_flight_time = 123;
#endif

      printf("**** message received from iridium module ****\n");
      printf("gps_lat %f\n", DegOfRad(gps_lat/1e7));
      printf("gps_lon %f\n", DegOfRad(gps_lon/1e7));
      printf("gps_alt %d\n", gps_alt);
      printf("gps_gspeed %d\n", gps_gspeed);
      printf("gps_course %d\n", gps_course);
      printf("estimator_airspeed %d\n", estimator_airspeed);
      printf("electrical_vsupply %d\n", electrical_vsupply);
      printf("energy %d\n", energy);
      printf("throttle %d\n", throttle);
      printf("pprz_mode %d\n", pprz_mode);
      printf("nav_block %d\n", nav_block);
      printf("autopilot_flight_time %d\n", autopilot_flight_time);
      fflush(stdout);

      IvySendMsg("%d GENERIC_COM %d %d %d %d %d %d %d %d %d %d %d %d",
          AC_ID,
          gps_lat,
          gps_lon,
          gps_alt,
          gps_gspeed,
          gps_course,
          estimator_airspeed,
          electrical_vsupply,
          energy,
          throttle,
          pprz_mode,
          nav_block,
          autopilot_flight_time);

    }
    else {
      int i = 0;
      // Raw print
      printf("**** Raw message ****\n");
      printf("Char: ");
      for (i = 0; i < count; i++) printf("%c",buf[i]);
      printf("\nHex: ");
      for (i = 0; i < count; i++) printf("%x ",buf[i]);
      printf("\n");
    }
  }
  else {
    printf("disconnect\n");
    close(sock);
    g_main_loop_quit(ml);
    return 0;
  }

  return 1;
}
示例#26
0
//Read tcp requests of connected clients
gboolean network_read(GIOChannel *source, GIOCondition cond, gpointer data) {

  GString *s = g_string_new(NULL);
  GError *error = NULL;
  GIOStatus ret = g_io_channel_read_line_string(source, s, NULL, &error);

  if (ret == G_IO_STATUS_ERROR) {
    //unref connection
    GSocketAddress *sockaddr = g_socket_connection_get_remote_address(data, NULL);
    GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
    //Read sender ip
    if (verbose) {
      printf("App Server: Communication error.. Removing client.. ->%s\n", g_inet_address_to_string(addr));
      fflush(stdout);
    }
    //Remove client
    remove_client(g_inet_address_to_string(addr));
    //Free objects
    g_string_free(s, TRUE);
    g_object_unref(sockaddr);
    g_object_unref(addr);
    g_object_unref(data);
    //Return false to stop listening this socket
    return FALSE;
  }
  else{
    //Read request command
    gchar  *RecString;
    RecString=s->str;
    //check client password
    if ((strncmp(RecString, AppPass, strlen(AppPass))) == 0) {
      //Password ok can send command
      GString *incs = g_string_new(s->str);
      incs = g_string_erase(s,0,(strlen(AppPass)+1));
      IvySendMsg("%s",incs->str);
      if (verbose) {
        printf("App Server: Command passed to ivy: %s\n",incs->str);
        fflush(stdout);
      }
    }
    //AC data request. (Ignore client password)
    else if ((strncmp(RecString, "getac ", strlen("getac "))) == 0) {
      //AC data request
      char AcData[BUFLEN];
      //Read ac data
      if (get_ac_data(RecString, AcData)) {
        //Send requested data to client
        GOutputStream * ostream = g_io_stream_get_output_stream (data);
        g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
      }
    }
    //Waypoint data request (Ignore client password)
    else if ((strncmp(RecString, "getwp ", strlen("getwp "))) == 0) {
      char AcData[BUFLEN];
      //Read wp data of ac
      if (get_wp_data(RecString, AcData)) {
        //Send requested data to client
        GOutputStream * ostream = g_io_stream_get_output_stream (data);
        g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
      }
    }
    //Waypoint data request (Ignore client password)
    else if ((strncmp(RecString, "getbl ", strlen("getbl "))) == 0) {
      char AcData[BUFLEN];
      //Read block data of AC
      if (get_bl_data(RecString, AcData)) {
        //Send requested data to client
        GOutputStream * ostream = g_io_stream_get_output_stream (data);
        g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
      }
    }

    //If client sends removeme command, remove it from broadcast list
    else if ((strncmp( RecString, "removeme", strlen("removeme"))) == 0) {
      GSocketAddress *sockaddr = g_socket_connection_get_remote_address(data, NULL);
      GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
      //Read sender ip
      if (verbose) {
        printf("App Server: need to remove %s\n", g_inet_address_to_string(addr));
        fflush(stdout);
      }
      //Remove client
      remove_client(g_inet_address_to_string(addr));
      //Free objects
      g_string_free(s, TRUE);
      g_object_unref(sockaddr);
      g_object_unref(addr);
      g_object_unref(data);
      //Return false to stop listening this socket
      return FALSE;
    }
    else {
      //Unknown command
      if (verbose) {
        printf("App Server: Client send an unknown command or wrong password: (%s)\n",RecString);
        fflush(stdout);
      }
    }
  }

  if (ret == G_IO_STATUS_EOF) {
    //Client disconnected
    if (verbose) {
      GSocketAddress *sockaddr = g_socket_connection_get_remote_address(data, NULL);
      GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
      printf("App Server: Client disconnected without saying 'bye':( ->%s\n", g_inet_address_to_string(addr));
      remove_client(g_inet_address_to_string(addr));
      fflush(stdout);
    }
    g_string_free(s, TRUE);
    //Unref the socket and return false to allow the client to reconnect
    g_object_unref(data);
    return FALSE;
  }
  //None above.. Keep listening the socket
  g_string_free(s, TRUE);
  return TRUE;
}
示例#27
0
/** The transmitter periodic function */
gboolean timeout_transmit_callback(gpointer data) {
  int i;

  // Loop trough all the available rigidbodies (TODO: optimize)
  for(i = 0; i < MAX_RIGIDBODIES; i++) {
    // Check if ID's are correct
    if(rigidBodies[i].id >= MAX_RIGIDBODIES) {
      fprintf(stderr, "Could not parse rigid body %d from NatNet, because ID is higher then or equal to %d (MAX_RIGIDBODIES-1).\r\n", rigidBodies[i].id, MAX_RIGIDBODIES-1);
      exit(EXIT_FAILURE);
    }

    // Check if we want to transmit (follow) this rigid
    if(aircrafts[rigidBodies[i].id].ac_id == 0)
      continue;

    // When we don track anymore and timeout or start tracking
    if(rigidBodies[i].nSamples < 1
      && aircrafts[rigidBodies[i].id].connected
      && (natnet_latency - aircrafts[rigidBodies[i].id].lastSample) > CONNECTION_TIMEOUT) {
      aircrafts[rigidBodies[i].id].connected = FALSE;
      fprintf(stderr, "#error Lost tracking rigid id %d, aircraft id %d.\n",
        rigidBodies[i].id, aircrafts[rigidBodies[i].id].ac_id);
    }
    else if(rigidBodies[i].nSamples > 0 && !aircrafts[rigidBodies[i].id].connected) {
      fprintf(stderr, "#pragma message: Now tracking rigid id %d, aircraft id %d.\n",
        rigidBodies[i].id, aircrafts[rigidBodies[i].id].ac_id);
    }

    // Check if we still track the rigid
    if(rigidBodies[i].nSamples < 1)
      continue;

    // Update the last tracked
    aircrafts[rigidBodies[i].id].connected = TRUE;
    aircrafts[rigidBodies[i].id].lastSample = natnet_latency;

    // Defines to make easy use of paparazzi math
    struct EnuCoor_d pos, speed;
    struct EcefCoor_d ecef_pos;
    struct LlaCoor_d lla_pos;
    struct DoubleQuat orient;
    struct DoubleEulers orient_eulers;

    // Add the Optitrack angle to the x and y positions
    pos.x = cos(tracking_offset_angle) * rigidBodies[i].x + sin(tracking_offset_angle) * rigidBodies[i].y;
    pos.y = sin(tracking_offset_angle) * rigidBodies[i].x - cos(tracking_offset_angle) * rigidBodies[i].y;
    pos.z = rigidBodies[i].z;

    // Convert the position to ecef and lla based on the Optitrack LTP
    ecef_of_enu_point_d(&ecef_pos ,&tracking_ltp ,&pos);
    lla_of_ecef_d(&lla_pos, &ecef_pos);

    // Check if we have enough samples to estimate the velocity
    rigidBodies[i].nVelocityTransmit++;
    if(rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
      // Calculate the derevative of the sum to get the correct velocity     (1 / freq_transmit) * (samples / total_samples)
      double sample_time = //((double)rigidBodies[i].nVelocitySamples / (double)rigidBodies[i].totalVelocitySamples) / 
                              ((double)rigidBodies[i].nVelocityTransmit / (double)freq_transmit);
      rigidBodies[i].vel_x = rigidBodies[i].vel_x / sample_time;
      rigidBodies[i].vel_y = rigidBodies[i].vel_y / sample_time;
      rigidBodies[i].vel_z = rigidBodies[i].vel_z / sample_time;

      // Add the Optitrack angle to the x and y velocities
      speed.x = cos(tracking_offset_angle) * rigidBodies[i].vel_x + sin(tracking_offset_angle) * rigidBodies[i].vel_y;
      speed.y = sin(tracking_offset_angle) * rigidBodies[i].vel_x - cos(tracking_offset_angle) * rigidBodies[i].vel_y;
      speed.z = rigidBodies[i].vel_z;

      // Conver the speed to ecef based on the Optitrack LTP
      ecef_of_enu_vect_d(&rigidBodies[i].ecef_vel ,&tracking_ltp ,&speed);
    }

    // Copy the quaternions and convert to euler angles for the heading
    orient.qi = rigidBodies[i].qw;
    orient.qx = rigidBodies[i].qx;
    orient.qy = rigidBodies[i].qy;
    orient.qz = rigidBodies[i].qz;
    DOUBLE_EULERS_OF_QUAT(orient_eulers, orient);

    // Calculate the heading by adding the Natnet offset angle and normalizing it
    double heading = -orient_eulers.psi-tracking_offset_angle;
    NormRadAngle(heading);

    printf_debug("[%d -> %d]Samples: %d\t%d\t\tTiming: %3.3f latency\n", rigidBodies[i].id, aircrafts[rigidBodies[i].id].ac_id
      , rigidBodies[i].nSamples, rigidBodies[i].nVelocitySamples, natnet_latency);
    printf_debug("    Heading: %f\t\tPosition: %f\t%f\t%f\t\tVelocity: %f\t%f\t%f\n", DegOfRad(heading), 
      rigidBodies[i].x, rigidBodies[i].y, rigidBodies[i].z, 
      rigidBodies[i].ecef_vel.x, rigidBodies[i].ecef_vel.y, rigidBodies[i].ecef_vel.z);

    // Transmit the REMOTE_GPS packet on the ivy bus
    IvySendMsg("0 REMOTE_GPS %d %d %d %d %d %d %d %d %d %d %d %d %d %d", aircrafts[rigidBodies[i].id].ac_id,
      rigidBodies[i].nMarkers,                //uint8 Number of markers (sv_num)
      (int)(ecef_pos.x*100.0),                //int32 ECEF X in CM
      (int)(ecef_pos.y*100.0),                //int32 ECEF Y in CM
      (int)(ecef_pos.z*100.0),                //int32 ECEF Z in CM
      (int)(lla_pos.lat*10000000.0),          //int32 LLA latitude in rad*1e7
      (int)(lla_pos.lon*10000000.0),          //int32 LLA longitude in rad*1e7
      (int)(rigidBodies[i].z*1000.0),         //int32 LLA altitude in mm above elipsoid
      (int)(rigidBodies[i].z*1000.0),         //int32 HMSL height above mean sea level in mm
      (int)(rigidBodies[i].ecef_vel.x*100.0), //int32 ECEF velocity X in m/s
      (int)(rigidBodies[i].ecef_vel.y*100.0), //int32 ECEF velocity Y in m/s
      (int)(rigidBodies[i].ecef_vel.z*100.0), //int32 ECEF velocity Z in m/s
      0,
      (int)(heading*10000000.0));             //int32 Course in rad*1e7

    // Reset the velocity differentiator if we calculated the velocity
    if(rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
      rigidBodies[i].vel_x = 0;
      rigidBodies[i].vel_y = 0;
      rigidBodies[i].vel_z = 0;
      rigidBodies[i].nVelocitySamples = 0;
      rigidBodies[i].totalVelocitySamples = 0;
      rigidBodies[i].nVelocityTransmit = 0;
    }

    rigidBodies[i].nSamples = 0;
  }

  return TRUE;
}
示例#28
0
void send_ivy(void)
{
  float phi,theta,psi,z,zdot;

  if (new_serial_data == 0)
    return;

  new_serial_data = 0;

  phi = ((float) remote_uav.phi) / 1000.0f;
  theta = ((float) remote_uav.theta) / 1000.0f;
  psi = ((float) remote_uav.psi) / 1000.0f;

  IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", remote_uav.ac_id);

  IvySendMsg("%d ATTITUDE %f %f %f\n", remote_uav.ac_id, phi, psi, theta);

/*
  remote_uav.utm_east = local_uav.utm_east;
  remote_uav.utm_north = local_uav.utm_north + 5000;
  remote_uav.utm_z = local_uav.utm_z + 1000;
  remote_uav.utm_zone = local_uav.utm_zone;
  remote_uav.speed = local_uav.speed * 4;
  remote_uav.psi += 30.;
*/

/*
   <message name="GPS" id="8">
     <field name="mode"       type="uint8"  unit="byte_mask"/>
     <field name="utm_east"   type="int32"  unit="cm" alt_unit="m"/>
     <field name="utm_north"  type="int32"  unit="cm" alt_unit="m"/>
     <field name="course"     type="int16"  unit="decideg" alt_unit="deg"/>
     <field name="alt"        type="int32"  unit="mm" alt_unit="m"/>
     <field name="speed"      type="uint16" unit="cm/s" alt_unit="m/s"/>
     <field name="climb"      type="int16"  unit="cm/s" alt_unit="m/s"/>
     <field name="week"       type="uint16" unit="weeks"/>
     <field name="itow"       type="uint32" unit="ms"/>
     <field name="utm_zone"   type="uint8"/>
     <field name="gps_nb_err" type="uint8"/>
   </message>
*/

  IvySendMsg("%d GPS 3 %d %d 0 %d %d 0 0 0 %d 0\n", remote_uav.ac_id, remote_uav.utm_east, remote_uav.utm_north, remote_uav.utm_z, remote_uav.speed, remote_uav.utm_zone);

/*
  <message name="FBW_STATUS" id="103">
    <field name="rc_status" type="uint8" values="OK|LOST|REALLY_LOST"/>
    <field name="frame_rate" type="uint8" unit="Hz"/>
    <field name="mode" type="uint8" values="MANUAL|AUTO|FAILSAFE"/>
    <field name="vsupply" type="uint8" unit="decivolt"/>
    <field name="current" type="int32" unit="mA"/>
  </message>
*/

  IvySendMsg("%d FBW_STATUS 2 0 1 81 0 \n", remote_uav.ac_id);

  z = ((float)remote_uav.utm_z) / 1000.0f;
  zdot = remote_uav.climb;
  IvySendMsg("%d ESTIMATOR %f %f \n", remote_uav.ac_id, z, zdot);

/*
   <message name="DESIRED" id="16">
     <field name="roll" type="float" format="%.2f" unit="rad" alt_unit="deg" alt_unit_coef="57.3"/>
     <field name="pitch" type="float" format="%.2f" unit="rad" alt_unit="deg" alt_unit_coef="57.3"/>
     <field name="course" type="float" format="%.1f" unit="rad" alt_unit="deg" alt_unit_coef="57.3"/>
     <field name="x" type="float" format="%.0f"  unit="m"/>
     <field name="y" type="float" format="%.0f" unit="m"/>
     <field name="altitude" type="float" format="%.0f"  unit="m"/>
     <field name="climb" type="float" format="%.1f"  unit="m/s"></field>
   </message>
*/
  IvySendMsg("%d DESIRED 0 0 0 0 0 %f 0 \n", remote_uav.ac_id, remote_uav.desired_alt);

/*
   <message name="NAVIGATION" id="10">
     <field name="cur_block" type="uint8"/>
     <field name="cur_stage" type="uint8"/>
     <field name="pos_x" type="float" unit="m" format="%.1f"/>
     <field name="pos_y" type="float" unit="m" format="%.1f"/>
     <field name="dist2_wp" type="float" format="%.1f" unit="m^2"/>
     <field name="dist2_home" type="float" format="%.1f" unit="m^2"/>
     <field name="circle_count" type="uint8"/>
     <field name="oval_count" type="uint8"/>
   </message>
*/

//  IvySendMsg("%d NAVIGATION %d 0 0 0 0 0 0 0 \n", remote_uav.ac_id, remote_uav.block);

/*
   <message name="BAT" id="12">
     <field name="throttle" type="int16" unit="pprz"/>
     <field name="voltage" type="uint8" unit="1e-1V" alt_unit="V" alt_unit_coef="0.1"/>
     <field name="amps" type="int16" unit="A" alt_unit="A" />
     <field name="flight_time" type="uint16" unit="s"/>
     <field name="kill_auto_throttle" type="uint8" unit="bool"/>
     <field name="block_time" type="uint16" unit="s"/>
     <field name="stage_time" type="uint16" unit="s"/>
     <field name="energy" type="int16" unit="mAh"/>
   </message>
*/

  // IvySendMsg("%d BAT 0 81 0 %ld 0 0 0 0\n", remote_uav.ac_id, count_serial);

/*
   <message name="PPRZ_MODE" id="11">
     <field name="ap_mode" type="uint8" values="MANUAL|AUTO1|AUTO2|HOME|NOGPS|FAILSAFE"/>
     <field name="ap_gaz" type="uint8" values="MANUAL|AUTO_THROTTLE|AUTO_CLIMB|AUTO_ALT"/>
     <field name="ap_lateral" type="uint8" values="MANUAL|ROLL_RATE|ROLL|COURSE"/>
     <field name="ap_horizontal" type="uint8" values="WAYPOINT|ROUTE|CIRCLE"/>
     <field name="if_calib_mode" type="uint8" values="NONE|DOWN|UP"/>
     <field name="mcu1_status" type="uint8" values="LOST|OK|REALLY_LOST"/>
   </message>
*/

  // IvySendMsg("%d PPRZ_MODE 0 0 0 0 0 0\n", remote_uav.ac_id);

/*	// Needed to show any NAV info like current block number
   <message name="NAVIGATION_REF" id="9">
     <field name="utm_east"  type="int32" unit="m"/>
     <field name="utm_north" type="int32" unit="m"/>
     <field name="utm_zone" type="uint8"/>
   </message>
*/

  static int delayer = 10;
  delayer++;
  if (delayer > 5)
  {
//    IvySendMsg("%d NAVIGATION_REF %d %d %d\n", remote_uav.ac_id, remote_uav.utm_east, remote_uav.utm_north, remote_uav.utm_zone);
    delayer = 0;
  }




  count_serial++;

  sprintf(status_serial_str, "Read %d from '%s': forwarding to IVY [%ld] {Rx=%ld} {Err=%ld}", remote_uav.ac_id, port,  count_serial, rx_bytes, rx_error);
  gtk_label_set_text( GTK_LABEL(status_serial), status_serial_str );
}
示例#29
0
文件: tcp2ivy.c 项目: AshuLara/lisa
static gboolean read_data(GIOChannel *chan, GIOCondition cond, gpointer data) {
  int count;
  char buf[BUFSIZE];

  /* receive data packet containing formatted data */
  count = recv(sock, buf, sizeof(buf), 0);
  if (count > 0) {
    if (count == 23) {
//    FillBufWith32bit(com_trans.buf, 1, gps_lat);
      gps_lat = buf2uint(&buf[0]);
//    FillBufWith32bit(com_trans.buf, 5, gps_lon);
      gps_lon = buf2uint(&buf[4]);
//    FillBufWith16bit(com_trans.buf, 9, (int16_t)(gps_alt/100)); // meters
      gps_alt = buf2ushort(&buf[8]) * 100;
//    FillBufWith16bit(com_trans.buf, 11, gps_gspeed); // ground speed
      gps_gspeed = buf2ushort(&buf[10]);
//    FillBufWith16bit(com_trans.buf, 13, gps_course); // course
      gps_course = buf2ushort(&buf[12]);
//    FillBufWith16bit(com_trans.buf, 15, (uint16_t)(estimator_airspeed*100)); // TAS (cm/s)
      estimator_airspeed = buf2ushort(&buf[14]);
//    com_trans.buf[16] = electrical.vsupply;
// should be (estimator_airspeed is two bytes):
//    com_trans.buf[17] = electrical.vsupply;
      electrical_vsupply = buf[16];
//    com_trans.buf[17] = (uint8_t)(energy*10);
      energy = buf[17] / 10;
//    com_trans.buf[18] = (uint8_t)(ap_state->commands[COMMAND_THROTTLE]*100/MAX_PPRZ);
      throttle = buf[18];
//    com_trans.buf[19] = pprz_mode;
      pprz_mode = buf[19];
//    com_trans.buf[20] = nav_block;
      nav_block = buf[20];
//    FillBufWith16bit(com_trans.buf, 21, estimator_flight_time); 
      estimator_flight_time = buf2ushort(&buf[21]);

//gps_lat = 52.2648312 * 1e7;
//gps_lon =  9.9939456 * 1e7;
//gps_alt = 169 * 1000;

//gps_gspeed = 13 * 100;
//gps_course = 60 * 10;
//estimator_airspeed = 15 * 100;
//electrical_vsupply = 126;
//energy = 9;
//throttle = 51;
//pprz_mode = 2;
//nav_block = 1;
//estimator_flight_time = 123;

      nav_utm_zone0 = (gps_lon/10000000+180) / 6 + 1;
      latlong_utm_of(RadOfDeg(gps_lat/1e7), RadOfDeg(gps_lon/1e7), nav_utm_zone0);
      gps_utm_east = latlong_utm_x * 100;
      gps_utm_north = latlong_utm_y * 100;
      gps_utm_zone = nav_utm_zone0;

printf("gps_lat %f\n", gps_lat/1e7);
printf("gps_lon %f\n", gps_lon/1e7);
printf("gps_alt %d\n", gps_alt);
printf("gps_gspeed %d\n", gps_gspeed);
printf("gps_course %d\n", gps_course);
printf("estimator_airspeed %d\n", estimator_airspeed);
printf("electrical_vsupply %d\n", electrical_vsupply);
printf("energy %d\n", energy);
printf("throttle %d\n", throttle);
printf("pprz_mode %d\n", pprz_mode);
printf("nav_block %d\n", nav_block);
printf("estimator_flight_time %d\n", estimator_flight_time);

printf("gps_utm_east %d\n", gps_utm_east);
printf("gps_utm_north %d\n", gps_utm_north);
printf("gps_utm_zone %d\n", gps_utm_zone);

/*
   <message name="GPS" id="8">
     <field name="mode"       type="uint8"  unit="byte_mask"/>
     <field name="utm_east"   type="int32"  unit="cm" alt_unit="m"/>
     <field name="utm_north"  type="int32"  unit="cm" alt_unit="m"/>
     <field name="course"     type="int16"  unit="decideg" alt_unit="deg"/>
     <field name="alt"        type="int32"  unit="mm" alt_unit="m"/>
     <field name="speed"      type="uint16" unit="cm/s" alt_unit="m/s"/>
     <field name="climb"      type="int16"  unit="cm/s" alt_unit="m/s"/>
     <field name="week"       type="uint16" unit="weeks"/>
     <field name="itow"       type="uint32" unit="ms"/>
     <field name="utm_zone"   type="uint8"/>
     <field name="gps_nb_err" type="uint8"/>
   </message>
*/
      IvySendMsg("%d GPS %d %d %d %d %d %d %d %d %d %d %d",
                AC_ID,
                3, // mode = 3D
                gps_utm_east,
                gps_utm_north,
                gps_course,
                gps_alt,
                gps_gspeed,
                0, // climb
                0, // week
                0, //itow
                gps_utm_zone,
                0); // gps_nb_err

/*
   <message name="PPRZ_MODE" id="11">
     <field name="ap_mode" type="uint8" values="MANUAL|AUTO1|AUTO2|HOME|NOGPS|FAILSAFE"/>
     <field name="ap_gaz" type="uint8" values="MANUAL|AUTO_THROTTLE|AUTO_CLIMB|AUTO_ALT"/>
     <field name="ap_lateral" type="uint8" values="MANUAL|ROLL_RATE|ROLL|COURSE"/>
     <field name="ap_horizontal" type="uint8" values="WAYPOINT|ROUTE|CIRCLE"/>
     <field name="if_calib_mode" type="uint8" values="NONE|DOWN|UP"/>
     <field name="mcu1_status" type="uint8" values="LOST|OK|REALLY_LOST"/>
   </message>
*/
      IvySendMsg("%d PPRZ_MODE %d %d %d %d %d %d",
                AC_ID,
                pprz_mode,
                0, // ap_gaz
                0, // ap_lateral
                0, // ap_horizontal
                0, // if_calib_mode
                0); // mcu1_status

/*
  <message name="AIRSPEED" id="54">
    <field name="airspeed" type="float" unit="m/s"/>
    <field name="airspeed_sp" type="float" unit="m/s"/>
    <field name="airspeed_cnt" type="float" unit="m/s"/>
    <field name="groundspeed_sp" type="float" unit="m/s"/>
  </message>
*/
      IvySendMsg("%d AIRSPEED %f %d %d %d",
                AC_ID,
                (float)(estimator_airspeed / 100.),
                0, // airspeed_sp
                0, // airspeed_cnt
                0); // groundspeed_sp

/*
   <message name="BAT" id="12">
     <field name="throttle" type="int16" unit="pprz"/>
     <field name="voltage" type="uint8" unit="1e-1V" alt_unit="V" alt_unit_coef="0.1"/>
     <field name="amps" type="int16" unit="A" alt_unit="A" />
     <field name="flight_time" type="uint16" unit="s"/>
     <field name="kill_auto_throttle" type="uint8" unit="bool"/>
     <field name="block_time" type="uint16" unit="s"/>
     <field name="stage_time" type="uint16" unit="s"/>
     <field name="energy" type="int16" unit="mAh"/>
   </message>
*/
      IvySendMsg("%d BAT %d %d %d %d %d %d %d %d",
                AC_ID,
                throttle * MAX_PPRZ / 100,
                electrical_vsupply,
                0, // amps
                estimator_flight_time,
                0, // kill_auto_throttle
                0, // block_time
                0, // stage_time
                energy);

/*
   <message name="NAVIGATION" id="10">
     <field name="cur_block" type="uint8"/>
     <field name="cur_stage" type="uint8"/>
     <field name="pos_x" type="float" unit="m" format="%.1f"/>
     <field name="pos_y" type="float" unit="m" format="%.1f"/>
     <field name="dist2_wp" type="float" format="%.1f" unit="m^2"/>
     <field name="dist2_home" type="float" format="%.1f" unit="m^2"/>
     <field name="circle_count" type="uint8"/>
     <field name="oval_count" type="uint8"/>
   </message>
*/
      IvySendMsg("%d NAVIGATION %d %d %d %d %d %d %d %d",
                AC_ID,
                nav_block,
                0, // cur_stage
                0, // pos_x
                0, // pos_y
                0, // dist2_wp
                0, // dist2_home
                0, // circle_count
                0); // oval_count

/*
  <message name="ESTIMATOR" id="42">
    <field name="z" type="float" unit="m"/>
    <field name="z_dot" type="float" unit="m/s"/>
  </message>
*/
      IvySendMsg("%d ESTIMATOR %f %d",
                AC_ID,
                gps_alt / 1000.,
                0); // z_dot

/*
   <message name="ATTITUDE" id="6">
     <field name="phi"   type="float" unit="rad" alt_unit="deg"/>
     <field name="psi"   type="float" unit="rad" alt_unit="deg"/>
     <field name="theta" type="float" unit="rad" alt_unit="deg"/>
   </message>
*/
      IvySendMsg("%d ATTITUDE %f %f %f",
                AC_ID,
                0., // phi
                RadOfDeg(gps_course / 10.),
                0.); // theta

    }
  }
  else {
    printf("disconnect\n");
    close(sock);
    g_main_loop_quit(ml);
    return 0;
  }

  return 1;
}
示例#30
0
int main(int argc, char **argv) {
  int i;

  //Get process id
  ProcessID= getpid();
  // default password

  AppPass = defaultAppPass;

  // try environment variable first, set to default if failed
  IvyBus = getenv("IVYBUS");
  if (IvyBus == NULL) IvyBus = defaultIvyBus;

  // Parse options
  for (i = 1; i < argc; ++i) {
    if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
      print_help();
      exit(0);
    }
    else if (strcmp(argv[i], "-t") == 0) {
      tcp_port = atoi(argv[++i]);
    }
    else if (strcmp(argv[i], "-u") == 0) {
      udp_port = atoi(argv[++i]);
    }
    else if (strcmp(argv[i], "-b") == 0) {
      IvyBus = argv[++i];
    }
    else if (strcmp(argv[i], "-p") == 0) {
      AppPass = argv[++i];
    }
    else if (strcmp(argv[i], "-v") == 0) {
      verbose = 1;
    }
    else if (strcmp(argv[i], "-utcp") == 0) {
      uTCP = 1;
    }
    else {
      printf("App Server: Unknown option\n");
      print_help();
      exit(0);
    }
  }

  if (verbose) {
    printf("### Paparazzi App Server ###\n");
    printf("Server listen port (TCP)    : %d\n", tcp_port);
    if (uTCP) {
      printf("Server using TCP communication..\n");
    }else{
      printf("Server broadcast port (UDP) : %d\n", udp_port);
    }
    printf("Control Pass                : %s\n", AppPass);
    printf("Ivy Bus                     : %s\n", IvyBus);
    fflush(stdout);
  }


  //Create tcp listener
#if !GLIB_CHECK_VERSION (2, 35, 1)
  // init GLib type system (only for older version)
  g_type_init();
#endif
  GSocketService *service = g_socket_service_new();

  GInetAddress *address = g_inet_address_new_any(G_SOCKET_FAMILY_IPV6); //G_SOCKET_FAMILY_IPV4 could be used
  GSocketAddress *socket_address = g_inet_socket_address_new(address, tcp_port);
  //Add listener
  g_socket_listener_add_address(G_SOCKET_LISTENER(service), socket_address, G_SOCKET_TYPE_STREAM,
      G_SOCKET_PROTOCOL_TCP, NULL, NULL, NULL);

  g_object_unref(socket_address);
  g_object_unref(address);
  g_socket_service_start(service);

  //Connect listening signal
  g_signal_connect(service, "incoming", G_CALLBACK(new_connection), NULL);

  //Here comes the ivy bindings
  IvyInit ("PPRZ_App_Server", "Papparazzi App Server Ready!", NULL, NULL, NULL, NULL);

  IvyBindMsg(Ivy_All_Msgs, NULL, "(^ground (\\S*) (\\S*) .*)");
  IvyBindMsg(on_app_server_NEW_AC, NULL, "ground NEW_AIRCRAFT (\\S*)");
  IvyBindMsg(on_app_server_GET_CONFIG, NULL, "(\\S*) ground CONFIG (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
  IvyBindMsg(on_app_server_AIRCRAFTS, NULL, "(\\S*) ground AIRCRAFTS (\\S*)");
  IvyStart(IvyBus);

  GMainLoop *loop = g_main_loop_new(NULL, FALSE);

  if (verbose) {
    printf("Starting App Server\n");
    fflush(stdout);
  }
  IvySendMsg("app_server");

  g_timeout_add(100, request_ac_list, NULL);

  g_main_loop_run(loop);

  if (verbose) {
    printf("Stoping App Server\n");
    fflush(stdout);
  }
  return 0;
}