diff --git a/HISTORY.txt b/HISTORY.txt index 7b5990e28..69419ac1a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -16,6 +16,16 @@ Made the flight mode switch and accessory pots move according to user input on t Changed the board pictures on the uploader widget 2012-07-27 Add more verbose debug output on the UAVOBJECTS saving code. + +Short summary of changes. For a complete list see the git log. +2012-07-20 +AeroSimRC simulator plugin is now included into the Windows distribution +(will be installed into .../OpenPilot/misc/AeroSIM-RC directory). Still +being an experimental development tool, it could be used to play with +HITL version 2. Other platforms include udp_test utility which can be +used to check the connectivity with AeroSimRC plugin running on Windows +machine. + 2012-07-10 On Windows the installation mode was changed from per-user to per-machine (for all users) installation. It is recommended to completely uninstall diff --git a/flight/CopterControl/Makefile b/flight/CopterControl/Makefile index 82334e56a..7c5498806 100644 --- a/flight/CopterControl/Makefile +++ b/flight/CopterControl/Makefile @@ -199,6 +199,8 @@ SRC += $(OPUAVSYNTHDIR)/attitudesettings.c SRC += $(OPUAVSYNTHDIR)/camerastabsettings.c SRC += $(OPUAVSYNTHDIR)/cameradesired.c SRC += $(OPUAVSYNTHDIR)/gpsposition.c +SRC += $(OPUAVSYNTHDIR)/gpsvelocity.c +SRC += $(OPUAVSYNTHDIR)/gpssettings.c SRC += $(OPUAVSYNTHDIR)/hwsettings.c SRC += $(OPUAVSYNTHDIR)/gcsreceiver.c SRC += $(OPUAVSYNTHDIR)/receiveractivity.c diff --git a/flight/CopterControl/System/inc/pios_config.h b/flight/CopterControl/System/inc/pios_config.h index dc3b10026..90ca55866 100644 --- a/flight/CopterControl/System/inc/pios_config.h +++ b/flight/CopterControl/System/inc/pios_config.h @@ -58,7 +58,8 @@ #define PIOS_INCLUDE_TELEMETRY_RF #define PIOS_INCLUDE_GPS #define PIOS_GPS_MINIMAL - +#define PIOS_INCLUDE_GPS_NMEA_PARSER /* Include the NMEA protocol parser */ +#define PIOS_INCLUDE_GPS_UBX_PARSER /* Include the UBX protocol parser */ #define PIOS_INCLUDE_SERVO #define PIOS_INCLUDE_SPI #define PIOS_INCLUDE_SYS diff --git a/flight/Modules/GPS/GPS.c b/flight/Modules/GPS/GPS.c index 716e47aa3..5851ac10d 100644 --- a/flight/Modules/GPS/GPS.c +++ b/flight/Modules/GPS/GPS.c @@ -33,18 +33,19 @@ #include "openpilot.h" #include "GPS.h" -#include - -#include "NMEA.h" - #include "gpsposition.h" #include "homelocation.h" #include "gpstime.h" #include "gpssatellites.h" +#include "gpsvelocity.h" +#include "gpssettings.h" #include "WorldMagModel.h" #include "CoordinateConversions.h" #include "hwsettings.h" +#include "NMEA.h" +#include "UBX.h" + // **************** // Private functions @@ -61,16 +62,18 @@ static float GravityAccel(float latitude, float longitude, float altitude); // Private constants #define GPS_TIMEOUT_MS 500 -#define NMEA_MAX_PACKET_LENGTH 96 // 82 max NMEA msg size plus 12 margin (because some vendors add custom crap) plus CR plus Linefeed -// same as in COM buffer #ifdef PIOS_GPS_SETS_HOMELOCATION // Unfortunately need a good size stack for the WMM calculation - #define STACK_SIZE_BYTES 800 + #define STACK_SIZE_BYTES 750 +#else +#if defined(PIOS_GPS_MINIMAL) + #define STACK_SIZE_BYTES 500 #else #define STACK_SIZE_BYTES 650 -#endif +#endif // PIOS_GPS_MINIMAL +#endif // PIOS_GPS_SETS_HOMELOCATION #define TASK_PRIORITY (tskIDLE_PRIORITY + 1) @@ -86,9 +89,8 @@ static char* gps_rx_buffer; static uint32_t timeOfLastCommandMs; static uint32_t timeOfLastUpdateMs; -static uint32_t numUpdates; -static uint32_t numChecksumErrors; -static uint32_t numParsingErrors; + +static struct GPS_RX_STATS gpsRxStats; // **************** /** @@ -120,6 +122,7 @@ int32_t GPSStart(void) int32_t GPSInitialize(void) { gpsPort = PIOS_COM_GPS; + uint8_t gpsProtocol; #ifdef MODULE_GPS_BUILTIN gpsEnabled = true; @@ -137,6 +140,7 @@ int32_t GPSInitialize(void) if (gpsPort && gpsEnabled) { GPSPositionInitialize(); + GPSVelocityInitialize(); #if !defined(PIOS_GPS_MINIMAL) GPSTimeInitialize(); GPSSatellitesInitialize(); @@ -145,8 +149,21 @@ int32_t GPSInitialize(void) HomeLocationInitialize(); #endif updateSettings(); + } - gps_rx_buffer = pvPortMalloc(NMEA_MAX_PACKET_LENGTH); + if (gpsPort && gpsEnabled) { + GPSSettingsInitialize(); + GPSSettingsDataProtocolGet(&gpsProtocol); + switch (gpsProtocol) { + case GPSSETTINGS_DATAPROTOCOL_NMEA: + gps_rx_buffer = pvPortMalloc(NMEA_MAX_PACKET_LENGTH); + break; + case GPSSETTINGS_DATAPROTOCOL_UBX: + gps_rx_buffer = pvPortMalloc(sizeof(struct UBXPacket)); + break; + default: + gps_rx_buffer = NULL; + } PIOS_Assert(gps_rx_buffer); return 0; @@ -165,140 +182,75 @@ MODULE_INITCALL(GPSInitialize, GPSStart) static void gpsTask(void *parameters) { portTickType xDelay = 100 / portTICK_RATE_MS; - uint32_t timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;; - GPSPositionData GpsData; - - uint8_t rx_count = 0; - bool start_flag = false; - bool found_cr = false; - int32_t gpsRxOverflow = 0; - - numUpdates = 0; - numChecksumErrors = 0; - numParsingErrors = 0; + uint32_t timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; + + GPSPositionData gpsposition; + uint8_t gpsProtocol; + + GPSSettingsDataProtocolGet(&gpsProtocol); timeOfLastUpdateMs = timeNowMs; timeOfLastCommandMs = timeNowMs; + GPSPositionGet(&gpsposition); // Loop forever while (1) { uint8_t c; - // NMEA or SINGLE-SENTENCE GPS mode // This blocks the task until there is something on the buffer while (PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, xDelay) > 0) { - - // detect start while acquiring stream - if (!start_flag && (c == '$')) - { - start_flag = true; - found_cr = false; - rx_count = 0; + int res; + switch (gpsProtocol) { +#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) + case GPSSETTINGS_DATAPROTOCOL_NMEA: + res = parse_nmea_stream (c,gps_rx_buffer, &gpsposition, &gpsRxStats); + break; +#endif +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + case GPSSETTINGS_DATAPROTOCOL_UBX: + res = parse_ubx_stream (c,gps_rx_buffer, &gpsposition, &gpsRxStats); + break; +#endif + default: + res = NO_PARSER; // this should not happen + break; } - else - if (!start_flag) - continue; - - if (rx_count >= NMEA_MAX_PACKET_LENGTH) - { - // The buffer is already full and we haven't found a valid NMEA sentence. - // Flush the buffer and note the overflow event. - gpsRxOverflow++; - start_flag = false; - found_cr = false; - rx_count = 0; - } - else - { - gps_rx_buffer[rx_count] = c; - rx_count++; - } - - // look for ending '\r\n' sequence - if (!found_cr && (c == '\r') ) - found_cr = true; - else - if (found_cr && (c != '\n') ) - found_cr = false; // false end flag - else - if (found_cr && (c == '\n') ) - { - // The NMEA functions require a zero-terminated string - // As we detected \r\n, the string as for sure 2 bytes long, we will also strip the \r\n - gps_rx_buffer[rx_count-2] = 0; - // prepare to parse next sentence - start_flag = false; - found_cr = false; - rx_count = 0; - // Our rxBuffer must look like this now: - // [0] = '$' - // ... = zero or more bytes of sentence payload - // [end_pos - 1] = '\r' - // [end_pos] = '\n' - // - // Prepare to consume the sentence from the buffer - - // Validate the checksum over the sentence - if (!NMEA_checksum(&gps_rx_buffer[1])) - { // Invalid checksum. May indicate dropped characters on Rx. - //PIOS_DEBUG_PinHigh(2); - ++numChecksumErrors; - //PIOS_DEBUG_PinLow(2); - } - else - { // Valid checksum, use this packet to update the GPS position - if (!NMEA_update_position(&gps_rx_buffer[1])) { - //PIOS_DEBUG_PinHigh(2); - ++numParsingErrors; - //PIOS_DEBUG_PinLow(2); - } - else - ++numUpdates; - - timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; - timeOfLastUpdateMs = timeNowMs; - timeOfLastCommandMs = timeNowMs; - } + if (res == PARSER_COMPLETE) { + timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; + timeOfLastUpdateMs = timeNowMs; + timeOfLastCommandMs = timeNowMs; } } // Check for GPS timeout timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; - if ((timeNowMs - timeOfLastUpdateMs) >= GPS_TIMEOUT_MS) - { // we have not received any valid GPS sentences for a while. + if ((timeNowMs - timeOfLastUpdateMs) >= GPS_TIMEOUT_MS) { + // we have not received any valid GPS sentences for a while. // either the GPS is not plugged in or a hardware problem or the GPS has locked up. - - GPSPositionGet(&GpsData); - GpsData.Status = GPSPOSITION_STATUS_NOGPS; - GPSPositionSet(&GpsData); + uint8_t status = GPSPOSITION_STATUS_NOGPS; + GPSPositionStatusSet(&status); AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR); - - } - else - { // we appear to be receiving GPS sentences OK, we've had an update - - GPSPositionGet(&GpsData); - -#ifdef PIOS_GPS_SETS_HOMELOCATION - HomeLocationData home; - HomeLocationGet(&home); - - if ((GpsData.Status == GPSPOSITION_STATUS_FIX3D) && (home.Set == HOMELOCATION_SET_FALSE)) - setHomeLocation(&GpsData); -#endif - + } else { + // we appear to be receiving GPS sentences OK, we've had an update //criteria for GPS-OK taken from this post... //http://forums.openpilot.org/topic/1523-professors-insgps-in-svn/page__view__findpost__p__5220 - if ((GpsData.PDOP < 3.5) && (GpsData.Satellites >= 7)) + if ((gpsposition.PDOP < 3.5) && (gpsposition.Satellites >= 7) && + (gpsposition.Status == GPSPOSITION_STATUS_FIX3D)) { AlarmsClear(SYSTEMALARMS_ALARM_GPS); - else - if (GpsData.Status == GPSPOSITION_STATUS_FIX3D) - AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_WARNING); - else - AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL); +#ifdef PIOS_GPS_SETS_HOMELOCATION + HomeLocationData home; + HomeLocationGet(&home); + + if (home.Set == HOMELOCATION_SET_FALSE) + setHomeLocation(&gpsposition); +#endif + } else if (gpsposition.Status == GPSPOSITION_STATUS_FIX3D) + AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_WARNING); + else + AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL); } } @@ -338,14 +290,6 @@ static void setHomeLocation(GPSPositionData * gpsData) // Compute home ECEF coordinates and the rotation matrix into NED double LLA[3] = { ((double)home.Latitude) / 10e6, ((double)home.Longitude) / 10e6, ((double)home.Altitude) }; - double ECEF[3]; - RneFromLLA(LLA, (float (*)[3])home.RNE); - LLA2ECEF(LLA, ECEF); - // TODO: Currently UAVTalk only supports float but these conversions use double - // need to find out if they require that precision and if so extend UAVTAlk - home.ECEF[0] = (int32_t) (ECEF[0] * 100); - home.ECEF[1] = (int32_t) (ECEF[1] * 100); - home.ECEF[2] = (int32_t) (ECEF[2] * 100); // Compute magnetic flux direction at home location if (WMM_GetMagVector(LLA[0], LLA[1], LLA[2], gps.Month, gps.Day, gps.Year, &home.Be[0]) >= 0) diff --git a/flight/Modules/GPS/NMEA.c b/flight/Modules/GPS/NMEA.c index 59593b807..17b1678ba 100644 --- a/flight/Modules/GPS/NMEA.c +++ b/flight/Modules/GPS/NMEA.c @@ -30,10 +30,14 @@ #include "openpilot.h" #include "pios.h" -#include "NMEA.h" + +#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) + #include "gpsposition.h" +#include "NMEA.h" #include "gpstime.h" #include "gpssatellites.h" +#include "GPS.h" //#define ENABLE_DEBUG_MSG ///< define to enable debug-messages #define DEBUG_PORT PIOS_COM_TELEM_RF ///< defines which serial port is ued for debug-messages @@ -43,7 +47,7 @@ // Debugging #ifdef ENABLE_DEBUG_MSG //#define DEBUG_MSG_IN ///< define to display the incoming NMEA messages -//#define DEBUG_PARS ///< define to display the incoming NMEA messages split into its parameters +//#define DEBUG_PARAMS ///< define to display the incoming NMEA messages split into its parameters //#define DEBUG_MGSID_IN ///< define to display the the names of the incoming NMEA messages //#define NMEA_DEBUG_PKT ///< define to enable debug of all NMEA messages //#define NMEA_DEBUG_GGA ///< define to enable debug of GGA messages @@ -63,7 +67,6 @@ struct nmea_parser { const char *prefix; bool(*handler) (GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); - uint32_t cnt; }; static bool nmeaProcessGPGGA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); @@ -75,50 +78,125 @@ static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, ch static bool nmeaProcessGPGSV(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); #endif //PIOS_GPS_MINIMAL - -static struct nmea_parser nmea_parsers[] = { +const static struct nmea_parser nmea_parsers[] = { { .prefix = "GPGGA", .handler = nmeaProcessGPGGA, - .cnt = 0, }, { .prefix = "GPVTG", .handler = nmeaProcessGPVTG, - .cnt = 0, }, { .prefix = "GPGSA", .handler = nmeaProcessGPGSA, - .cnt = 0, }, { .prefix = "GPRMC", .handler = nmeaProcessGPRMC, - .cnt = 0, }, #if !defined(PIOS_GPS_MINIMAL) { .prefix = "GPZDA", .handler = nmeaProcessGPZDA, - .cnt = 0, }, { .prefix = "GPGSV", .handler = nmeaProcessGPGSV, - .cnt = 0, }, #endif //PIOS_GPS_MINIMAL }; -static struct nmea_parser *NMEA_find_parser_by_prefix(const char *prefix) +int parse_nmea_stream (uint8_t c, char *gps_rx_buffer, GPSPositionData *GpsData, struct GPS_RX_STATS *gpsRxStats) +{ + static uint8_t rx_count = 0; + static bool start_flag = false; + static bool found_cr = false; + + // detect start while acquiring stream + if (!start_flag && (c == '$')) // NMEA identifier found + { + start_flag = true; + found_cr = false; + rx_count = 0; + } + else + if (!start_flag) + return PARSER_ERROR; + + if (rx_count >= NMEA_MAX_PACKET_LENGTH) + { + // The buffer is already full and we haven't found a valid NMEA sentence. + // Flush the buffer and note the overflow event. + gpsRxStats->gpsRxOverflow++; + start_flag = false; + found_cr = false; + rx_count = 0; + return PARSER_OVERRUN; + } + else + { + gps_rx_buffer[rx_count] = c; + rx_count++; + } + + // look for ending '\r\n' sequence + if (!found_cr && (c == '\r') ) + found_cr = true; + else + if (found_cr && (c != '\n') ) + found_cr = false; // false end flag + else + if (found_cr && (c == '\n') ) + { + // The NMEA functions require a zero-terminated string + // As we detected \r\n, the string as for sure 2 bytes long, we will also strip the \r\n + gps_rx_buffer[rx_count-2] = 0; + + // prepare to parse next sentence + start_flag = false; + found_cr = false; + rx_count = 0; + // Our rxBuffer must look like this now: + // [0] = '$' + // ... = zero or more bytes of sentence payload + // [end_pos - 1] = '\r' + // [end_pos] = '\n' + // + // Prepare to consume the sentence from the buffer + + // Validate the checksum over the sentence + if (!NMEA_checksum(&gps_rx_buffer[1])) + { // Invalid checksum. May indicate dropped characters on Rx. + //PIOS_DEBUG_PinHigh(2); + gpsRxStats->gpsRxChkSumError++; + //PIOS_DEBUG_PinLow(2); + return PARSER_ERROR; + } + else + { // Valid checksum, use this packet to update the GPS position + if (!NMEA_update_position(&gps_rx_buffer[1], GpsData)) { + //PIOS_DEBUG_PinHigh(2); + gpsRxStats->gpsRxParserError++; + //PIOS_DEBUG_PinLow(2); + } + else + gpsRxStats->gpsRxReceived++;; + + return PARSER_COMPLETE; + } + } + return PARSER_INCOMPLETE; +} + +const static struct nmea_parser *NMEA_find_parser_by_prefix(const char *prefix) { if (!prefix) { return (NULL); } for (uint8_t i = 0; i < NELEMENTS(nmea_parsers); i++) { - struct nmea_parser *parser = &nmea_parsers[i]; + const struct nmea_parser *parser = &nmea_parsers[i]; /* Use strcmp to check for exact equality over the entire prefix */ if (!strcmp(prefix, parser->prefix)) { @@ -234,6 +312,10 @@ static bool NMEA_latlon_to_fixed_point(int32_t * latlon, char *nmea_latlon, bool PIOS_DEBUG_Assert(nmea_latlon); PIOS_DEBUG_Assert(latlon); + if (*nmea_latlon == '\0') { /* empty lat/lon field */ + return false; + } + if (!NMEA_parse_real(&num_DDDMM, &num_m, &units, nmea_latlon)) { return false; } @@ -285,7 +367,7 @@ static bool NMEA_latlon_to_fixed_point(int32_t * latlon, char *nmea_latlon, bool * \return true if the sentence was successfully parsed * \return false if any errors were encountered with the parsing */ -bool NMEA_update_position(char *nmea_sentence) +bool NMEA_update_position(char *nmea_sentence, GPSPositionData *GpsData) { char* p = nmea_sentence; char* params[MAX_NB_PARAMS]; @@ -327,7 +409,7 @@ bool NMEA_update_position(char *nmea_sentence) #endif // The first parameter is the message name, lets see if we find a parser for it - struct nmea_parser *parser; + const struct nmea_parser *parser; parser = NMEA_find_parser_by_prefix(params[0]); if (!parser) { // No parser found @@ -335,18 +417,22 @@ bool NMEA_update_position(char *nmea_sentence) return false; } - parser->cnt++; #ifdef DEBUG_MGSID_IN - DEBUG_MSG("%s %d ", params[0], parser->cnt); + DEBUG_MSG("%s %d ", params[0]); #endif - // Send the message to then parser and get it update the GpsData - GPSPositionData GpsData; - GPSPositionGet(&GpsData); - bool gpsDataUpdated; + // Send the message to the parser and get it update the GpsData + // Information from various different NMEA messages are temporarily + // cumulated in the GpsData structure. An actual GPSPosition update + // is triggered by GGA messages only. This message type sets the + // gpsDataUpdated flag to request this. + bool gpsDataUpdated = false; - if (!parser->handler(&GpsData, &gpsDataUpdated, params, nbParams)) { + if (!parser->handler(GpsData, &gpsDataUpdated, params, nbParams)) { // Parse failed DEBUG_MSG("PARSE FAILED (\"%s\")\n", params[0]); + if (gpsDataUpdated && (GpsData->Status == GPSPOSITION_STATUS_NOFIX)) { + GPSPositionSet(GpsData); + } return false; } @@ -356,7 +442,7 @@ bool NMEA_update_position(char *nmea_sentence) #ifdef DEBUG_MGSID_IN DEBUG_MSG("U"); #endif - GPSPositionSet(&GpsData); + GPSPositionSet(GpsData); } #ifdef DEBUG_MGSID_IN @@ -390,6 +476,13 @@ static bool nmeaProcessGPGGA(GPSPositionData * GpsData, bool* gpsDataUpdated, ch *gpsDataUpdated = true; + // check for invalid GPS fix + // do this first to make sure we get this information, even if later checks exit + // this function early + if (param[6][0] == '0') { + GpsData->Status = GPSPOSITION_STATUS_NOFIX; // treat invalid fix as NOFIX + } + // get latitude [DDMM.mmmmm] [N|S] if (!NMEA_latlon_to_fixed_point(&GpsData->Latitude, param[2], param[3][0] == 'S')) { return false; @@ -431,7 +524,7 @@ static bool nmeaProcessGPRMC(GPSPositionData * GpsData, bool* gpsDataUpdated, ch DEBUG_MSG(" DateOfFix=%s\n\n", param[9]); #endif - *gpsDataUpdated = true; + *gpsDataUpdated = false; #if !defined(PIOS_GPS_MINIMAL) GPSTimeData gpst; @@ -444,6 +537,11 @@ static bool nmeaProcessGPRMC(GPSPositionData * GpsData, bool* gpsDataUpdated, ch gpst.Hour = (int)hms / 10000; #endif //PIOS_GPS_MINIMAL + // don't process void sentences + if (param[2][0] == 'V') { + return false; + } + // get latitude [DDMM.mmmmm] [N|S] if (!NMEA_latlon_to_fixed_point(&GpsData->Latitude, param[3], param[4][0] == 'S')) { return false; @@ -455,7 +553,7 @@ static bool nmeaProcessGPRMC(GPSPositionData * GpsData, bool* gpsDataUpdated, ch } // get speed in knots - GpsData->Groundspeed = NMEA_real_to_float(param[7]) * 0.51444; // to m/s + GpsData->Groundspeed = NMEA_real_to_float(param[7]) * 0.51444f; // to m/s // get True course GpsData->Heading = NMEA_real_to_float(param[8]); @@ -489,10 +587,10 @@ static bool nmeaProcessGPVTG(GPSPositionData * GpsData, bool* gpsDataUpdated, ch DEBUG_MSG(" GroundSpeed=%s %s\n", param[5], param[6]); #endif - *gpsDataUpdated = true; + *gpsDataUpdated = false; GpsData->Heading = NMEA_real_to_float(param[1]); - GpsData->Groundspeed = NMEA_real_to_float(param[5]) * 0.51444; // to m/s + GpsData->Groundspeed = NMEA_real_to_float(param[5]) * 0.51444f; // to m/s return true; } @@ -555,7 +653,7 @@ static bool nmeaProcessGPGSV(GPSPositionData * GpsData, bool* gpsDataUpdated, ch uint8_t nbSentences = atoi(param[1]); uint8_t currSentence = atoi(param[2]); - *gpsDataUpdated = true; + *gpsDataUpdated = false; if (nbSentences < 1 || nbSentences > 8 || currSentence < 1 || currSentence > nbSentences) return false; @@ -639,7 +737,7 @@ static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, ch DEBUG_MSG(" VDOP=%s\n", param[17]); #endif - *gpsDataUpdated = true; + *gpsDataUpdated = false; switch (atoi(param[2])) { case 1: @@ -669,3 +767,4 @@ static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, ch return true; } +#endif // PIOS_INCLUDE_GPS_NMEA_PARSER diff --git a/flight/Modules/GPS/UBX.c b/flight/Modules/GPS/UBX.c new file mode 100644 index 000000000..92d5e08bf --- /dev/null +++ b/flight/Modules/GPS/UBX.c @@ -0,0 +1,341 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup GSPModule GPS Module + * @brief Process GPS information (UBX binary format) + * @{ + * + * @file UBX.c + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @brief GPS module, handles GPS and NMEA stream + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "openpilot.h" +#include "pios.h" + +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + +#include "UBX.h" +#include "GPS.h" + +// parse incoming character stream for messages in UBX binary format + +int parse_ubx_stream (uint8_t c, char *gps_rx_buffer, GPSPositionData *GpsData, struct GPS_RX_STATS *gpsRxStats) +{ + enum proto_states { + START, + UBX_SY2, + UBX_CLASS, + UBX_ID, + UBX_LEN1, + UBX_LEN2, + UBX_PAYLOAD, + UBX_CHK1, + UBX_CHK2, + FINISHED + }; + + static enum proto_states proto_state = START; + static uint8_t rx_count = 0; + struct UBXPacket *ubx = (struct UBXPacket *)gps_rx_buffer; + + switch (proto_state) { + case START: // detect protocol + if (c == UBX_SYNC1) // first UBX sync char found + proto_state = UBX_SY2; + break; + case UBX_SY2: + if (c == UBX_SYNC2) // second UBX sync char found + proto_state = UBX_CLASS; + else + proto_state = START; // reset state + break; + case UBX_CLASS: + ubx->header.class = c; + proto_state = UBX_ID; + break; + case UBX_ID: + ubx->header.id = c; + proto_state = UBX_LEN1; + break; + case UBX_LEN1: + ubx->header.len = c; + proto_state = UBX_LEN2; + break; + case UBX_LEN2: + ubx->header.len += (c << 8); + if (ubx->header.len > sizeof(UBXPayload)) { + gpsRxStats->gpsRxOverflow++; + proto_state = START; + } else { + rx_count = 0; + proto_state = UBX_PAYLOAD; + } + break; + case UBX_PAYLOAD: + if (rx_count < ubx->header.len) { + ubx->payload.payload[rx_count] = c; + if (++rx_count == ubx->header.len) + proto_state = UBX_CHK1; + } else { + gpsRxStats->gpsRxOverflow++; + proto_state = START; + } + break; + case UBX_CHK1: + ubx->header.ck_a = c; + proto_state = UBX_CHK2; + break; + case UBX_CHK2: + ubx->header.ck_b = c; + if (checksum_ubx_message(ubx)) { // message complete and valid + parse_ubx_message(ubx, GpsData); + proto_state = FINISHED; + } else { + gpsRxStats->gpsRxChkSumError++; + proto_state = START; + } + break; + default: break; + } + + if (proto_state == START) + return PARSER_ERROR; // parser couldn't use this byte + else if (proto_state == FINISHED) { + gpsRxStats->gpsRxReceived++; + proto_state = START; + return PARSER_COMPLETE; // message complete & processed + } + + return PARSER_INCOMPLETE; // message not (yet) complete +} + + +// Keep track of various GPS messages needed to make up a single UAVO update +// time-of-week timestamp is used to correlate matching messages + +#define POSLLH_RECEIVED (1 << 0) +#define STATUS_RECEIVED (1 << 1) +#define DOP_RECEIVED (1 << 2) +#define VELNED_RECEIVED (1 << 3) +#define SOL_RECEIVED (1 << 4) +#define ALL_RECEIVED (SOL_RECEIVED | VELNED_RECEIVED | DOP_RECEIVED | POSLLH_RECEIVED) +#define NONE_RECEIVED 0 + +static struct msgtracker{ + uint32_t currentTOW; // TOW of the message set currently in progress + uint8_t msg_received; // keep track of received message types + } msgtracker; + +// Check if a message belongs to the current data set and register it as 'received' +bool check_msgtracker (uint32_t tow, uint8_t msg_flag) +{ + + if (tow > msgtracker.currentTOW ? true // start of a new message set + : (msgtracker.currentTOW - tow > 6*24*3600*1000)) { // 6 days, TOW wrap around occured + msgtracker.currentTOW = tow; + msgtracker.msg_received = NONE_RECEIVED; + } else if (tow < msgtracker.currentTOW) // message outdated (don't process) + return false; + + msgtracker.msg_received |= msg_flag; // register reception of this msg type + return true; +} + +bool checksum_ubx_message (struct UBXPacket *ubx) +{ + int i; + uint8_t ck_a, ck_b; + + ck_a = ubx->header.class; + ck_b = ck_a; + + ck_a += ubx->header.id; + ck_b += ck_a; + + ck_a += ubx->header.len & 0xff; + ck_b += ck_a; + + ck_a += ubx->header.len >> 8; + ck_b += ck_a; + + for (i = 0; i < ubx->header.len; i++) { + ck_a += ubx->payload.payload[i]; + ck_b += ck_a; + } + + if (ubx->header.ck_a == ck_a && + ubx->header.ck_b == ck_b) + return true; + else + return false; + +} + +void parse_ubx_nav_posllh (struct UBX_NAV_POSLLH *posllh, GPSPositionData *GpsPosition) +{ + if (check_msgtracker(posllh->iTOW, POSLLH_RECEIVED)) { + if (GpsPosition->Status != GPSPOSITION_STATUS_NOFIX) { + GpsPosition->Altitude = (float)posllh->hMSL*0.001f; + GpsPosition->GeoidSeparation = (float)(posllh->height - posllh->hMSL)*0.001f; + GpsPosition->Latitude = posllh->lat; + GpsPosition->Longitude = posllh->lon; + } + } +} + +void parse_ubx_nav_sol (struct UBX_NAV_SOL *sol, GPSPositionData *GpsPosition) +{ + if (check_msgtracker(sol->iTOW, SOL_RECEIVED)) { + GpsPosition->Satellites = sol->numSV; + + if (sol->flags & STATUS_FLAGS_GPSFIX_OK) { + switch (sol->gpsFix) { + case STATUS_GPSFIX_2DFIX: + GpsPosition->Status = GPSPOSITION_STATUS_FIX2D; + break; + case STATUS_GPSFIX_3DFIX: + GpsPosition->Status = GPSPOSITION_STATUS_FIX3D; + break; + default: GpsPosition->Status = GPSPOSITION_STATUS_NOFIX; + } + } + else // fix is not valid so we make sure to treat is as NOFIX + GpsPosition->Status = GPSPOSITION_STATUS_NOFIX; + } +} + +void parse_ubx_nav_dop (struct UBX_NAV_DOP *dop, GPSPositionData *GpsPosition) +{ + if (check_msgtracker(dop->iTOW, DOP_RECEIVED)) { + GpsPosition->HDOP = (float)dop->hDOP * 0.01f; + GpsPosition->VDOP = (float)dop->vDOP * 0.01f; + GpsPosition->PDOP = (float)dop->pDOP * 0.01f; + } +} + +void parse_ubx_nav_velned (struct UBX_NAV_VELNED *velned, GPSPositionData *GpsPosition) +{ + GPSVelocityData GpsVelocity; + + if (check_msgtracker(velned->iTOW, VELNED_RECEIVED)) { + if (GpsPosition->Status != GPSPOSITION_STATUS_NOFIX) { + GpsVelocity.North = (float)velned->velN/100.0f; + GpsVelocity.East = (float)velned->velE/100.0f; + GpsVelocity.Down = (float)velned->velD/100.0f; + GPSVelocitySet(&GpsVelocity); + GpsPosition->Groundspeed = (float)velned->gSpeed * 0.01f; + GpsPosition->Heading = (float)velned->heading * 1.0e-5f; + } + } +} + +#if !defined(PIOS_GPS_MINIMAL) +void parse_ubx_nav_timeutc (struct UBX_NAV_TIMEUTC *timeutc) +{ + if (!(timeutc->valid & TIMEUTC_VALIDUTC)) + return; + + GPSTimeData GpsTime; + + GpsTime.Year = timeutc->year; + GpsTime.Month = timeutc->month; + GpsTime.Day = timeutc->day; + GpsTime.Hour = timeutc->hour; + GpsTime.Minute = timeutc->min; + GpsTime.Second = timeutc->sec; + + GPSTimeSet(&GpsTime); +} +#endif + +#if !defined(PIOS_GPS_MINIMAL) +void parse_ubx_nav_svinfo (struct UBX_NAV_SVINFO *svinfo) +{ + uint8_t chan; + GPSSatellitesData svdata; + + svdata.SatsInView = 0; + for (chan = 0; chan < svinfo->numCh; chan++) { + if (svdata.SatsInView < GPSSATELLITES_PRN_NUMELEM) { + svdata.Azimuth[svdata.SatsInView] = (float)svinfo->sv[chan].azim; + svdata.Elevation[svdata.SatsInView] = (float)svinfo->sv[chan].elev; + svdata.PRN[svdata.SatsInView] = svinfo->sv[chan].svid; + svdata.SNR[svdata.SatsInView] = svinfo->sv[chan].cno; + svdata.SatsInView++; + } + + } + // fill remaining slots (if any) + for (chan = svdata.SatsInView; chan < GPSSATELLITES_PRN_NUMELEM; chan++) { + svdata.Azimuth[chan] = (float)0.0f; + svdata.Elevation[chan] = (float)0.0f; + svdata.PRN[chan] = 0; + svdata.SNR[chan] = 0; + } + + GPSSatellitesSet(&svdata); +} +#endif + +// UBX message parser +// returns UAVObjectID if a UAVObject structure is ready for further processing + +uint32_t parse_ubx_message (struct UBXPacket *ubx, GPSPositionData *GpsPosition) +{ + uint32_t id = 0; + + switch (ubx->header.class) { + case UBX_CLASS_NAV: + switch (ubx->header.id) { + case UBX_ID_POSLLH: + parse_ubx_nav_posllh (&ubx->payload.nav_posllh, GpsPosition); + break; + case UBX_ID_DOP: + parse_ubx_nav_dop (&ubx->payload.nav_dop, GpsPosition); + break; + case UBX_ID_SOL: + parse_ubx_nav_sol (&ubx->payload.nav_sol, GpsPosition); + break; + case UBX_ID_VELNED: + parse_ubx_nav_velned (&ubx->payload.nav_velned, GpsPosition); + break; +#if !defined(PIOS_GPS_MINIMAL) + case UBX_ID_TIMEUTC: + parse_ubx_nav_timeutc (&ubx->payload.nav_timeutc); + break; + case UBX_ID_SVINFO: + parse_ubx_nav_svinfo (&ubx->payload.nav_svinfo); + break; +#endif + } + break; + } + if (msgtracker.msg_received == ALL_RECEIVED) { + GPSPositionSet(GpsPosition); + msgtracker.msg_received = NONE_RECEIVED; + id = GPSPOSITION_OBJID; + } + return id; +} + +#endif // PIOS_INCLUDE_GPS_UBX_PARSER + diff --git a/flight/Modules/GPS/inc/GPS.h b/flight/Modules/GPS/inc/GPS.h index 86a92d285..6e243c21f 100644 --- a/flight/Modules/GPS/inc/GPS.h +++ b/flight/Modules/GPS/inc/GPS.h @@ -34,6 +34,24 @@ #ifndef GPS_H #define GPS_H +#include "gpsvelocity.h" +#include "gpssatellites.h" +#include "gpsposition.h" +#include "gpstime.h" + +#define NO_PARSER -3 // no parser available +#define PARSER_OVERRUN -2 // message buffer overrun before completing the message +#define PARSER_ERROR -1 // message unparsable by this parser +#define PARSER_INCOMPLETE 0 // parser needs more data to complete the message +#define PARSER_COMPLETE 1 // parser has received a complete message and finished processing + +struct GPS_RX_STATS { + uint16_t gpsRxReceived; + uint16_t gpsRxChkSumError; + uint16_t gpsRxOverflow; + uint16_t gpsRxParserError; +}; + int32_t GPSInitialize(void); #endif // GPS_H diff --git a/flight/Modules/GPS/inc/NMEA.h b/flight/Modules/GPS/inc/NMEA.h index 6ff6b1195..49213e716 100644 --- a/flight/Modules/GPS/inc/NMEA.h +++ b/flight/Modules/GPS/inc/NMEA.h @@ -33,8 +33,12 @@ #include #include +#include "GPS.h" -extern bool NMEA_update_position(char *nmea_sentence); +#define NMEA_MAX_PACKET_LENGTH 96 // 82 max NMEA msg size plus 12 margin (because some vendors add custom crap) plus CR plus Linefeed + +extern bool NMEA_update_position(char *nmea_sentence, GPSPositionData *GpsData); extern bool NMEA_checksum(char *nmea_sentence); +extern int parse_nmea_stream(uint8_t, char *, GPSPositionData *, struct GPS_RX_STATS *); #endif /* NMEA_H */ diff --git a/flight/Modules/GPS/inc/UBX.h b/flight/Modules/GPS/inc/UBX.h new file mode 100644 index 000000000..dc27fa798 --- /dev/null +++ b/flight/Modules/GPS/inc/UBX.h @@ -0,0 +1,224 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup GSPModule GPS Module + * @brief Process GPS information + * @{ + * + * @file UBX.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief GPS module, handles GPS and NMEA stream + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UBX_H +#define UBX_H +#include "openpilot.h" +#include "gpsposition.h" +#include "GPS.h" + + +#define UBX_SYNC1 0xb5 // UBX protocol synchronization characters +#define UBX_SYNC2 0x62 + +// From u-blox6 receiver protocol specification + +// Messages classes +#define UBX_CLASS_NAV 0x01 + +// Message IDs +#define UBX_ID_POSLLH 0x02 +#define UBX_ID_STATUS 0x03 +#define UBX_ID_DOP 0x04 +#define UBX_ID_SOL 0x06 +#define UBX_ID_VELNED 0x12 +#define UBX_ID_TIMEUTC 0x21 +#define UBX_ID_SVINFO 0x30 + +// private structures + +// Geodetic Position Solution +struct UBX_NAV_POSLLH { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + int32_t lon; // Longitude (deg*1e-7) + int32_t lat; // Latitude (deg*1e-7) + int32_t height; // Height above Ellipsoid (mm) + int32_t hMSL; // Height above mean sea level (mm) + uint32_t hAcc; // Horizontal Accuracy Estimate (mm) + uint32_t vAcc; // Vertical Accuracy Estimate (mm) +}; + +// Receiver Navigation Status + +#define STATUS_GPSFIX_NOFIX 0x00 +#define STATUS_GPSFIX_DRONLY 0x01 +#define STATUS_GPSFIX_2DFIX 0x02 +#define STATUS_GPSFIX_3DFIX 0x03 +#define STATUS_GPSFIX_GPSDR 0x04 +#define STATUS_GPSFIX_TIMEONLY 0x05 + +#define STATUS_FLAGS_GPSFIX_OK (1 << 0) +#define STATUS_FLAGS_DIFFSOLN (1 << 1) +#define STATUS_FLAGS_WKNSET (1 << 2) +#define STATUS_FLAGS_TOWSET (1 << 3) + +struct UBX_NAV_STATUS { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + uint8_t gpsFix; // GPS fix type + uint8_t flags; // Navigation Status Flags + uint8_t fixStat; // Fix Status Information + uint8_t flags2; // Additional navigation output information + uint32_t ttff; // Time to first fix (ms) + uint32_t msss; // Milliseconds since startup/reset (ms) +}; + +// Dilution of precision +struct UBX_NAV_DOP { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + uint16_t gDOP; // Geometric DOP + uint16_t pDOP; // Position DOP + uint16_t tDOP; // Time DOP + uint16_t vDOP; // Vertical DOP + uint16_t hDOP; // Horizontal DOP + uint16_t nDOP; // Northing DOP + uint16_t eDOP; // Easting DOP +}; + +// Navigation solution + +struct UBX_NAV_SOL { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + int32_t fTOW; // fractional nanoseconds (ns) + int16_t week; // GPS week + uint8_t gpsFix; // GPS fix type + uint8_t flags; // Fix status flags + int32_t ecefX; // ECEF X coordinate (cm) + int32_t ecefY; // ECEF Y coordinate (cm) + int32_t ecefZ; // ECEF Z coordinate (cm) + uint32_t pAcc; // 3D Position Accuracy Estimate (cm) + int32_t ecefVX; // ECEF X coordinate (cm/s) + int32_t ecefVY; // ECEF Y coordinate (cm/s) + int32_t ecefVZ; // ECEF Z coordinate (cm/s) + uint32_t sAcc; // Speed Accuracy Estimate + uint16_t pDOP; // Position DOP + uint8_t reserved1; // Reserved + uint8_t numSV; // Number of SVs used in Nav Solution + uint32_t reserved2; // Reserved +}; + +// North/East/Down velocity + +struct UBX_NAV_VELNED { + uint32_t iTOW; // ms GPS Millisecond Time of Week + int32_t velN; // cm/s NED north velocity + int32_t velE; // cm/s NED east velocity + int32_t velD; // cm/s NED down velocity + uint32_t speed; // cm/s Speed (3-D) + uint32_t gSpeed; // cm/s Ground Speed (2-D) + int32_t heading; // 1e-5 *deg Heading of motion 2-D + uint32_t sAcc; // cm/s Speed Accuracy Estimate + uint32_t cAcc; // 1e-5 *deg Course / Heading Accuracy Estimate +}; + +// UTC Time Solution + +#define TIMEUTC_VALIDTOW (1 << 0) +#define TIMEUTC_VALIDWKN (1 << 1) +#define TIMEUTC_VALIDUTC (1 << 2) + +struct UBX_NAV_TIMEUTC { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + uint32_t tAcc; // Time Accuracy Estimate (ns) + int32_t nano; // Nanoseconds of second + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t valid; // Validity Flags +}; + +// Space Vehicle (SV) Information + +// Single SV information block + +#define SVUSED (1 << 0) // This SV is used for navigation +#define DIFFCORR (1 << 1) // Differential correction available +#define ORBITAVAIL (1 << 2) // Orbit information available +#define ORBITEPH (1 << 3) // Orbit information is Ephemeris +#define UNHEALTHY (1 << 4) // SV is unhealthy +#define ORBITALM (1 << 5) // Orbit information is Almanac Plus +#define ORBITAOP (1 << 6) // Orbit information is AssistNow Autonomous +#define SMOOTHED (1 << 7) // Carrier smoothed pseudoranges used + +struct UBX_NAV_SVINFO_SV { + uint8_t chn; // Channel number + uint8_t svid; // Satellite ID + uint8_t flags; // Misc SV information + uint8_t quality; // Misc quality indicators + uint8_t cno; // Carrier to Noise Ratio (dbHz) + int8_t elev; // Elevation (integer degrees) + int16_t azim; // Azimuth (integer degrees) + int32_t prRes; // Pseudo range residual (cm) +}; + +// SV information message +#define MAX_SVS 16 + +struct UBX_NAV_SVINFO { + uint32_t iTOW; // GPS Millisecond Time of Week (ms) + uint8_t numCh; // Number of channels + uint8_t globalFlags; // + uint16_t reserved2; // Reserved + struct UBX_NAV_SVINFO_SV sv[MAX_SVS]; // Repeated 'numCh' times +}; + +typedef union { + uint8_t payload[0]; + struct UBX_NAV_POSLLH nav_posllh; + struct UBX_NAV_STATUS nav_status; + struct UBX_NAV_DOP nav_dop; + struct UBX_NAV_SOL nav_sol; + struct UBX_NAV_VELNED nav_velned; +#if !defined(PIOS_GPS_MINIMAL) + struct UBX_NAV_TIMEUTC nav_timeutc; + struct UBX_NAV_SVINFO nav_svinfo; +#endif +} UBXPayload; + +struct UBXHeader { + uint8_t class; + uint8_t id; + uint16_t len; + uint8_t ck_a; + uint8_t ck_b; +}; + +struct UBXPacket { + struct UBXHeader header; + UBXPayload payload; +}; + +bool checksum_ubx_message(struct UBXPacket *); +uint32_t parse_ubx_message(struct UBXPacket *, GPSPositionData *); +int parse_ubx_stream(uint8_t, char *, GPSPositionData *, struct GPS_RX_STATS *); + +#endif /* UBX_H */ diff --git a/flight/Revolution/System/inc/pios_config.h b/flight/Revolution/System/inc/pios_config.h index 3043ea630..5b249bfe5 100644 --- a/flight/Revolution/System/inc/pios_config.h +++ b/flight/Revolution/System/inc/pios_config.h @@ -95,7 +95,9 @@ #define PIOS_INCLUDE_INITCALL /* Include init call structures */ #define PIOS_TELEM_PRIORITY_QUEUE /* Enable a priority queue in telemetry */ #define PIOS_QUATERNION_STABILIZATION /* Stabilization options */ -//#define PIOS_GPS_SETS_HOMELOCATION /* GPS options */ +#define PIOS_GPS_SETS_HOMELOCATION /* GPS options */ +#define PIOS_INCLUDE_GPS_NMEA_PARSER /* Include the NMEA protocol parser */ +#define PIOS_INCLUDE_GPS_UBX_PARSER /* Include the UBX protocol parser */ /* Alarm Thresholds */ #define HEAP_LIMIT_WARNING 4000 diff --git a/flight/Revolution/UAVObjects.inc b/flight/Revolution/UAVObjects.inc index d91eb9c17..462acfc34 100644 --- a/flight/Revolution/UAVObjects.inc +++ b/flight/Revolution/UAVObjects.inc @@ -46,7 +46,9 @@ UAVOBJSRCFILENAMES += flighttelemetrystats UAVOBJSRCFILENAMES += gcstelemetrystats UAVOBJSRCFILENAMES += gpsposition UAVOBJSRCFILENAMES += gpssatellites +UAVOBJSRCFILENAMES += gpssettings UAVOBJSRCFILENAMES += gpstime +UAVOBJSRCFILENAMES += gpsvelocity UAVOBJSRCFILENAMES += guidancesettings UAVOBJSRCFILENAMES += homelocation UAVOBJSRCFILENAMES += i2cstats diff --git a/flight/SimPosix/UAVObjects.inc b/flight/SimPosix/UAVObjects.inc index d91eb9c17..8953c7462 100644 --- a/flight/SimPosix/UAVObjects.inc +++ b/flight/SimPosix/UAVObjects.inc @@ -47,6 +47,8 @@ UAVOBJSRCFILENAMES += gcstelemetrystats UAVOBJSRCFILENAMES += gpsposition UAVOBJSRCFILENAMES += gpssatellites UAVOBJSRCFILENAMES += gpstime +UAVOBJSRCFILENAMES += gpssettings +UAVOBJSRCFILENAMES += gpsvelocity UAVOBJSRCFILENAMES += guidancesettings UAVOBJSRCFILENAMES += homelocation UAVOBJSRCFILENAMES += i2cstats diff --git a/ground/openpilotgcs/copydata.pro b/ground/openpilotgcs/copydata.pro index 7e1d5b1b5..d31730d80 100644 --- a/ground/openpilotgcs/copydata.pro +++ b/ground/openpilotgcs/copydata.pro @@ -9,9 +9,7 @@ equals(copydata, 1) { win32:CONFIG(release, debug|release) { # copy Qt DLLs and phonon4 - QT_DLLS = libgcc_s_dw2-1.dll \ - mingwm10.dll \ - phonon4.dll \ + QT_DLLS = phonon4.dll \ QtCore4.dll \ QtGui4.dll \ QtNetwork4.dll \ @@ -27,6 +25,13 @@ equals(copydata, 1) { data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline() } + # copy MinGW DLLs + MINGW_DLLS = libgcc_s_dw2-1.dll \ + mingwm10.dll + for(dll, MINGW_DLLS) { + data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../../../../mingw/bin/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline() + } + # copy iconengines QT_ICONENGINE_DLLS = qsvgicon4.dll data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/iconengines\") $$addNewline() diff --git a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp index d6bddb291..e70f2ed72 100644 --- a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp +++ b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp @@ -123,7 +123,7 @@ void GpsConstellationWidget::updateSat(int index, int prn, int elevation, int az satellites[index][2] = azimuth; satellites[index][3] = snr; - if (prn) { + if (prn && elevation >= 0) { QPointF opd = polarToCoord(elevation,azimuth); opd += QPointF(-satIcons[index]->boundingRect().center().x(), -satIcons[index]->boundingRect().center().y()); diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp index 51daf2460..f8306e30d 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp @@ -1,3 +1,30 @@ +/** + ****************************************************************************** + * + * @file aerosimrc.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup HITLPlugin HITLv2 Plugin + * @{ + * @brief The Hardware In The Loop plugin version 2 + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #include "aerosimrc.h" #include #include diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h index 19dae3bce..42b7d4aa5 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h @@ -1,3 +1,30 @@ +/** + ****************************************************************************** + * + * @file aerosimrc.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup HITLPlugin HITLv2 Plugin + * @{ + * @brief The Hardware In The Loop plugin version 2 + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifndef AEROSIMRC_H #define AEROSIMRC_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/aerosimrc.pro b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/aerosimrc.pro new file mode 100644 index 000000000..74df87185 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/aerosimrc.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs + +win32 { + SUBDIRS += plugin +} + +SUBDIRS += udptest + +plugin.file = src/plugin.pro +udptest.file = src/udptest.pro diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/aerosimrcdatastruct.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/aerosimrcdatastruct.h new file mode 100644 index 000000000..697695bc2 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/aerosimrcdatastruct.h @@ -0,0 +1,206 @@ +/** + ****************************************************************************** + * + * @file aerosimrcdatastruct.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef AEROSIMRCDATASTRUCT_H +#define AEROSIMRCDATASTRUCT_H + +#include + +const quint8 AEROSIMRC_MAX_CHANNELS = 39; +const quint16 DBG_BUFFER_MAX_SIZE = 4096; + +#define MAX_DLL_USER_MENU_ITEMS 16 +#define OBSOLETE_MIT_COMMAND (1 << 0) +#define OBSOLETE_MIT_CHECKBOX (1 << 1) +#define OBSOLETE_MIT_SEPARATOR (1 << 7) + +#define PACK_STRUCT __attribute__((packed)) + +struct simToPlugin +{ + quint16 structSize; + float simTimeStep; + float chSimTX[AEROSIMRC_MAX_CHANNELS]; + float chSimRX[AEROSIMRC_MAX_CHANNELS]; + uchar *OSDVideoBuf; + quint32 simMenuStatus; + float initPosX; + float initPosY; + float initPosZ; + float initHeading; + float initPitch; + float initRoll; + float wpHomeX; + float wpHomeY; + float wpHomeLat; + float wpHomeLong; + const char *wpHomeDesc; // (m, deg, string) + float wpAX; + float wpAY; + float wpALat; + float wpALong; + const char *wpADesc; // (m, deg, string) + float wpBX; + float wpBY; + float wpBLat; + float wpBLong; + const char *wpBDesc; // (m, deg, string) + float wpCX; + float wpCY; + float wpCLat; + float wpCLong; + const char *wpCDesc; // (m, deg, string) + float wpDX; + float wpDY; + float wpDLat; + float wpDLong; + const char *wpDDesc; // (m, deg, string) + float posX; + float posY; + float posZ; + float velX; + float velY; + float velZ; + float angVelX; + float angVelY; + float angVelZ; + float accelX; + float accelY; + float accelZ; + qreal latitude; + qreal longitude; + float AGL; + float heading; + float pitch; + float roll; + float windVelX; + float windVelY; + float windVelZ; + float eng1RPM; + float eng2RPM; + float eng3RPM; + float eng4RPM; + float voltage; // V + float current; // A + float consumedCharge; // Ah + float capacity; // Ah + float fuelConsumed; // l + float fuelTankCapacity; // l + // ver 3.83 + qint16 screenW; + qint16 screenH; + // Model Orientation Matrix (X=Right, Y=Front, Z=Up) + float axisXx; + float axisXy; + float axisXz; + float axisYx; + float axisYy; + float axisYz; + float axisZx; + float axisZy; + float axisZz; + // Model data in body frame coordinates (X=Right, Y=Front, Z=Up) + float velXm; // m/s Model velocity in body coordinates + float velYm; + float velZm; + float angVelXm; // rad/s Model angular velocity in body coordinates + float angVelYm; + float angVelZm; + float accelXm; // m/s/s Model acceleration in body coordinates + float accelYm; + float accelZm; + // ver 3.90 + quint32 OSDVideoBufSize; +} PACK_STRUCT ; // normal - 592, packed - 582 OK (3.81) + // normal - ???, packed - 658 OK (3.83) + // normal - ???, packed - 662 OK (3.90) + +struct pluginToSim +{ + quint16 structSize; + const char *dbgInfoText; + uchar chOverTX[AEROSIMRC_MAX_CHANNELS]; + float chNewTX[AEROSIMRC_MAX_CHANNELS]; + uchar chOverRX[AEROSIMRC_MAX_CHANNELS]; + float chNewRX[AEROSIMRC_MAX_CHANNELS]; + float newPosX; // m + float newPosY; + float newPosZ; + float newVelX; // m/s + float newVelY; + float newVelZ; + float newAngVelX; // rad/s + float newAngVelY; + float newAngVelZ; + float newHeading; // rad + float newPitch; + float newRoll; + quint32 modelOverrideFlags; + quint32 newMenuStatus; + quint8 isOSDShow; + quint8 isOSDChanged; + quint16 OSDWindow_DX; + quint16 OSDWindow_DY; + float OSDScale; + float newWindVelX; + float newWindVelY; + float newWindVelZ; + float newEng1RPM; + float newEng2RPM; + float newEng3RPM; + float newEng4RPM; + float newVoltage; + float newCurrent; + float newConsumedCharge; + float newFuelConsumed; + quint8 modelCrashInhibit; + // ver 3.83 + qint16 newScreenW; // Simulator window position and size on screen + qint16 newScreenH; + qint16 newScreenX; + qint16 newScreenY; +} PACK_STRUCT ; // normal 516, packed 507 OK (3.81) + // normal ???, packed 515 OK (3.83 & 3.90) + +struct TPluginMenuItem +{ + quint32 OBSOLETE_eType; + char *OBSOLETE_strName; +} PACK_STRUCT ; + +struct pluginInit +{ + quint32 nStructSize; + char *OBSOLETE_strMenuTitle; + TPluginMenuItem OBSOLETE_atMenuItem[MAX_DLL_USER_MENU_ITEMS]; + const char *strPluginFolder; + const char *strOutputFolder; +} PACK_STRUCT ; // normal - 144, packed - 144 OK (3.81 & 3.83 & 3.90) + +#undef PACK_STRUCT + +#endif // AEROSIMRCDATASTRUCT_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/enums.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/enums.h new file mode 100644 index 000000000..31abb1e0a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/enums.h @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * + * @file enums.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ENUMS_H +#define ENUMS_H + +// Custom Menu Item masks +enum MenuMasks { + MenuEnable = (1 << 0), + MenuTx = (1 << 1), + MenuRx = (1 << 2), + MenuScreen = (1 << 3), + MenuNextWpt = (1 << 4), + MenuCmdReset = (1 << 5), + MenuLedBlue = (1 << 6), + MenuLedGreen = (1 << 7), + MenuFMode1 = (1 << 8), + MenuFMode2 = (1 << 9), + MenuFMode3 = (1 << 10) +}; + +enum EOverrideFlags +{ + OVR_POS = (1 << 0), + OVR_VEL = (1 << 1), + OVR_ANG_VEL = (1 << 2), + OVR_HPR = (1 << 3), // Override Heading, Pitch and Roll + OVR_WIND_VEL = (1 << 4), // Override Wind velocity at model + OVR_ENGINE_RPM = (1 << 5), // Override RPM of all Engines or Motors + OVR_BAT_VOLT = (1 << 6), // Override motor Battery Voltage + OVR_BAT_AMP = (1 << 7), // Override motor Battery current + OVR_BAT_AH_CONSUMED = (1 << 8), // Override motor Battery AmpsHour consumed + OVR_FUEL_CONSUMED = (1 << 9) // Override Fuel consumed (gas & jet engines) +}; + +enum Channels { + Ch1Aileron, + Ch2Elevator, + Ch3Throttle, + Ch4Rudder, + Ch5, + Ch6, + Ch7, + Ch8, + Ch9, + Ch10Retracts, + Ch11Flaps, + Ch12FPVCamPan, + Ch13FPVCamTilt, + Ch14Brakes, + Ch15Spoilers, + Ch16Smoke, + Ch17Fire, + Ch18FlightMode, + Ch19ALTHold, + Ch20FPVTiltHold, + Ch21ResetModel, + Ch22MouseTX, + Ch23Plugin1, + Ch24Plugin2, + Ch25ThrottleHold, + Ch26CareFree, + Ch27FPVCamRoll, + Ch28LMotorDual, + Ch29RMotorDual, + Ch30Mix, + Ch31Mix, + Ch32Mix, + Ch33Mix, + Ch34Mix, + Ch35Mix, + Ch36Mix, + Ch37Mix, + Ch38Mix, + Ch39Mix +}; + +#endif // ENUMS_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.cpp new file mode 100644 index 000000000..18ba2c15d --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.cpp @@ -0,0 +1,394 @@ +/** + ****************************************************************************** + * + * @file plugin.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "plugin.h" +#include "udpconnect.h" +#include "qdebughandler.h" +#include "enums.h" +#include "settings.h" + +bool isFirstRun = true; +QString debugInfo(DBG_BUFFER_MAX_SIZE, ' '); +QString pluginFolder(MAX_PATH, ' '); +QString outputFolder(MAX_PATH, ' '); + +QList videoModes; +QTime ledTimer; + +UdpSender *sndr; +UdpReceiver *rcvr; + +const float RAD2DEG = (float)(180.0 / M_PI); +const float DEG2RAD = (float)(M_PI / 180.0); + +//extern "C" int __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +extern "C" int __stdcall DllMain(void*, quint32 fdwReason, void*) +{ + switch (fdwReason) { + case 0: +// qDebug() << hinstDLL << "DLL_PROCESS_DETACH " << lpvReserved; +// free resources here + rcvr->stop(); + rcvr->wait(500); + delete rcvr; + delete sndr; + qDebug("------"); + break; + case 1: +// qDebug() << hinstDLL << " DLL_PROCESS_ATTACH " << lpvReserved; + break; + case 2: +// qDebug() << hinstDLL << "DLL_THREAD_ATTACH " << lpvReserved; + break; + case 3: +// qDebug() << hinstDLL << "DLL_THREAD_DETACH " << lpvReserved; + break; + } + return true; +} + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_ReportStructSizes(quint32 *sizeSimToPlugin, + quint32 *sizePluginToSim, + quint32 *sizePluginInit) +{ + // debug redirection + qInstallMsgHandler(myQDebugHandler); + + qDebug() << "AeroSIMRC_Plugin_ReportStructSizes"; + *sizeSimToPlugin = sizeof(simToPlugin); + *sizePluginToSim = sizeof(pluginToSim); + *sizePluginInit = sizeof(pluginInit); + qDebug() << "sizeSimToPlugin = " << *sizeSimToPlugin; + qDebug() << "sizePluginToSim = " << *sizePluginToSim; + qDebug() << "sizePluginInit = " << *sizePluginInit; +} + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_Init(pluginInit *p) +{ + qDebug() << "AeroSIMRC_Plugin_Init begin"; + + pluginFolder = p->strPluginFolder; + outputFolder = p->strOutputFolder; + + ledTimer.restart(); + + Settings *ini = new Settings(pluginFolder); + ini->read(); + + videoModes = ini->getVideoModes(); + + sndr = new UdpSender(ini->getOutputMap(), ini->isFromTX()); + sndr->init(ini->remoteHost(), ini->remotePort()); + + rcvr = new UdpReceiver(ini->getInputMap(), ini->isToRX()); + rcvr->init(ini->localHost(), ini->localPort()); + + // run thread + rcvr->start(); + + delete ini; + + qDebug() << "AeroSIMRC_Plugin_Init done"; +} + +//----------------------------------------------------------------------------- + +void Run_Command_Reset(/*const simToPlugin *stp, + pluginToSim *pts*/) +{ + // Print some debug info, although it will only be seen during one frame + debugInfo.append("\nRESET"); +} + +void Run_Command_WindowSizeAndPos(const simToPlugin *stp, + pluginToSim *pts) +{ + static quint8 snSequence = 0; + quint8 idx = snSequence * 4; + + if (snSequence >= videoModes.at(0)) { // set fullscreen + pts->newScreenX = 0; + pts->newScreenY = 0; + pts->newScreenW = stp->screenW; + pts->newScreenH = stp->screenH; + snSequence = 0; + } else { // set video mode from config + pts->newScreenX = videoModes.at(idx + 1); + pts->newScreenY = videoModes.at(idx + 2); + pts->newScreenW = videoModes.at(idx + 3); + pts->newScreenH = videoModes.at(idx + 4); + snSequence++; + } +} + +void Run_Command_MoveToNextWaypoint(const simToPlugin *stp, + pluginToSim *pts) +{ + static quint8 snSequence = 0; + + switch(snSequence) { + case 0: + pts->newPosX = stp->wpAX; + pts->newPosY = stp->wpAY; + pts->newPosZ = 100.0; + break; + case 1: + pts->newPosX = stp->wpBX; + pts->newPosY = stp->wpBY; + pts->newPosZ = 100.0; + break; + case 2: + pts->newPosX = stp->wpCX; + pts->newPosY = stp->wpCY; + pts->newPosZ = 100.0; + break; + case 3: + pts->newPosX = stp->wpDX; + pts->newPosY = stp->wpDY; + pts->newPosZ = 100.0; + break; + case 4: + pts->newPosX = stp->wpHomeX; + pts->newPosY = stp->wpHomeY; + pts->newPosZ = 100.0; + break; + default: + qFatal("Run_Command_MoveToNextWaypoint switch error"); + } + pts->modelOverrideFlags = 0; + pts->modelOverrideFlags |= OVR_POS; + + snSequence++; + if(snSequence > 4) + snSequence = 0; +} + +void Run_BlinkLEDs(const simToPlugin *stp, + pluginToSim *pts) +{ + if ((stp->simMenuStatus & MenuEnable) != 0) { + pts->newMenuStatus |= MenuLedGreen; + int timeout; + quint8 armed; + quint8 mode; + rcvr->getFlighStatus(armed, mode); + debugInfo.append(QString("armed: %1, mode: %2\n").arg(armed).arg(mode)); + + if (armed == 0) // disarm + timeout = 1000; + else if (armed == 1) // arming + timeout = 40; + else if (armed == 2) // armed + timeout = 100; + else // unknown + timeout = 2000; + if (ledTimer.elapsed() > timeout) { + ledTimer.restart(); + pts->newMenuStatus ^= MenuLedBlue; + } + + if (mode == 6) { + pts->newMenuStatus |= MenuFMode3; + pts->newMenuStatus |= MenuFMode2; + pts->newMenuStatus |= MenuFMode1; + } else if (mode == 5) { + pts->newMenuStatus |= MenuFMode3; + pts->newMenuStatus |= MenuFMode2; + pts->newMenuStatus &= ~MenuFMode1; + } else if (mode == 4) { + pts->newMenuStatus |= MenuFMode3; + pts->newMenuStatus &= ~MenuFMode2; + pts->newMenuStatus |= MenuFMode1; + } else if (mode == 3) { + pts->newMenuStatus |= MenuFMode3; + pts->newMenuStatus &= ~MenuFMode2; + pts->newMenuStatus &= ~MenuFMode1; + } else if (mode == 2) { + pts->newMenuStatus &= ~MenuFMode3; + pts->newMenuStatus |= MenuFMode2; + pts->newMenuStatus &= ~MenuFMode1; + } else if (mode == 1) { + pts->newMenuStatus &= ~MenuFMode3; + pts->newMenuStatus &= ~MenuFMode2; + pts->newMenuStatus |= MenuFMode1; + } else /*(mode == 0)*/ { + pts->newMenuStatus &= ~MenuFMode3; + pts->newMenuStatus &= ~MenuFMode2; + pts->newMenuStatus &= ~MenuFMode1; + } + } else { + pts->newMenuStatus = 0; + } +} + +void InfoText(const simToPlugin *stp, + pluginToSim *pts) +{ + debugInfo.append( + QString( + "Plugin Folder = %1\n" + "Output Folder = %2\n" + "nStructSize = %3 " + "fIntegrationTimeStep = %4\n" + "\n" + "Aileron TX = %5 RX = %6 RCMD TX = %7 RX = %8\n" + "Elevator TX = %9 RX = %10 RCMD TX = %11 RX = %12\n" + "Throttle TX = %13 RX = %14 RCMD TX = %15 RX = %16\n" + "Rudder TX = %17 RX = %18 RCMD TX = %19 RX = %20\n" + "Channel5 TX = %21 RX = %22 RCMD TX = %23 RX = %24\n" + "Channel6 TX = %25 RX = %26 RCMD TX = %27 RX = %28\n" + "Channel7 TX = %29 RX = %30 RCMD TX = %31 RX = %32\n" + "PluginCh1 TX = %33 RX = %34 RCMD TX = %35 RX = %36\n" + "PluginCh2 TX = %37 RX = %38 RCMD TX = %39 RX = %40\n" + "FPVCamPan TX = %41 RX = %42 RCMD TX = %43 RX = %44\n" + "FPVCamTil TX = %45 RX = %46 RCMD TX = %47 RX = %48\n" + "\n" + "MenuItems = %49\n" + // Model data + "\n" + "fPosX,Y,Z = (%50, %51, %52)\n" + "fVelX,Y,Z = (%53, %54, %55)\n" + "fAngVelX,Y,Z = (%56, %57, %58)\n" + "fAccelX,Y,Z = (%59, %60, %61)\n" + "\n" + "Lat, Long = %62, %63\n" + "fHeightAboveTerrain = %64\n" + "\n" + "fHeading = %65 fPitch = %66 fRoll = %67\n" + ) + .arg(pluginFolder) + .arg(outputFolder) + .arg(stp->structSize) + .arg(1.0 / stp->simTimeStep, 4, 'f', 1) + .arg(stp->chSimTX[Ch1Aileron], 5, 'f', 2) + .arg(stp->chSimRX[Ch1Aileron], 5, 'f', 2) + .arg(pts->chNewTX[Ch1Aileron], 5, 'f', 2) + .arg(pts->chNewRX[Ch1Aileron], 5, 'f', 2) + .arg(stp->chSimTX[Ch2Elevator], 5, 'f', 2) + .arg(stp->chSimRX[Ch2Elevator], 5, 'f', 2) + .arg(pts->chNewTX[Ch2Elevator], 5, 'f', 2) + .arg(pts->chNewRX[Ch2Elevator], 5, 'f', 2) + .arg(stp->chSimTX[Ch3Throttle], 5, 'f', 2) + .arg(stp->chSimRX[Ch3Throttle], 5, 'f', 2) + .arg(pts->chNewTX[Ch3Throttle], 5, 'f', 2) + .arg(pts->chNewRX[Ch3Throttle], 5, 'f', 2) + .arg(stp->chSimTX[Ch4Rudder], 5, 'f', 2) + .arg(stp->chSimRX[Ch4Rudder], 5, 'f', 2) + .arg(pts->chNewTX[Ch4Rudder], 5, 'f', 2) + .arg(pts->chNewRX[Ch4Rudder], 5, 'f', 2) + .arg(stp->chSimTX[Ch5], 5, 'f', 2) + .arg(stp->chSimRX[Ch5], 5, 'f', 2) + .arg(pts->chNewTX[Ch5], 5, 'f', 2) + .arg(pts->chNewRX[Ch5], 5, 'f', 2) + .arg(stp->chSimTX[Ch6], 5, 'f', 2) + .arg(stp->chSimRX[Ch6], 5, 'f', 2) + .arg(pts->chNewTX[Ch6], 5, 'f', 2) + .arg(pts->chNewRX[Ch6], 5, 'f', 2) + .arg(stp->chSimTX[Ch7], 5, 'f', 2) + .arg(stp->chSimRX[Ch7], 5, 'f', 2) + .arg(pts->chNewTX[Ch7], 5, 'f', 2) + .arg(pts->chNewRX[Ch7], 5, 'f', 2) + .arg(stp->chSimTX[Ch23Plugin1], 5, 'f', 2) + .arg(stp->chSimRX[Ch23Plugin1], 5, 'f', 2) + .arg(pts->chNewTX[Ch23Plugin1], 5, 'f', 2) + .arg(pts->chNewRX[Ch23Plugin1], 5, 'f', 2) + .arg(stp->chSimTX[Ch24Plugin2], 5, 'f', 2) + .arg(stp->chSimRX[Ch24Plugin2], 5, 'f', 2) + .arg(pts->chNewTX[Ch24Plugin2], 5, 'f', 2) + .arg(pts->chNewRX[Ch24Plugin2], 5, 'f', 2) + .arg(stp->chSimTX[Ch12FPVCamPan], 5, 'f', 2) + .arg(stp->chSimRX[Ch12FPVCamPan], 5, 'f', 2) + .arg(pts->chNewTX[Ch12FPVCamPan], 5, 'f', 2) + .arg(pts->chNewRX[Ch12FPVCamPan], 5, 'f', 2) + .arg(stp->chSimTX[Ch13FPVCamTilt], 5, 'f', 2) + .arg(stp->chSimRX[Ch13FPVCamTilt], 5, 'f', 2) + .arg(pts->chNewTX[Ch13FPVCamTilt], 5, 'f', 2) + .arg(pts->chNewRX[Ch13FPVCamTilt], 5, 'f', 2) + .arg(stp->simMenuStatus) + .arg(stp->posX, 5, 'f', 2) + .arg(stp->posY, 5, 'f', 2) + .arg(stp->posZ, 5, 'f', 2) + .arg(stp->velX, 5, 'f', 2) + .arg(stp->velY, 5, 'f', 2) + .arg(stp->velZ, 5, 'f', 2) + .arg(stp->angVelXm, 5, 'f', 2) + .arg(stp->angVelYm, 5, 'f', 2) + .arg(stp->angVelZm, 5, 'f', 2) + .arg(stp->accelXm, 5, 'f', 2) + .arg(stp->accelYm, 5, 'f', 2) + .arg(stp->accelZm, 5, 'f', 2) + .arg(stp->latitude, 5, 'f', 2) + .arg(stp->longitude, 5, 'f', 2) + .arg(stp->AGL, 5, 'f', 2) + .arg(stp->heading*RAD2DEG, 5, 'f', 2) + .arg(stp->pitch*RAD2DEG, 5, 'f', 2) + .arg(stp->roll*RAD2DEG, 5, 'f', 2) + ); +} + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_Run(const simToPlugin *stp, + pluginToSim *pts) +{ + debugInfo = "---\n"; + // By default do not change the Menu Items of type CheckBox + pts->newMenuStatus = stp->simMenuStatus; + // Extract Menu Commands from Flags + bool isReset = (stp->simMenuStatus & MenuCmdReset) != 0; + bool isEnable = (stp->simMenuStatus & MenuEnable) != 0; + bool isTxON = (stp->simMenuStatus & MenuTx) != 0; + bool isRxON = (stp->simMenuStatus & MenuRx) != 0; + bool isScreen = (stp->simMenuStatus & MenuScreen) != 0; + bool isNextWp = (stp->simMenuStatus & MenuNextWpt) != 0; + // Run commands + if (isReset) { + Run_Command_Reset(/*stp, pts*/); + } else if (isScreen) { + Run_Command_WindowSizeAndPos(stp, pts); + } else if (isNextWp) { + Run_Command_MoveToNextWaypoint(stp, pts); + } else { + Run_BlinkLEDs(stp, pts); + if (isEnable) { + if (isTxON) + sndr->sendDatagram(stp); + if (isRxON) + rcvr->setChannels(pts); + } + + // network lag + debugInfo.append(QString("out: %1, inp: %2, delta: %3\n") + .arg(sndr->pcks() - 1) + .arg(rcvr->pcks()) + .arg(sndr->pcks() - rcvr->pcks() - 1) + ); + } + + // debug info is shown on the screen + InfoText(stp, pts); + pts->dbgInfoText = debugInfo.toAscii(); + isFirstRun = false; +} diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.h new file mode 100644 index 000000000..a590c8a24 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * + * @file plugin.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include +#include +#include +#include "aerosimrcdatastruct.h" + +#define SIM_DLL_EXPORT extern "C" __declspec(dllexport) + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_ReportStructSizes( + quint32 *sizeSimToPlugin, + quint32 *sizePluginToSim, + quint32 *sizePluginInit +); + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_Init( + pluginInit *p +); + +SIM_DLL_EXPORT void AeroSIMRC_Plugin_Run( + const simToPlugin *stp, + pluginToSim *pts +); + +#endif // PLUGIN_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.pro b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.pro new file mode 100644 index 000000000..51bb42abd --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/plugin.pro @@ -0,0 +1,71 @@ +!win32 { + error("AeroSimRC plugin is only available for win32 platform") +} + +include(../../../../../openpilotgcs.pri) + +QT += network +QT -= gui + +TEMPLATE = lib +TARGET = plugin_AeroSIMRC + +RES_DIR = $${PWD}/resources +SIM_DIR = $$GCS_BUILD_TREE/../AeroSIM-RC +PLUGIN_DIR = $$SIM_DIR/Plugin/CopterControl +DLLDESTDIR = $$PLUGIN_DIR + +HEADERS = \ + aerosimrcdatastruct.h \ + enums.h \ + plugin.h \ + qdebughandler.h \ + udpconnect.h \ + settings.h + +SOURCES = \ + qdebughandler.cpp \ + plugin.cpp \ + udpconnect.cpp \ + settings.cpp + +# Resemble the AeroSimRC directory structure and copy plugin files and resources +equals(copydata, 1) { + + # Windows release only + win32:CONFIG(release, debug|release) { + + data_copy.commands += -@$(MKDIR) $$targetPath(\"$$PLUGIN_DIR\") $$addNewline() + + # resources and sample configuration + PLUGIN_RESOURCES = \ + cc_off.tga \ + cc_off_hover.tga \ + cc_on.tga \ + cc_on_hover.tga \ + cc_plugin.ini \ + plugin.txt + for(res, PLUGIN_RESOURCES) { + data_copy.commands += $(COPY_FILE) $$targetPath(\"$$RES_DIR/$$res\") $$targetPath(\"$$PLUGIN_DIR/$$res\") $$addNewline() + } + + # Qt DLLs + QT_DLLS = \ + QtCore4.dll \ + QtNetwork4.dll + for(dll, QT_DLLS) { + data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/$$dll\") $$targetPath(\"$$SIM_DIR/$$dll\") $$addNewline() + } + + # MinGW DLLs + MINGW_DLLS = \ + libgcc_s_dw2-1.dll \ + mingwm10.dll + for(dll, MINGW_DLLS) { + data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../../../../mingw/bin/$$dll\") $$targetPath(\"$$SIM_DIR/$$dll\") $$addNewline() + } + + data_copy.target = FORCE + QMAKE_EXTRA_TARGETS += data_copy + } +} diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.cpp new file mode 100644 index 000000000..bb9617511 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.cpp @@ -0,0 +1,64 @@ +/** + ****************************************************************************** + * + * @file qdebughandler.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "qdebughandler.h" + +void myQDebugHandler(QtMsgType type, const char *msg) +{ + static bool firstRun = true; + QString txt; + + switch (type) { + case QtDebugMsg: + txt = QString("Debug: %1").arg(msg); + break; + case QtWarningMsg: + txt = QString("Warning: %1").arg(msg); + break; + case QtCriticalMsg: + txt = QString("Critical: %1").arg(msg); + break; + case QtFatalMsg: + txt = QString("Fatal: %1").arg(msg); + break; + } + + QFile outFile("dbglog.txt"); + outFile.open(QIODevice::WriteOnly | QIODevice::Append); + QTextStream ts(&outFile); + QTime time; + + if (firstRun) { + ts << endl << endl; + firstRun = false; + } + + ts << time.currentTime().toString("hh:mm:ss.zzz") << " " << txt << endl; + + if (type == QtFatalMsg) + abort(); +} diff --git a/flight/Libraries/inc/NMEA.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.h similarity index 65% rename from flight/Libraries/inc/NMEA.h rename to ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.h index c3f8b66d9..d41dc6a67 100644 --- a/flight/Libraries/inc/NMEA.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/qdebughandler.h @@ -1,16 +1,13 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules - * @{ - * @addtogroup GSPModule GPS Module - * @brief Process GPS information - * @{ - * - * @file NMEA.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief GPS module, handles GPS and NMEA stream - * @see The GNU Public License (GPL) Version 3 * + * @file qdebughandler.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -28,15 +25,13 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef NMEA_H -#define NMEA_H +#ifndef QDEBUGHANDLER_H +#define QDEBUGHANDLER_H -#include -#include +#include +#include +#include -#define NMEA_MAX_PACKET_LENGTH 96 +void myQDebugHandler(QtMsgType type, const char *msg); -extern bool NMEA_update_position(char *nmea_sentence); -extern bool NMEA_checksum(char *nmea_sentence); - -#endif /* NMEA_H */ +#endif // QDEBUGHANDLER_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off.tga b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off.tga new file mode 100644 index 000000000..d8f4e0297 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off.tga differ diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off_hover.tga b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off_hover.tga new file mode 100644 index 000000000..e00d86a48 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_off_hover.tga differ diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on.tga b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on.tga new file mode 100644 index 000000000..424853384 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on.tga differ diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on_hover.tga b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on_hover.tga new file mode 100644 index 000000000..406204e32 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_on_hover.tga differ diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_plugin.ini b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_plugin.ini new file mode 100644 index 000000000..8b4174f60 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/cc_plugin.ini @@ -0,0 +1,55 @@ +[General] + +; Network settings +listen_on_host = 127.0.0.1 +listen_on_port = 40200 +send_to_host = 127.0.0.1 +send_to_port = 40100 + +; Channels enumerator, applicable for the AeroSIM RC version 3.90+ +all_channels = Ch1-Aileron Ch2-Elevator Ch3-Throttle Ch4-Rudder Ch5 Ch6 Ch7 Ch8 Ch9 Ch10-Retracts Ch11-Flaps Ch12-FPV-Pan Ch13-FPV-Tilt Ch14-Brakes Ch15-Spoilers Ch16-Smoke Ch17-Fire Ch18-Flight-Mode Ch19-ALT-Hold Ch20-FPV-Tilt-Hold Ch21-Reset-Model Ch22-MouseTX Ch23-Plugin-1 Ch24-Plugin-2 Ch25-Throttle-Hold Ch26-CareFree Ch27-FPV-Roll Ch28-L-Motor-Dual Ch29-R-Motor-Dual Ch30-Mix Ch31-Mix Ch32-Mix Ch33-Mix Ch34-Mix Ch35-Mix Ch36-Mix Ch37-Mix Ch38-Mix Ch39-Mix + +[Input] + +; Map CopterControl channels to simulator channels +; To use internal simulator channels just comment the mapping here +cc_channel_1 = Ch1-Aileron +cc_channel_2 = Ch2-Elevator +cc_channel_3 = Ch3-Throttle +cc_channel_4 = Ch4-Rudder +;cc_channel_5 = Ch27-FPV-Roll +cc_channel_6 = Ch13-FPV-Tilt +;cc_channel_7 = Ch12-FPV-Pan +;cc_channel_8 = +;cc_channel_9 = +;cc_channel_10= + +; Control TX or RX (before or after mixes) +send_to = RX + +[Output] + +; Map simulator channels to GCS HiTL/CopterControl channels +; Only mapped channels will be sent to the GCS +sim_channel_1 = Ch1-Aileron +sim_channel_2 = Ch2-Elevator +sim_channel_3 = Ch3-Throttle +sim_channel_4 = Ch4-Rudder +sim_channel_5 = Ch23-Plugin-1 +;sim_channel_6 = Ch27-FPV-Roll +sim_channel_7 = Ch13-FPV-Tilt +;sim_channel_8 = Ch12-FPV-Pan + +; take values from TX or RX (before or after mixes) +take_from = TX + +[Video] + +; Windowed simulator mode configurations +; Each resolution defines the upper left corner and width/hight. +; User can cycle through all resolutions using the menu command. +number_of_resolutions = 2 + +; x, y, width, height +resolution_1 = 50 50 640 720 +resolution_2 = 0 0 800 480 diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/plugin.txt b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/plugin.txt new file mode 100644 index 000000000..901e5c50a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/resources/plugin.txt @@ -0,0 +1,86 @@ +.NAME "CopterControl" + +.HELP_EN "\ +OpenPilot CopterControl HiTL plugin for AeroSIM RC" + +.IMAGE_OFF "cc_off.tga" +.IMAGE_ON "cc_on.tga" +.IMAGE_OFF_MOUSE_HOVER "cc_off_hover.tga" +.IMAGE_ON_MOUSE_HOVER "cc_on_hover.tga" + +.MENU_ITEM_00_NAME "Enable" +.MENU_ITEM_00_TYPE CHECKBOX +.MENU_ITEM_00_HAS_SEPARATOR 0 +.MENU_ITEM_00_MOUSE_RECT_XY 89 91 +.MENU_ITEM_00_MOUSE_RECT_DXDY 48 48 +.MENU_ITEM_00_HIDE_MENU_ITEM 0 + +.MENU_ITEM_01_NAME "Transmit data" +.MENU_ITEM_01_TYPE CHECKBOX +.MENU_ITEM_01_HAS_SEPARATOR 0 +.MENU_ITEM_01_MOUSE_RECT_XY 110 166 +.MENU_ITEM_01_MOUSE_RECT_DXDY 52 34 +.MENU_ITEM_01_HIDE_MENU_ITEM 0 + +.MENU_ITEM_02_NAME "Receive data" +.MENU_ITEM_02_TYPE CHECKBOX +.MENU_ITEM_02_HAS_SEPARATOR 1 +.MENU_ITEM_02_MOUSE_RECT_XY 36 166 +.MENU_ITEM_02_MOUSE_RECT_DXDY 52 34 +.MENU_ITEM_02_HIDE_MENU_ITEM 0 + +.MENU_ITEM_03_NAME "Change window size and position" +.MENU_ITEM_03_TYPE COMMAND +.MENU_ITEM_03_HAS_SEPARATOR 0 +.MENU_ITEM_03_MOUSE_RECT_XY 0 0 +.MENU_ITEM_03_MOUSE_RECT_DXDY 0 0 +.MENU_ITEM_03_HIDE_MENU_ITEM 0 + +.MENU_ITEM_04_NAME "Move to next waypoint" +.MENU_ITEM_04_TYPE COMMAND +.MENU_ITEM_04_HAS_SEPARATOR 0 +.MENU_ITEM_04_MOUSE_RECT_XY 0 0 +.MENU_ITEM_04_MOUSE_RECT_DXDY 0 0 +.MENU_ITEM_04_HIDE_MENU_ITEM 0 + +.MENU_ITEM_05_NAME "no action" +.MENU_ITEM_05_TYPE COMMAND +.MENU_ITEM_05_HAS_SEPARATOR 0 +.MENU_ITEM_05_MOUSE_RECT_XY 0 0 +.MENU_ITEM_05_MOUSE_RECT_DXDY 0 0 +.MENU_ITEM_05_HIDE_MENU_ITEM 0 + +.MENU_ITEM_06_NAME "Blue LED" +.MENU_ITEM_06_TYPE CHECKBOX +.MENU_ITEM_06_HAS_SEPARATOR 0 +.MENU_ITEM_06_MOUSE_RECT_XY 6 40 +.MENU_ITEM_06_MOUSE_RECT_DXDY 15 12 +.MENU_ITEM_06_HIDE_MENU_ITEM 1 + +.MENU_ITEM_07_NAME "Green LED" +.MENU_ITEM_07_TYPE CHECKBOX +.MENU_ITEM_07_HAS_SEPARATOR 0 +.MENU_ITEM_07_MOUSE_RECT_XY 6 52 +.MENU_ITEM_07_MOUSE_RECT_DXDY 15 12 +.MENU_ITEM_07_HIDE_MENU_ITEM 1 + +.MENU_ITEM_08_NAME "FlightMode 1" +.MENU_ITEM_08_TYPE CHECKBOX +.MENU_ITEM_08_HAS_SEPARATOR 0 +.MENU_ITEM_08_MOUSE_RECT_XY 40 19 +.MENU_ITEM_08_MOUSE_RECT_DXDY 38 38 +.MENU_ITEM_08_HIDE_MENU_ITEM 1 + +.MENU_ITEM_09_NAME "FlightMode 2" +.MENU_ITEM_09_TYPE CHECKBOX +.MENU_ITEM_09_HAS_SEPARATOR 0 +.MENU_ITEM_09_MOUSE_RECT_XY 78 19 +.MENU_ITEM_09_MOUSE_RECT_DXDY 38 38 +.MENU_ITEM_09_HIDE_MENU_ITEM 1 + +.MENU_ITEM_10_NAME "FlightMode 3" +.MENU_ITEM_10_TYPE CHECKBOX +.MENU_ITEM_10_HAS_SEPARATOR 0 +.MENU_ITEM_10_MOUSE_RECT_XY 115 19 +.MENU_ITEM_10_MOUSE_RECT_DXDY 38 38 +.MENU_ITEM_10_HIDE_MENU_ITEM 1 diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.cpp new file mode 100644 index 000000000..6c19f91dc --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.cpp @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * + * @file settings.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "settings.h" + +Settings::Settings(QString settingsPath, QObject *parent) : + QObject(parent) +{ + settings = new QSettings(settingsPath + "/cc_plugin.ini", QSettings::IniFormat); + // default settings + sendToHost = "127.0.0.1"; + sendToPort = 40100; + listenOnHost = "127.0.0.1"; + listenOnPort = 40200; + channels.reserve(60); + for (quint8 i = 0; i < 10; ++i) + inputMap << 255; + for (quint8 i = 0; i < 8; ++i) + outputMap << 255; + sendToRX = true; + takeFromTX = true; + videoModes << 1 << 50 << 50 << 800 << 600; +} + +void Settings::read() +{ + // network + listenOnHost = settings->value("listen_on_host", listenOnHost).toString(); + listenOnPort = settings->value("listen_on_port", listenOnPort).toInt(); + sendToHost = settings->value("send_to_host", sendToHost).toString(); + sendToPort = settings->value("send_to_port", sendToPort).toInt(); + + QString allChannels = settings->value("all_channels").toString(); + QString chan; + int i = 0; + foreach (chan, allChannels.split(" ")) + channels.insert(chan, i++); + + // inputs + QString num = ""; + QString map = ""; + for (quint8 i = 0; i < 10; ++i) { + num = QString::number(i+1); + map = settings->value("Input/cc_channel_" + num).toString(); + inputMap[i] = channels.value(map, inputMap.at(i)); + } + + QString sendTo = settings->value("Input/send_to", "RX").toString(); + sendToRX = (sendTo == "RX") ? true : false; + + // outputs + for (quint8 i = 0; i < 8; ++i) { + num = QString::number(i+1); + map = settings->value("Output/sim_channel_" + num).toString(); + outputMap[i] = channels.value(map, outputMap.at(i)); + } + + QString takeFrom = settings->value("Output/take_from", "TX").toString(); + takeFromTX = (takeFrom == "TX") ? true : false; + + // video + quint8 resolutionNum = settings->value("Video/number_of_resolutions", 0).toInt(); + if (resolutionNum > 0) { + videoModes.clear(); + videoModes << resolutionNum; + for (quint8 i = 0; i < resolutionNum; ++i) { + num = QString::number(i+1); + QString modes = settings->value("Video/resolution_" + num, "0, 0, 640, 480").toString(); + QString mode; + foreach (mode, modes.split(" ")) + videoModes << mode.toInt(); + } + } +} diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.h new file mode 100644 index 000000000..5bc39135d --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/settings.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * + * @file settings.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include +#include +#include +#include +#include + +class Settings : public QObject +{ +public: + explicit Settings(QString settingsPath, QObject *parent = 0); + void read(); + QString remoteHost() { return sendToHost; } + quint16 remotePort() { return sendToPort; } + QString localHost() { return listenOnHost; } + quint16 localPort() { return listenOnPort; } + QList getInputMap() { return inputMap; } + QList getOutputMap() { return outputMap; } + bool isToRX() { return sendToRX; } + bool isFromTX() { return takeFromTX; } + QList getVideoModes() { return videoModes; } + +private: + QHash channels; + QSettings *settings; + QString sendToHost; + quint16 sendToPort; + QString listenOnHost; + quint16 listenOnPort; + QList inputMap; + QList outputMap; + bool sendToRX; + bool takeFromTX; + QList videoModes; +}; + +#endif // SETTINGS_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.cpp new file mode 100644 index 000000000..0448a705a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.cpp @@ -0,0 +1,228 @@ +/** + ****************************************************************************** + * + * @file udpconnect.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "udpconnect.h" +#include "enums.h" + +UdpSender::UdpSender(const QList map, + bool isTX, + QObject *parent) + : QObject(parent) +{ + qDebug() << this << "UdpSender::UdpSender thread:" << thread(); + outSocket = NULL; + for (int i = 0; i < 8; ++i) + channels << 0.0; + channelsMap = map; + takeFromTX = isTX; + packetsSended = 0; +} + +UdpSender::~UdpSender() +{ + qDebug() << this << "UdpSender::~UdpSender"; + if (outSocket) + delete outSocket; +} + +// public +void UdpSender::init(const QString &remoteHost, quint16 remotePort) +{ + qDebug() << this << "UdpSender::init"; + outHost = remoteHost; + outPort = remotePort; + outSocket = new QUdpSocket(); +} + +void UdpSender::sendDatagram(const simToPlugin *stp) +{ + QByteArray data; + data.resize(188); + QDataStream out(&data, QIODevice::WriteOnly); + out.setFloatingPointPrecision(QDataStream::SinglePrecision); + + // magic header, "AERO" + out << quint32(0x4153494D); + // simulation step + out << stp->simTimeStep; + // home location + out << stp->initPosX << stp->initPosY << stp->initPosZ; + out << stp->wpHomeX << stp->wpHomeY << stp->wpHomeLat << stp->wpHomeLong; + // position + out << stp->posX << stp->posY << stp->posZ; + // velocity (world) + out << stp->velX << stp->velY << stp->velZ; + // angular velocity (model) + out << stp->angVelXm << stp->angVelYm << stp->angVelZm; + // acceleration (model) + out << stp->accelXm << stp->accelYm << stp->accelZm; + // coordinates + out << stp->latitude << stp->longitude; + // sonar + out << stp->AGL; + // attitude + out << stp->heading << stp->pitch << stp->roll; + // electric + out << stp->voltage << stp->current; + // matrix + out << stp->axisXx << stp->axisXy << stp->axisXz; + out << stp->axisYx << stp->axisYy << stp->axisYz; + out << stp->axisZx << stp->axisZy << stp->axisZz; + // channels + for (int i = 0; i < 8; ++i) { + quint8 mapTo = channelsMap.at(i); + if (mapTo == 255) // unused channel + out << 0.0; + else if (takeFromTX) // use values from simulators transmitter + out << stp->chSimTX[mapTo]; + else // direct use values from ESC/motors/ailerons/etc + out << stp->chSimRX[mapTo]; + } + + // packet counter + out << packetsSended; + + outSocket->writeDatagram(data, outHost, outPort); + ++packetsSended; +} + +//----------------------------------------------------------------------------- + +UdpReceiver::UdpReceiver(const QList map, + bool isRX, + QObject *parent) + : QThread(parent) +{ + qDebug() << this << "UdpReceiver::UdpReceiver thread:" << thread(); + + stopped = false; + inSocket = NULL; + for (int i = 0; i < 10; ++i) + channels << -1.0; + channelsMap = map; + sendToRX = isRX; + armed = 0; + mode = 0; + packetsRecived = 1; +} + +UdpReceiver::~UdpReceiver() +{ + qDebug() << this << "UdpReceiver::~UdpReceiver"; + if (inSocket) + delete inSocket; +} + +// public +void UdpReceiver::init(const QString &localHost, quint16 localPort) +{ + qDebug() << this << "UdpReceiver::init"; + + inSocket = new QUdpSocket(); + qDebug() << this << "inSocket constructed" << inSocket->thread(); + + inSocket->bind(QHostAddress(localHost), localPort); +} + +void UdpReceiver::run() +{ + qDebug() << this << "UdpReceiver::run start"; + while (!stopped) + onReadyRead(); + qDebug() << this << "UdpReceiver::run ended"; +} + +void UdpReceiver::stop() +{ + qDebug() << this << "UdpReceiver::stop"; + stopped = true; +} + +void UdpReceiver::setChannels(pluginToSim *pts) +{ + QMutexLocker locker(&mutex); + + for (int i = 0; i < 10; ++i) { + quint8 mapTo = channelsMap.at(i); + if (mapTo != 255) { + float channelValue = qBound(-1.0f, channels.at(i), 1.0f); + if (sendToRX) { + // direct connect to ESC/motors/ailerons/etc + pts->chNewRX[mapTo] = channelValue; + pts->chOverRX[mapTo] = true; + } else { + // replace simulators transmitter + pts->chNewTX[mapTo] = channelValue; + pts->chOverTX[mapTo] = true; + } + } + } +} + +void UdpReceiver::getFlighStatus(quint8 &arm, quint8 &mod) +{ + QMutexLocker locker(&mutex); + + arm = armed; + mod = mode; +} + +// private +void UdpReceiver::onReadyRead() +{ + if (!inSocket->waitForReadyRead(8)) // 1/60fps ~= 16.7ms, 1/120fps ~= 8.3ms + return; + // TODO: add failsafe + // if a command not recieved then slowly return all channel to neutral + // + while (inSocket->hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + quint64 datagramSize; + datagramSize = inSocket->readDatagram(datagram.data(), datagram.size()); + + processDatagram(datagram); + } +} + +void UdpReceiver::processDatagram(QByteArray &datagram) +{ + QDataStream stream(datagram); + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + // check magic header + quint32 magic; + stream >> magic; + if (magic != 0x52434D44) // "RCMD" + return; + // read channels + for (int i = 0; i < 10; ++i) + stream >> channels[i]; + // read flight mode + stream >> armed >> mode; + // read counter + stream >> packetsRecived; +} diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.h new file mode 100644 index 000000000..ead07f046 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udpconnect.h @@ -0,0 +1,90 @@ +/** + ****************************************************************************** + * + * @file udpconnect.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UDPCONNECT_H +#define UDPCONNECT_H + +#include +#include +#include +#include +#include +#include +#include "aerosimrcdatastruct.h" + +class UdpSender : public QObject +{ +// Q_OBJECT +public: + explicit UdpSender(const QList map, bool isTX, QObject *parent = 0); + ~UdpSender(); + void init(const QString &remoteHost, quint16 remotePort); + void sendDatagram(const simToPlugin *stp); + quint32 pcks() { return packetsSended; } + +private: + QUdpSocket *outSocket; + QHostAddress outHost; + quint16 outPort; + QList channels; + QList channelsMap; + bool takeFromTX; + quint32 packetsSended; +}; + + +class UdpReceiver : public QThread +{ +// Q_OBJECT +public: + explicit UdpReceiver(const QList map, bool isRX, QObject *parent = 0); + ~UdpReceiver(); + void init(const QString &localHost, quint16 localPort); + void run(); + void stop(); + // function getChannels for other threads + void setChannels(pluginToSim *pts); + void getFlighStatus(quint8 &arm, quint8 &mod); + quint8 getArmed() { return armed; } + quint8 getMode() { return mode; } + quint32 pcks() { return packetsRecived; } + +private: + volatile bool stopped; + QMutex mutex; + QUdpSocket *inSocket; + QList channels; + QList channelsMap; + bool sendToRX; + quint8 armed; + quint8 mode; + quint32 packetsRecived; + void onReadyRead(); + void processDatagram(QByteArray &datagram); +}; + +#endif // UDPCONNECT_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptest.pro b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptest.pro new file mode 100644 index 000000000..ac63be5ae --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptest.pro @@ -0,0 +1,17 @@ +include(../../../../../openpilotgcs.pri) + +QT += core gui network + +TEMPLATE = app +TARGET = udp_test +DESTDIR = $$GCS_APP_PATH + +HEADERS += \ + udptestwidget.h + +SOURCES += \ + udptestmain.cpp \ + udptestwidget.cpp + +FORMS += \ + udptestwidget.ui diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestmain.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestmain.cpp new file mode 100644 index 000000000..744e4bf25 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestmain.cpp @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * + * @file udptestmain.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin test utility + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "udptestwidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + + return a.exec(); +} diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.cpp b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.cpp new file mode 100644 index 000000000..9ab45e45a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.cpp @@ -0,0 +1,537 @@ +/** + ****************************************************************************** + * + * @file udptestwidget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin test utility + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "udptestwidget.h" +#include "ui_udptestwidget.h" + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + + inSocket = NULL; + outSocket = NULL; + screenTimeout.start(); + packetCounter = 0; + + autoSendTimer = new QTimer(this); + connect(autoSendTimer, SIGNAL(timeout()), this, SLOT(sendDatagram()), Qt::DirectConnection); +} + +Widget::~Widget() +{ + if(outSocket) { + delete outSocket; + } + if(inSocket) { + delete inSocket; + } + delete ui; +} + +// private slots ////////////////////////////////////////////////////////////// + +void Widget::on_btReciveStart_clicked() +{ + on_btReciveStop_clicked(); + + inSocket = new QUdpSocket(); + QString host = ui->localHost->text(); + quint16 port = ui->localPort->text().toInt(); + + if (inSocket->bind(QHostAddress(host), port)) { + connect(inSocket, SIGNAL(readyRead()), + this, SLOT(readDatagram()), Qt::DirectConnection); + + ui->listWidget->addItem("bind ok"); + ui->btReciveStop->setEnabled(1); + ui->localHost->setDisabled(1); + ui->localPort->setDisabled(1); + ui->btReciveStart->setDisabled(1); + } else { + ui->listWidget->addItem("bind error: " + inSocket->errorString()); + } +} + +void Widget::on_btReciveStop_clicked() +{ + if(inSocket) { + delete inSocket; + inSocket = NULL; + ui->listWidget->addItem("unbind ok"); + } else { + ui->listWidget->addItem("socket not found"); + } + ui->btReciveStart->setEnabled(1); + ui->localHost->setEnabled(1); + ui->localPort->setEnabled(1); + ui->btReciveStop->setDisabled(1); +} + +void Widget::on_btTransmitStart_clicked() +{ + on_btTransmitStop_clicked(); + + outSocket = new QUdpSocket(); + outHost = ui->simHost->text(); + outPort = ui->simPort->text().toInt(); + + ui->listWidget->addItem("transmit started"); + ui->btTransmitStop->setEnabled(1); + ui->simHost->setDisabled(1); + ui->simPort->setDisabled(1); + ui->btTransmitStart->setDisabled(1); +} + +void Widget::on_btTransmitStop_clicked() +{ + if(outSocket) { + delete outSocket; + outSocket = NULL; + ui->listWidget->addItem("transmit stopped"); + } else { + ui->listWidget->addItem("transmit socket not found"); + } + ui->btTransmitStart->setEnabled(1); + ui->simHost->setEnabled(1); + ui->simPort->setEnabled(1); + ui->btTransmitStop->setDisabled(1); +} + +void Widget::readDatagram() +{ + while (inSocket->hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + QHostAddress sender; + quint16 senderPort; + quint64 datagramSize = inSocket->readDatagram(datagram.data(), datagram.size(), + &sender, &senderPort); + Q_UNUSED(datagramSize); + + processDatagram(datagram); + if (ui->autoAnswer->isChecked()) + sendDatagram(); + } +} + +// private //////////////////////////////////////////////////////////////////// + +void Widget::processDatagram(const QByteArray &data) +{ + QByteArray buf = data; + QDataStream stream(&buf, QIODevice::ReadOnly); + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + + // check magic header + quint32 magic; + stream >> magic; + if (magic == 0x4153494D) { // "AERO" + float timeStep, + homeX, homeY, homeZ, + WpHX, WpHY, WpLat, WpLon, + posX, posY, posZ, + velX, velY, velZ, + angX, angY, angZ, + accX, accY, accZ, + lat, lon, alt, + head, pitch, roll, + volt, curr, + rx, ry, rz, fx, fy, fz, ux, uy, uz, + chAil, chEle, chThr, chRud, chPlg1, chPlg2, chFpv1, chFpv2; + + stream >> timeStep; + stream >> homeX >> homeY >> homeZ; + stream >> WpHX >> WpHY >> WpLat >> WpLon; + stream >> posX >> posY >> posZ; + stream >> velX >> velY >> velZ; + stream >> angX >> angY >> angZ; + stream >> accX >> accY >> accZ; + stream >> lat >> lon >> alt; + stream >> head >> pitch >> roll; + stream >> volt >> curr; + stream >> rx >> ry >> rz >> fx >> fy >> fz >> ux >> uy >> uz; + stream >> chAil >> chEle >> chThr >> chRud >> chPlg1 >> chPlg2 >> chFpv1 >> chFpv2; + stream >> packetCounter; + + if(ui->tabWidget->currentIndex() != 0) + return; + + if (screenTimeout.elapsed() < 200) + return; + + ui->listWidget->clear(); + /* + ui->listWidget->addItem("time step (s)"); + ui->listWidget->addItem(QString("%1") + .arg(timeStep); + ui->listWidget->addItem("home location (m)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(homeX, 7, 'f', 4) + .arg(homeY, 7, 'f', 4) + .arg(homeZ, 7, 'f', 4)); + ui->listWidget->addItem("home waypoint"); + ui->listWidget->addItem(QString("%1, %2, %3, %4") + .arg(WpHX, 7, 'f', 4) + .arg(WpHY, 7, 'f', 4) + .arg(WpLat, 7, 'f', 4) + .arg(WpLon, 7, 'f', 4)); + ui->listWidget->addItem("model position (m)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(posX, 7, 'f', 4) + .arg(posY, 7, 'f', 4) + .arg(posZ, 7, 'f', 4)); + ui->listWidget->addItem("model velocity (m/s)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(velX, 7, 'f', 4) + .arg(velY, 7, 'f', 4) + .arg(velZ, 7, 'f', 4)); + ui->listWidget->addItem("model angular velocity (rad/s)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(angX, 7, 'f', 4) + .arg(angY, 7, 'f', 4) + .arg(angZ, 7, 'f', 4)); + ui->listWidget->addItem("model acceleration (m/s/s)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(accX, 7, 'f', 4) + .arg(accY, 7, 'f', 4) + .arg(accZ, 7, 'f', 4)); + ui->listWidget->addItem("model coordinates (deg, deg, m)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(lat, 7, 'f', 4) + .arg(lon, 7, 'f', 4) + .arg(alt, 7, 'f', 4)); + ui->listWidget->addItem("model electrics"); + ui->listWidget->addItem(QString("%1V, %2A") + .arg(volt, 7, 'f', 4) + .arg(curr, 7, 'f', 4)); + ui->listWidget->addItem("channels"); + ui->listWidget->addItem(QString("%1 %2 %3 %4 %5 %6 %7 %8") + .arg(chAil, 6, 'f', 3) + .arg(chEle, 6, 'f', 3) + .arg(chThr, 6, 'f', 3) + .arg(chRud, 6, 'f', 3) + .arg(chPlg1, 6, 'f', 3) + .arg(chPlg2, 6, 'f', 3) + .arg(chFpv1, 6, 'f', 3) + .arg(chFpv2, 6, 'f', 3)); + ui->listWidget->addItem("datagram size (bytes), packet counter"); + ui->listWidget->addItem(QString("%1 %2") + .arg(data.size()) + .arg(packetCounter)); +*/ + + // matrix calculation start + // model matrix + QMatrix4x4 m = QMatrix4x4( fy, fx, -fz, 0.0, + ry, rx, -rz, 0.0, + -uy, -ux, uz, 0.0, + 0.0, 0.0, 0.0, 1.0); + m.optimize(); + + // world matrix + QMatrix4x4 w = m.inverted(); + + // model quat + QQuaternion q; + asMatrix2Quat(m, q); + + // model roll, pitch, yaw + QVector3D rpy; + asMatrix2RPY(m, rpy); + + // sonar + float sAlt = 5.0; + if ((alt < (sAlt * 2.0)) && (roll < 0.35) && (pitch < 0.35)) { + float x = alt * qTan(roll); + float y = alt * qTan(pitch); + float h = QVector3D(x, y, alt).length(); + sAlt = qMin(h, sAlt); + } + + ui->listWidget->addItem("sonar altitude"); + ui->listWidget->addItem(QString("%1") + .arg(sAlt, 8, 'f', 5)); + ui->listWidget->addItem("vectors"); + ui->listWidget->addItem(QString(" X Y Z")); + ui->listWidget->addItem(QString("R: %1 %2 %3\nF: %4 %5 %6\nU: %7 %8 %9") + .arg(rx, 8, 'f', 5).arg(ry, 8, 'f', 5).arg(rz, 8, 'f', 5) + .arg(fx, 8, 'f', 5).arg(fy, 8, 'f', 5).arg(fz, 8, 'f', 5) + .arg(ux, 8, 'f', 5).arg(uy, 8, 'f', 5).arg(uz, 8, 'f', 5)); + ui->listWidget->addItem("CC model matrix"); + ui->listWidget->addItem(QString(" %1 %2 %3\n %4 %5 %6\n %7 %8 %9") + .arg(m(0, 0), 8, 'f', 5).arg(m(0, 1), 8, 'f', 5).arg(m(0, 2), 8, 'f', 5) + .arg(m(1, 0), 8, 'f', 5).arg(m(1, 1), 8, 'f', 5).arg(m(1, 2), 8, 'f', 5) + .arg(m(2, 0), 8, 'f', 5).arg(m(2, 1), 8, 'f', 5).arg(m(2, 2), 8, 'f', 5)); + ui->listWidget->addItem("CC world matrix"); + ui->listWidget->addItem(QString(" %1 %2 %3\n %4 %5 %6\n %7 %8 %9") + .arg(w(0, 0), 8, 'f', 5).arg(w(0, 1), 8, 'f', 5).arg(w(0, 2), 8, 'f', 5) + .arg(w(1, 0), 8, 'f', 5).arg(w(1, 1), 8, 'f', 5).arg(w(1, 2), 8, 'f', 5) + .arg(w(2, 0), 8, 'f', 5).arg(w(2, 1), 8, 'f', 5).arg(w(2, 2), 8, 'f', 5)); + ui->listWidget->addItem("CC quaternion"); + ui->listWidget->addItem(QString("%1, %2, %3, %4") + .arg(q.x(), 7, 'f', 4) + .arg(q.y(), 7, 'f', 4) + .arg(q.z(), 7, 'f', 4) + .arg(q.scalar(), 7, 'f', 4)); + ui->listWidget->addItem("model attitude (deg)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(roll*RAD2DEG, 7, 'f', 4) + .arg(pitch*RAD2DEG, 7, 'f', 4) + .arg(head*RAD2DEG, 7, 'f', 4)); + ui->listWidget->addItem("CC attitude calculated (deg)"); + ui->listWidget->addItem(QString("%1, %2, %3") + .arg(rpy.x(), 7, 'f', 4) + .arg(rpy.y(), 7, 'f', 4) + .arg(rpy.z(), 7, 'f', 4)); + + screenTimeout.restart(); + + } else if (magic == 0x52434D44) { // "RCMD" + qreal ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10; + stream >> ch1 >> ch2 >> ch3 >> ch4 >> ch5 >> ch6 >> ch7 >> ch8 >> ch9 >> ch10; + quint8 armed, mode; + stream >> armed >> mode; + + if(ui->tabWidget->currentIndex() == 0) { + if (screenTimeout.elapsed() < 200) + return; + ui->listWidget->clear(); + ui->listWidget->addItem("channels"); + ui->listWidget->addItem("CH1: " + QString::number(ch1)); + ui->listWidget->addItem("CH2: " + QString::number(ch2)); + ui->listWidget->addItem("CH3: " + QString::number(ch3)); + ui->listWidget->addItem("CH4: " + QString::number(ch4)); + ui->listWidget->addItem("CH5: " + QString::number(ch5)); + ui->listWidget->addItem("CH6: " + QString::number(ch6)); + ui->listWidget->addItem("CH7: " + QString::number(ch7)); + ui->listWidget->addItem("CH8: " + QString::number(ch8)); + ui->listWidget->addItem("CH9: " + QString::number(ch9)); + ui->listWidget->addItem("CH10:" + QString::number(ch10)); + ui->listWidget->addItem("armed:" + QString::number(armed)); + ui->listWidget->addItem("fmode:" + QString::number(mode)); + } + screenTimeout.restart(); + } else { + qDebug() << "unknown magic:" << magic; + } +} + +void Widget::sendDatagram() +{ + if(!outSocket) + return; + + float ch[10]; // = {0,0,0,0,0,0,0,0,0,0}; + quint8 armed; + quint8 fmode; + const float coeff = 1.0 / 512.0; + + ch[0] = ui->ch1->value() * coeff; + ch[1] = ui->ch2->value() * coeff; + ch[2] = ui->ch3->value() * coeff; + ch[3] = ui->ch4->value() * coeff; + ch[4] = ui->ch5->value() * coeff; + ch[5] = ui->ch6->value() * coeff; + ch[6] = ui->ch7->value() * coeff; + ch[7] = ui->ch8->value() * coeff; + ch[8] = ui->ch9->value() * coeff; + ch[9] = ui->ch10->value() * coeff; + + armed = (ui->disarmed->isChecked()) ? 0 : (ui->arming->isChecked()) ? 1 : 2; + fmode = ui->flightMode->value(); + + QByteArray data; + // 50 - current size of values, 4(quint32) + 10*4(float) + 2*1(quint8) + 4(quint32) + data.resize(50); + QDataStream stream(&data, QIODevice::WriteOnly); + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + + // magic header, "RCMD" + stream << quint32(0x52434D44); + // send channels + for (int i = 0; i < 10; ++i) { + stream << ch[i]; + } + // send armed and mode + stream << armed << fmode; + // send readed counter + stream << packetCounter; + + if (outSocket->writeDatagram(data, outHost, outPort) == -1) { + qDebug() << "write failed: outHost" << outHost << " " + << "outPort " << outPort << " " + << outSocket->errorString(); + } +} + +void Widget::on_autoSend_clicked() +{ + autoSendTimer->start(100); + qDebug() << "timer start"; +} + +void Widget::on_autoAnswer_clicked() +{ + autoSendTimer->stop(); + qDebug() << "timer stop"; +} + +// transfomations + +void Widget::asMatrix2Quat(const QMatrix4x4 &m, QQuaternion &q) +{ + qreal w, x, y, z; + + // w always >= 0 + w = qSqrt(qMax(0.0, 1.0 + m(0, 0) + m(1, 1) + m(2, 2))) / 2.0; + x = qSqrt(qMax(0.0, 1.0 + m(0, 0) - m(1, 1) - m(2, 2))) / 2.0; + y = qSqrt(qMax(0.0, 1.0 - m(0, 0) + m(1, 1) - m(2, 2))) / 2.0; + z = qSqrt(qMax(0.0, 1.0 - m(0, 0) - m(1, 1) + m(2, 2))) / 2.0; + + x = copysign(x, (m(1, 2) - m(2, 1))); + y = copysign(y, (m(2, 0) - m(0, 2))); + z = copysign(z, (m(0, 1) - m(1, 0))); + + q.setScalar(w); + q.setX(x); + q.setY(y); + q.setZ(z); +} + +void Widget::asQuat2RPY(const QQuaternion &q, QVector3D &rpy) +{ + qreal roll; + qreal pitch; + qreal yaw; + + const qreal d2 = 2.0; + const qreal qss = q.scalar() * q.scalar(); + const qreal qxx = q.x() * q.x(); + const qreal qyy = q.y() * q.y(); + const qreal qzz = q.z() * q.z(); + + qreal test = -d2 * (q.x() * q.z() - q.scalar() * q.y()); + if (qFabs(test) > 0.998) { + // ~86.3, gimbal lock + qreal R10 = d2 * (q.x() * q.y() - q.scalar() * q.z()); + qreal R11 = qss - qxx + qyy - qzz; + + roll = 0.0; + pitch = copysign(M_PI_2, test); + yaw = qAtan2(-R10, R11); + } else { + qreal R12 = d2 * (q.y() * q.z() + q.scalar() * q.x()); + qreal R22 = qss - qxx - qyy + qzz; + qreal R01 = d2 * (q.x() * q.y() + q.scalar() * q.z()); + qreal R00 = qss + qxx - qyy - qzz; + + roll = qAtan2(R12, R22); + pitch = qAsin(test); + yaw = qAtan2(R01, R00); + } + rpy.setX(RAD2DEG * roll); + rpy.setY(RAD2DEG * pitch); + rpy.setZ(RAD2DEG * yaw); +} + +void Widget::asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy) +{ + qreal roll; + qreal pitch; + qreal yaw; + + if (qFabs(m(0, 2)) > 0.998) { + // ~86.3, gimbal lock + roll = 0.0; + pitch = copysign(M_PI_2, -m(0, 2)); + yaw = qAtan2(-m(1, 0), m(1, 1)); + } else { + roll = qAtan2(m(1, 2), m(2, 2)); + pitch = qAsin(-m(0, 2)); + yaw = qAtan2(m(0, 1), m(0, 0)); + } + + rpy.setX(roll * RAD2DEG); + rpy.setY(pitch * RAD2DEG); + rpy.setZ(yaw * RAD2DEG); +} + +/* // not used + +void Widget::ccRPY2Quat(const QVector3D &rpy, QQuaternion &q) +{ + float phi, theta, psi; + float cphi, sphi, ctheta, stheta, cpsi, spsi; + + phi = rpy.x() / 2; + theta = rpy.y() / 2; + psi = rpy.z() / 2; + cphi = cosf(phi); + sphi = sinf(phi); + ctheta = cosf(theta); + stheta = sinf(theta); + cpsi = cosf(psi); + spsi = sinf(psi); + + q.setScalar(cphi * ctheta * cpsi + sphi * stheta * spsi); + q.setX(sphi * ctheta * cpsi - cphi * stheta * spsi); + q.setY(cphi * stheta * cpsi + sphi * ctheta * spsi); + q.setZ(cphi * ctheta * spsi - sphi * stheta * cpsi); + + if (q.scalar() < 0) { // q0 always positive for uniqueness + q.setScalar(-q.scalar()); + q.setX(-q.x()); + q.setY(-q.y()); + q.setZ(-q.z()); + } +} + +void Widget::ccQuat2Matrix(const QQuaternion &q, QMatrix4x4 &m) +{ + float q0s = q.scalar() * q.scalar(); + float q1s = q.x() * q.x(); + float q2s = q.y() * q.y(); + float q3s = q.z() * q.z(); + + float m00 = q0s + q1s - q2s - q3s; + float m01 = 2 * (q.x() * q.y() + q.scalar() * q.z()); + float m02 = 2 * (q.x() * q.z() - q.scalar() * q.y()); + float m10 = 2 * (q.x() * q.y() - q.scalar() * q.z()); + float m11 = q0s - q1s + q2s - q3s; + float m12 = 2 * (q.y() * q.z() + q.scalar() * q.x()); + float m20 = 2 * (q.x() * q.z() + q.scalar() * q.y()); + float m21 = 2 * (q.y() * q.z() - q.scalar() * q.x()); + float m22 = q0s - q1s - q2s + q3s; + + m = QMatrix4x4(m00, m01, m02, 0, + m10, m11, m12, 0, + m20, m21, m22, 0, + 0, 0, 0, 1); +} +*/ diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.h b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.h new file mode 100644 index 000000000..500f35482 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * + * @file udptestwidget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. + * @addtogroup 3rdParty Third-party integration + * @{ + * @addtogroup AeroSimRC AeroSimRC proxy plugin + * @{ + * @brief AeroSimRC simulator to HITL proxy plugin test utility + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UDPTESTWIDGET_H +#define UDPTESTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { + class Widget; +} + +const float RAD2DEG = (float)(180.0/M_PI); +const float DEG2RAD = (float)(M_PI/180.0); + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + +private slots: + void on_btReciveStart_clicked(); + void on_btReciveStop_clicked(); + void on_btTransmitStart_clicked(); + void on_btTransmitStop_clicked(); + + void readDatagram(); + void sendDatagram(); + + void on_autoSend_clicked(); + + void on_autoAnswer_clicked(); + +private: + Ui::Widget *ui; + + QTime screenTimeout; + QUdpSocket *inSocket; + QUdpSocket *outSocket; + QHostAddress outHost; + quint16 outPort; + quint32 packetCounter; + + void processDatagram(const QByteArray &data); + QTimer *autoSendTimer; + + void asMatrix2Quat(const QMatrix4x4 &m, QQuaternion &q); + void asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy); + void asQuat2RPY(const QQuaternion &q, QVector3D &rpy); + +/* // not used + * void ccRPY2Quat(const QVector3D &rpy, QQuaternion &q); + * void ccQuat2Matrix(const QQuaternion &q, QMatrix4x4 &m); + */ +}; + +#endif // UDPTESTWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.ui b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.ui new file mode 100644 index 000000000..a060a6042 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/aerosimrc/src/udptestwidget.ui @@ -0,0 +1,940 @@ + + + Widget + + + + 0 + 0 + 440 + 525 + + + + udp_test + + + + + + + + + + + + 60 + 0 + + + + Connect + + + + + + + true + + + + 0 + 0 + + + + + 50 + 0 + + + + 40100 + + + 5 + + + + + + + true + + + + 0 + 0 + + + + 127.0.0.1 + + + + + + + sim host + + + + + + + local host: + + + + + + + local port: + + + + + + + false + + + + 60 + 0 + + + + Disconnect + + + + + + + true + + + + 0 + 0 + + + + 127.0.0.1 + + + + + + + sim port + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + 40200 + + + 5 + + + + + + + + 60 + 0 + + + + Transmit + + + + + + + false + + + + 60 + 0 + + + + Stop + + + + + + + + + 0 + + + + raw data + + + + + + + Terminal + 10 + + + + + + + + + channels + + + + 0 + + + 9 + + + + + send data + + + + 6 + + + 9 + + + 0 + + + 3 + + + + + true + + + answer on recieve + + + true + + + + + + + true + + + auto send + + + false + + + + + + + + + + Flight mode + + + + 6 + + + 9 + + + 0 + + + 3 + + + + + 6 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 1 + + + + + + + + + + Armed state + + + + 6 + + + 9 + + + 0 + + + 3 + + + + + Disarmed + + + true + + + + + + + Arming + + + + + + + Armed + + + + + + + + + + Channels + + + + 9 + + + 0 + + + 9 + + + 3 + + + 3 + + + + + CH1 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + CH2 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + CH3 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + CH4 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + CH5 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + CH6 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + Ch7 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + Ch8 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + Ch9 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + Ch10 + + + Qt::AlignCenter + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 0 + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + -511 + + + 512 + + + 16 + + + 32 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 128 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro index 58475b05f..132fbe8ee 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro @@ -1,27 +1,5 @@ -TEMPLATE = lib -TARGET = HITLv2 -QT += network -include(../../openpilotgcsplugin.pri) -include(hitlv2_dependencies.pri) -HEADERS += \ - aerosimrc.h \ - hitlv2configuration.h \ - hitlv2factory.h \ - hitlv2gadget.h \ - hitlv2optionspage.h \ - hitlv2plugin.h \ - hitlv2widget.h \ - simulatorv2.h -SOURCES += \ - aerosimrc.cpp \ - hitlv2configuration.cpp \ - hitlv2factory.cpp \ - hitlv2gadget.cpp \ - hitlv2optionspage.cpp \ - hitlv2plugin.cpp \ - hitlv2widget.cpp \ - simulatorv2.cpp -OTHER_FILES += hitlv2.pluginspec -FORMS += \ - hitlv2optionspage.ui \ - hitlv2widget.ui +TEMPLATE = subdirs + +SUBDIRS = plugin aerosimrc + +plugin.file = plugin.pro diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp index 890742e41..5977e5220 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlconfiguration.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2configuration.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h index dfac80ddf..3e6a96df6 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlconfiguration.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2configuration.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp index 6e6f1a42e..c9e52ebb4 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlfactory.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2factory.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "hitlv2factory.h" #include "hitlv2widget.h" #include "hitlv2gadget.h" diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h index b4142eeed..cfa91750d 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlfactory.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2factory.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp index de22d121b..b114cbde5 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitl.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2gadget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "hitlv2gadget.h" #include "hitlv2widget.h" #include "hitlv2configuration.h" diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h index 0e4fd1a80..45302abb8 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitl.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2gadget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp index 5b88785ad..280ccf030 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitloptionspage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2optionspage.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h index 5c8d33f59..dbfe028bc 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitloptionspage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2optionspage.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp index f0ee2d07a..c63ba5c86 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file mapplugin.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2plugin.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "hitlv2plugin.h" #include "hitlv2factory.h" #include diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h index e68129bd4..3e83915b3 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file browserplugin.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2plugin.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp index 55d14f735..8933d7748 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlwidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2widget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "hitlv2widget.h" #include "ui_hitlv2widget.h" #include diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h index 78f3e9405..6cf1c66c7 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file hitlwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file hitlv2widget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/plugin.pro b/ground/openpilotgcs/src/plugins/hitlv2/plugin.pro new file mode 100644 index 000000000..2d375e426 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/hitlv2/plugin.pro @@ -0,0 +1,32 @@ +TEMPLATE = lib +TARGET = HITLv2 +QT += network + +include(../../openpilotgcsplugin.pri) +include(hitlv2_dependencies.pri) + +HEADERS += \ + aerosimrc.h \ + hitlv2configuration.h \ + hitlv2factory.h \ + hitlv2gadget.h \ + hitlv2optionspage.h \ + hitlv2plugin.h \ + hitlv2widget.h \ + simulatorv2.h + +SOURCES += \ + aerosimrc.cpp \ + hitlv2configuration.cpp \ + hitlv2factory.cpp \ + hitlv2gadget.cpp \ + hitlv2optionspage.cpp \ + hitlv2plugin.cpp \ + hitlv2widget.cpp \ + simulatorv2.cpp + +FORMS += \ + hitlv2optionspage.ui \ + hitlv2widget.ui + +OTHER_FILES += hitlv2.pluginspec diff --git a/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp b/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp index c4c698689..bc5e0b0b1 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp +++ b/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file simulator.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file simulatorv2.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h b/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h index 6a0a9f008..445358a22 100644 --- a/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h +++ b/ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file simulator.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file simulatorv2.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012. * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup HITLPlugin HITL Plugin + * @addtogroup HITLPlugin HITLv2 Plugin * @{ - * @brief The Hardware In The Loop plugin + * @brief The Hardware In The Loop plugin version 2 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro index bfe2342b3..720d36ebd 100755 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro @@ -52,6 +52,8 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \ $$UAVOBJECT_SYNTHETICS/gpsposition.h \ $$UAVOBJECT_SYNTHETICS/gpstime.h \ $$UAVOBJECT_SYNTHETICS/gpssatellites.h \ + $$UAVOBJECT_SYNTHETICS/gpssettings.h \ + $$UAVOBJECT_SYNTHETICS/gpsvelocity.h \ $$UAVOBJECT_SYNTHETICS/positionactual.h \ $$UAVOBJECT_SYNTHETICS/flightbatterystate.h \ $$UAVOBJECT_SYNTHETICS/homelocation.h \ @@ -112,6 +114,8 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \ $$UAVOBJECT_SYNTHETICS/gpsposition.cpp \ $$UAVOBJECT_SYNTHETICS/gpstime.cpp \ $$UAVOBJECT_SYNTHETICS/gpssatellites.cpp \ + $$UAVOBJECT_SYNTHETICS/gpssettings.cpp \ + $$UAVOBJECT_SYNTHETICS/gpsvelocity.cpp \ $$UAVOBJECT_SYNTHETICS/positionactual.cpp \ $$UAVOBJECT_SYNTHETICS/flightbatterystate.cpp \ $$UAVOBJECT_SYNTHETICS/homelocation.cpp \ diff --git a/make/winx86/README.txt b/make/winx86/README.txt index 17477d098..3bc070ee1 100644 --- a/make/winx86/README.txt +++ b/make/winx86/README.txt @@ -33,7 +33,7 @@ It is expected that you have the following tools installed into the listed locations (but any other locations are fine as well): - Python in C:\Python27 - - QtSDK in C:\Qt\2010.05 or C:\QtSDK (depending on SDK version) + - QtSDK in C:\QtSDK (depending on SDK version) - CodeSourcery G++ in %ProgramFiles%\CodeSourcery\Sourcery G++ Lite - msysGit in %ProgramFiles%\Git - Unicode NSIS in %ProgramFiles%\NSIS\Unicode @@ -190,8 +190,8 @@ This set of scripts uses the MSYS package included into the msysGit distribution and MinGW make included into the QtSDK package. The sh.cmd, shell_script.reg and this README.txt files were written -by Oleg Semyonov (os-openpilot-org@os-propo.info) for the OpenPilot -project and are licensed under CC-BY-SA terms: +by Oleg Semyonov (os@openpilot.org) for the OpenPilot project and +are licensed under CC-BY-SA terms: http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/make/winx86/cmd/sh.cmd b/make/winx86/cmd/sh.cmd index 480044ab7..d9e74033b 100644 --- a/make/winx86/cmd/sh.cmd +++ b/make/winx86/cmd/sh.cmd @@ -54,12 +54,8 @@ set NOT_FOUND= set PATH_DIRS= call :which MSYSGIT "%ProgramFiles%\Git\bin" git.exe -rem These two lines for qt-sdk-win-opensource-2010.05.exe: -call :which QTMINGW "C:\Qt\2010.05\mingw\bin" mingw32-make.exe -call :which QTSDK "C:\Qt\2010.05\qt\bin" qmake.exe -rem These two lines for Qt_SDK_Win_offline_v1_1_1_en.exe: -rem call :which QTMINGW "C:\QtSDK\mingw\bin" mingw32-make.exe -rem call :which QTSDK "C:\QtSDK\Desktop\Qt\4.7.3\mingw\bin" qmake.exe +call :which QTMINGW "C:\QtSDK\mingw\bin" mingw32-make.exe +call :which QTSDK "C:\QtSDK\Desktop\Qt\4.8.1\mingw\bin" qmake.exe call :which CODESOURCERY "%ProgramFiles%\CodeSourcery\Sourcery G++ Lite\bin" cs-make.exe call :which PYTHON "C:\Python27" python.exe call :which UNSIS "%ProgramFiles%\NSIS\Unicode" makensis.exe diff --git a/package/winx86/openpilotgcs.nsi b/package/winx86/openpilotgcs.nsi index 363760ec0..2a032870d 100644 --- a/package/winx86/openpilotgcs.nsi +++ b/package/winx86/openpilotgcs.nsi @@ -38,6 +38,7 @@ !define NSIS_DATA_TREE "." !define GCS_BUILD_TREE "..\..\build\ground\openpilotgcs" !define UAVO_SYNTH_TREE "..\..\build\uavobject-synthetics" + !define AEROSIMRC_TREE "..\..\build\ground\AeroSIM-RC" ; Default installation folder InstallDir "$PROGRAMFILES\OpenPilot" @@ -161,7 +162,7 @@ Section "Core files" InSecCore SectionEnd ; Copy GCS plugins -Section "Plugins" InSecPlugins +Section "-Plugins" InSecPlugins SectionIn RO SetOutPath "$INSTDIR\lib\openpilotgcs\plugins" File /r "${GCS_BUILD_TREE}\lib\openpilotgcs\plugins\*.dll" @@ -169,7 +170,7 @@ Section "Plugins" InSecPlugins SectionEnd ; Copy GCS resources -Section "Resources" InSecResources +Section "-Resources" InSecResources SetOutPath "$INSTDIR\share\openpilotgcs\diagrams" File /r "${GCS_BUILD_TREE}\share\openpilotgcs\diagrams\*" SetOutPath "$INSTDIR\share\openpilotgcs\dials" @@ -183,14 +184,14 @@ Section "Resources" InSecResources SectionEnd ; Copy Notify plugin sound files -Section "Sound files" InSecSounds +Section "-Sound files" InSecSounds SetOutPath "$INSTDIR\share\openpilotgcs\sounds" File /r "${GCS_BUILD_TREE}\share\openpilotgcs\sounds\*" SectionEnd ; Copy localization files ; Disabled until GCS source is stable and properly localized -Section "Localization" InSecLocalization +Section "-Localization" InSecLocalization SetOutPath "$INSTDIR\share\openpilotgcs\translations" ; File /r "${GCS_BUILD_TREE}\share\openpilotgcs\translations\openpilotgcs_*.qm" File /r "${GCS_BUILD_TREE}\share\openpilotgcs\translations\qt_*.qm" @@ -229,6 +230,12 @@ Section "CDC driver" InSecInstallDrivers ExecWait '"$PLUGINSDIR\dpinst.exe" /lm /path "$INSTDIR\drivers"' SectionEnd +; AeroSimRC plugin files +Section "AeroSimRC plugin" InSecAeroSimRC + SetOutPath "$INSTDIR\misc\AeroSIM-RC" + File /r "${AEROSIMRC_TREE}\*" +SectionEnd + Section "Shortcuts" InSecShortcuts ; Create desktop and start menu shortcuts SetOutPath "$INSTDIR" @@ -277,6 +284,7 @@ SectionEnd !insertmacro MUI_DESCRIPTION_TEXT ${InSecUtilities} $(DESC_InSecUtilities) !insertmacro MUI_DESCRIPTION_TEXT ${InSecDrivers} $(DESC_InSecDrivers) !insertmacro MUI_DESCRIPTION_TEXT ${InSecInstallDrivers} $(DESC_InSecInstallDrivers) + !insertmacro MUI_DESCRIPTION_TEXT ${InSecAeroSimRC} $(DESC_InSecAeroSimRC) !insertmacro MUI_DESCRIPTION_TEXT ${InSecShortcuts} $(DESC_InSecShortcuts) !insertmacro MUI_FUNCTION_DESCRIPTION_END @@ -301,6 +309,7 @@ Section "un.OpenPilot GCS" UnSecProgram RMDir /r /rebootok "$INSTDIR\firmware" RMDir /r /rebootok "$INSTDIR\utilities" RMDir /r /rebootok "$INSTDIR\drivers" + RMDir /r /rebootok "$INSTDIR\misc" Delete /rebootok "$INSTDIR\HISTORY.txt" Delete /rebootok "$INSTDIR\Uninstall.exe" diff --git a/package/winx86/translations/strings_de.nsh b/package/winx86/translations/strings_de.nsh index 234a1fe3a..71ee8c489 100644 --- a/package/winx86/translations/strings_de.nsh +++ b/package/winx86/translations/strings_de.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_GERMAN} "OpenPilot firmware binaries." LangString DESC_InSecUtilities ${LANG_GERMAN} "OpenPilot Dienstprogramme (Matlab Log Parser)." LangString DESC_InSecDrivers ${LANG_GERMAN} "OpenPilot Hardware Treiberdateien (optionaler OpenPilot CDC Treiber)." - LangString DESC_InSecInstallDrivers ${LANG_GERMAN} "Installiere OpenPilot CDC Treiber (optional)." + LangString DESC_InSecInstallDrivers ${LANG_GERMAN} "OpenPilot CDC Treiber (optional)." + LangString DESC_InSecAeroSimRC ${LANG_GERMAN} "AeroSimRC plugin files with sample configuration." LangString DESC_InSecShortcuts ${LANG_GERMAN} "Installiere Verknüpfungen unter Startmenü->Anwendungen." ;-------------------------------- diff --git a/package/winx86/translations/strings_en.nsh b/package/winx86/translations/strings_en.nsh index 3e640ad4d..e8aa794b0 100644 --- a/package/winx86/translations/strings_en.nsh +++ b/package/winx86/translations/strings_en.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_ENGLISH} "OpenPilot firmware binaries." LangString DESC_InSecUtilities ${LANG_ENGLISH} "OpenPilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_ENGLISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." - LangString DESC_InSecInstallDrivers ${LANG_ENGLISH} "Install OpenPilot CDC driver (optional)." + LangString DESC_InSecInstallDrivers ${LANG_ENGLISH} "Optional OpenPilot CDC driver (virtual USB COM port)." + LangString DESC_InSecAeroSimRC ${LANG_ENGLISH} "AeroSimRC plugin files with sample configuration." LangString DESC_InSecShortcuts ${LANG_ENGLISH} "Install application start menu shortcuts." ;-------------------------------- diff --git a/package/winx86/translations/strings_es.nsh b/package/winx86/translations/strings_es.nsh index 21aeb31d4..6ac59f0d8 100644 --- a/package/winx86/translations/strings_es.nsh +++ b/package/winx86/translations/strings_es.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_SPANISH} "OpenPilot firmware binaries." LangString DESC_InSecUtilities ${LANG_SPANISH} "OpenPilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_SPANISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." - LangString DESC_InSecInstallDrivers ${LANG_SPANISH} "Install OpenPilot CDC driver (optional)." + LangString DESC_InSecInstallDrivers ${LANG_SPANISH} "Optional OpenPilot CDC driver (virtual USB COM port)." + LangString DESC_InSecAeroSimRC ${LANG_SPANISH} "AeroSimRC plugin files with sample configuration." LangString DESC_InSecShortcuts ${LANG_SPANISH} "Instalar accesos directos de la aplicación (menú inicio y escritorio)." ;-------------------------------- diff --git a/package/winx86/translations/strings_fr.nsh b/package/winx86/translations/strings_fr.nsh index 3b1c9efb0..c0919405e 100644 --- a/package/winx86/translations/strings_fr.nsh +++ b/package/winx86/translations/strings_fr.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_FRENCH} "OpenPilot firmware binaries." LangString DESC_InSecUtilities ${LANG_FRENCH} "OpenPilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_FRENCH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." - LangString DESC_InSecInstallDrivers ${LANG_FRENCH} "Install OpenPilot CDC driver (optional)." + LangString DESC_InSecInstallDrivers ${LANG_FRENCH} "Optional OpenPilot CDC driver (virtual USB COM port)." + LangString DESC_InSecAeroSimRC ${LANG_FRENCH} "AeroSimRC plugin files with sample configuration." LangString DESC_InSecShortcuts ${LANG_FRENCH} "Installer les raccourcis dans le menu démarrer." ;-------------------------------- diff --git a/package/winx86/translations/strings_ru.nsh b/package/winx86/translations/strings_ru.nsh index f62e708d2..0aa90b31a 100644 --- a/package/winx86/translations/strings_ru.nsh +++ b/package/winx86/translations/strings_ru.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_RUSSIAN} "Файлы прошивок OpenPilot." LangString DESC_InSecUtilities ${LANG_RUSSIAN} "Утилиты (конвертор логов для Matlab)." LangString DESC_InSecDrivers ${LANG_RUSSIAN} "Файлы драйверов (опциональный драйвер CDC порта)." - LangString DESC_InSecInstallDrivers ${LANG_RUSSIAN} "Установка опционального OpenPilot CDC драйвера." + LangString DESC_InSecInstallDrivers ${LANG_RUSSIAN} "Опциональный OpenPilot CDC драйвер (виртуальный USB COM порт)." + LangString DESC_InSecAeroSimRC ${LANG_RUSSIAN} "Файлы плагина для симулятора AeroSimRC с примером конфигурации." LangString DESC_InSecShortcuts ${LANG_RUSSIAN} "Установка ярлыков для приложения." ;-------------------------------- diff --git a/package/winx86/translations/strings_zh_CN.nsh b/package/winx86/translations/strings_zh_CN.nsh index 5eff43762..50d867223 100644 --- a/package/winx86/translations/strings_zh_CN.nsh +++ b/package/winx86/translations/strings_zh_CN.nsh @@ -33,7 +33,8 @@ LangString DESC_InSecFirmware ${LANG_TRADCHINESE} "OpenPilot firmware binaries." LangString DESC_InSecUtilities ${LANG_TRADCHINESE} "OpenPilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_TRADCHINESE} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." - LangString DESC_InSecInstallDrivers ${LANG_TRADCHINESE} "Install OpenPilot CDC driver (optional)." + LangString DESC_InSecInstallDrivers ${LANG_TRADCHINESE} "Optional OpenPilot CDC driver (virtual USB COM port)." + LangString DESC_InSecAeroSimRC ${LANG_TRADCHINESE} "AeroSimRC plugin files with sample configuration." LangString DESC_InSecShortcuts ${LANG_TRADCHINESE} "安装开始菜单的快捷方式." ;-------------------------------- diff --git a/shared/uavobjectdefinition/gpssettings.xml b/shared/uavobjectdefinition/gpssettings.xml new file mode 100644 index 000000000..5c38f43fe --- /dev/null +++ b/shared/uavobjectdefinition/gpssettings.xml @@ -0,0 +1,10 @@ + + + Settings for the GPS + + + + + + + diff --git a/shared/uavobjectdefinition/gpsvelocity.xml b/shared/uavobjectdefinition/gpsvelocity.xml new file mode 100644 index 000000000..8673463a8 --- /dev/null +++ b/shared/uavobjectdefinition/gpsvelocity.xml @@ -0,0 +1,12 @@ + + + Raw GPS data from @ref GPSModule. + + + + + + + + +