From 222009002e6424ffad17602fcb9bde81827c20c8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell <tridge@samba.org> Date: Mon, 2 Apr 2012 09:24:05 +1000 Subject: [PATCH] MAVLink: allow for find grained stream rate control streams can now be requested at any multiple of 20ms. So if you ask for a stream at 7Hz then you will get it at close to 7Hz. --- ArduPlane/ArduPlane.pde | 11 +--- ArduPlane/GCS.h | 34 ++++++---- ArduPlane/GCS_Mavlink.pde | 127 +++++++++++++++++++++++--------------- ArduPlane/planner.pde | 5 +- 4 files changed, 101 insertions(+), 76 deletions(-) diff --git a/ArduPlane/ArduPlane.pde b/ArduPlane/ArduPlane.pde index 8235efef7..0b0efbf26 100644 --- a/ArduPlane/ArduPlane.pde +++ b/ArduPlane/ArduPlane.pde @@ -749,11 +749,8 @@ static void fast_loop() // ------------------------------ set_servos(); - - // XXX is it appropriate to be doing the comms below on the fast loop? - gcs_update(); - gcs_data_stream_send(45,1000); + gcs_data_stream_send(); } static void medium_loop() @@ -854,10 +851,6 @@ Serial.println(tempaccel.z, DEC); if (g.log_bitmask & MASK_LOG_GPS) Log_Write_GPS(g_gps->time, current_loc.lat, current_loc.lng, g_gps->altitude, current_loc.alt, (long) g_gps->ground_speed, g_gps->ground_course, g_gps->fix, g_gps->num_sats); - - // send all requested output streams with rates requested - // between 5 and 45 Hz - gcs_data_stream_send(5,45); break; // This case controls the slow loop @@ -919,7 +912,6 @@ static void slow_loop() update_events(); mavlink_system.sysid = g.sysid_this_mav; // This is just an ugly hack to keep mavlink_system.sysid sync'd with our parameter - gcs_data_stream_send(3,5); #if USB_MUX_PIN > 0 check_usb_mux(); @@ -936,7 +928,6 @@ static void one_second_loop() // send a heartbeat gcs_send_message(MSG_HEARTBEAT); - gcs_data_stream_send(1,3); } static void update_GPS(void) diff --git a/ArduPlane/GCS.h b/ArduPlane/GCS.h index 6a1fc4182..f3eee5bab 100644 --- a/ArduPlane/GCS.h +++ b/ArduPlane/GCS.h @@ -76,16 +76,8 @@ public: /// void send_text(gcs_severity severity, const prog_char_t *str) {} - // test if frequency within range requested for loop - // used by data_stream_send - static bool freqLoopMatch(uint16_t freq, uint16_t freqMin, uint16_t freqMax) - { - if (freq != 0 && freq >= freqMin && freq < freqMax) return true; - else return false; - } - // send streams which match frequency range - void data_stream_send(uint16_t freqMin, uint16_t freqMax); + void data_stream_send(void); // set to true if this GCS link is active bool initialised; @@ -118,12 +110,28 @@ public: void send_message(enum ap_message id); void send_text(gcs_severity severity, const char *str); void send_text(gcs_severity severity, const prog_char_t *str); - void data_stream_send(uint16_t freqMin, uint16_t freqMax); + void data_stream_send(void); void queued_param_send(); void queued_waypoint_send(); static const struct AP_Param::GroupInfo var_info[]; + // NOTE! The streams enum below and the + // set of AP_Int16 stream rates _must_ be + // kept in the same order + enum streams {STREAM_RAW_SENSORS, + STREAM_EXTENDED_STATUS, + STREAM_RC_CHANNELS, + STREAM_RAW_CONTROLLER, + STREAM_POSITION, + STREAM_EXTRA1, + STREAM_EXTRA2, + STREAM_EXTRA3, + NUM_STREAMS}; + + // see if we should send a stream now. Called at 50Hz + bool stream_trigger(enum streams stream_num); + private: void handleMessage(mavlink_message_t * msg); @@ -168,7 +176,8 @@ private: uint16_t waypoint_send_timeout; // milliseconds uint16_t waypoint_receive_timeout; // milliseconds - // data stream rates + // data stream rates. The code assumes that + // streamRateRawSensors is the first AP_Int16 streamRateRawSensors; AP_Int16 streamRateExtendedStatus; AP_Int16 streamRateRCChannels; @@ -177,6 +186,9 @@ private: AP_Int16 streamRateExtra1; AP_Int16 streamRateExtra2; AP_Int16 streamRateExtra3; + + // number of 50Hz ticks until we next send this stream + uint8_t stream_ticks[NUM_STREAMS]; }; #endif // __GCS_H diff --git a/ArduPlane/GCS_Mavlink.pde b/ArduPlane/GCS_Mavlink.pde index 3d7e2d35b..c8cd783c1 100644 --- a/ArduPlane/GCS_Mavlink.pde +++ b/ArduPlane/GCS_Mavlink.pde @@ -886,64 +886,89 @@ GCS_MAVLINK::update(void) } } +// see if we should send a stream now. Called at 50Hz +bool GCS_MAVLINK::stream_trigger(enum streams stream_num) +{ + AP_Int16 *stream_rates = &streamRateRawSensors; + uint8_t rate = (uint8_t)stream_rates[stream_num].get(); + + if (rate == 0) { + return false; + } + + if (stream_ticks[stream_num] == 0) { + // we're triggering now, setup the next trigger point + if (rate > 50) { + rate = 50; + } + stream_ticks[stream_num] = 50 / rate; + return true; + } + + // count down at 50Hz + stream_ticks[stream_num]--; + return false; +} + void -GCS_MAVLINK::data_stream_send(uint16_t freqMin, uint16_t freqMax) +GCS_MAVLINK::data_stream_send(void) { - if (waypoint_sending == false && waypoint_receiving == false && _queued_parameter == NULL) { + if (waypoint_sending || waypoint_receiving || _queued_parameter != NULL) { + // don't send the streams when transferring bulk data + return; + } - if (freqLoopMatch(streamRateRawSensors, freqMin, freqMax)){ - send_message(MSG_RAW_IMU1); - send_message(MSG_RAW_IMU2); - send_message(MSG_RAW_IMU3); - } + if (stream_trigger(STREAM_RAW_SENSORS)) { + send_message(MSG_RAW_IMU1); + send_message(MSG_RAW_IMU2); + send_message(MSG_RAW_IMU3); + } - if (freqLoopMatch(streamRateExtendedStatus, freqMin, freqMax)) { - send_message(MSG_EXTENDED_STATUS1); - send_message(MSG_EXTENDED_STATUS2); - send_message(MSG_CURRENT_WAYPOINT); - send_message(MSG_GPS_RAW); // TODO - remove this message after location message is working - send_message(MSG_NAV_CONTROLLER_OUTPUT); - send_message(MSG_FENCE_STATUS); - - if (last_gps_satellites != g_gps->num_sats) { - // this message is mostly a huge waste of bandwidth, - // except it is the only message that gives the number - // of visible satellites. So only send it when that - // changes. - send_message(MSG_GPS_STATUS); - last_gps_satellites = g_gps->num_sats; - } - } + if (stream_trigger(STREAM_EXTENDED_STATUS)) { + send_message(MSG_EXTENDED_STATUS1); + send_message(MSG_EXTENDED_STATUS2); + send_message(MSG_CURRENT_WAYPOINT); + send_message(MSG_GPS_RAW); // TODO - remove this message after location message is working + send_message(MSG_NAV_CONTROLLER_OUTPUT); + send_message(MSG_FENCE_STATUS); + + if (last_gps_satellites != g_gps->num_sats) { + // this message is mostly a huge waste of bandwidth, + // except it is the only message that gives the number + // of visible satellites. So only send it when that + // changes. + send_message(MSG_GPS_STATUS); + last_gps_satellites = g_gps->num_sats; + } + } - if (freqLoopMatch(streamRatePosition, freqMin, freqMax)) { - // sent with GPS read - send_message(MSG_LOCATION); - } + if (stream_trigger(STREAM_POSITION)) { + // sent with GPS read + send_message(MSG_LOCATION); + } - if (freqLoopMatch(streamRateRawController, freqMin, freqMax)) { - // This is used for HIL. Do not change without discussing with HIL maintainers - send_message(MSG_SERVO_OUT); - } + if (stream_trigger(STREAM_RAW_CONTROLLER)) { + send_message(MSG_SERVO_OUT); + } - if (freqLoopMatch(streamRateRCChannels, freqMin, freqMax)) { - send_message(MSG_RADIO_OUT); - send_message(MSG_RADIO_IN); - } + if (stream_trigger(STREAM_RC_CHANNELS)) { + send_message(MSG_RADIO_OUT); + send_message(MSG_RADIO_IN); + } - if (freqLoopMatch(streamRateExtra1, freqMin, freqMax)){ // Use Extra 1 for AHRS info - send_message(MSG_ATTITUDE); - send_message(MSG_SIMSTATE); - } + if (stream_trigger(STREAM_EXTRA1)) { + send_message(MSG_ATTITUDE); + send_message(MSG_SIMSTATE); + } - if (freqLoopMatch(streamRateExtra2, freqMin, freqMax)){ // Use Extra 2 for additional HIL info - send_message(MSG_VFR_HUD); - } + if (stream_trigger(STREAM_EXTRA2)) { + send_message(MSG_VFR_HUD); + } - if (freqLoopMatch(streamRateExtra3, freqMin, freqMax)){ - send_message(MSG_AHRS); - send_message(MSG_HWSTATUS); - } - } + if (stream_trigger(STREAM_EXTRA3)) { + send_message(MSG_AHRS); + send_message(MSG_HWSTATUS); + } } @@ -2157,11 +2182,11 @@ static void gcs_send_message(enum ap_message id) /* send data streams in the given rate range on both links */ -static void gcs_data_stream_send(uint16_t freqMin, uint16_t freqMax) +static void gcs_data_stream_send(void) { - gcs0.data_stream_send(freqMin, freqMax); + gcs0.data_stream_send(); if (gcs3.initialised) { - gcs3.data_stream_send(freqMin, freqMax); + gcs3.data_stream_send(); } } diff --git a/ArduPlane/planner.pde b/ArduPlane/planner.pde index 94ef061e4..86147133d 100644 --- a/ArduPlane/planner.pde +++ b/ArduPlane/planner.pde @@ -41,11 +41,8 @@ planner_gcs(uint8_t argc, const Menu::arg *argv) read_radio(); - gcs_data_stream_send(45,1000); - if ((loopcount % 5) == 0) // 10 hz - gcs_data_stream_send(5,45); + gcs_data_stream_send(); if ((loopcount % 16) == 0) { // 3 hz - gcs_data_stream_send(1,5); gcs_send_message(MSG_HEARTBEAT); } loopcount++; -- GitLab