GPS Version String

iOS Apps and Games for the AR.Drone. General Android discussions.
Post Reply
stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

GPS Version String

Post by stu54 » 20 Jun 2014, 19:12

I have made my own GPS module following instructions in another thread. However, the AR Drone 2.0 I have won't recognize the SW Version number as correct so it tries to update the firmware (which it can't do with my GPS).

Can anyone tell me the correct SIRF software version string I should return that will satisfy the AR Drone
when I use FreeFlight 2.4.10?

I tried GSD4e_4.1.2-P6 but that didn't do it.

Kyrt
Strange wobble
Posts: 241
Joined: 10 Jun 2013, 12:49
Drone Type: AR.Drone 2

Re: GPS Version String

Post by Kyrt » 02 Jul 2014, 12:44

Isn't there an option in freeflight to disable updating of GPS firmware?

What actually happens when it fails to update? I mean, does it stop it from working?

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 02 Jul 2014, 15:57

I did turn off the update attempt but the AR Drone does not use the GPS data since it thinks the version is not up to date. However, it sends GPS data out on MAVLINK with no problems. The FreeFlight software just does not recognize the GPS hardware or software version as valid. That's why I think the version issues has to do with FreeFlight and not with the firmware running on the AR Drone processor. Unfortunately, even though FreeFlight is supposed to be open source, the source that comes with the Parrot SDK is several releases old and does not have the GPS capability. If I had the latest Android source I could see what info FreeFlight is looking for that would make it use the GPS.

pawelsky
Serious flight time
Posts: 1272
Joined: 02 Aug 2012, 22:01
Drone Type: Bebop
Location: Poland
Contact:

Re: GPS Version String

Post by pawelsky » 02 Jul 2014, 20:40

stu54 wrote:I did turn off the update attempt but the AR Drone does not use the GPS data since it thinks the version is not up to date. However, it sends GPS data out on MAVLINK with no problems. The FreeFlight software just does not recognize the GPS hardware or software version as valid.
How do you know that FF does not use the GPS data? What exactly do you see in FF (other than the update attempt)?

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 02 Jul 2014, 21:19

I believe if FF recognizes the GPS it will enable the GPS functions, like waypoints and maps. Also, on the "about" screen in settings I can see the number of satellites but all of the GPS version info is grayed out.

pawelsky
Serious flight time
Posts: 1272
Joined: 02 Aug 2012, 22:01
Drone Type: Bebop
Location: Poland
Contact:

Re: GPS Version String

Post by pawelsky » 02 Jul 2014, 21:31

stu54 wrote:I believe if FF recognizes the GPS it will enable the GPS functions, like waypoints and maps. Also, on the "about" screen in settings I can see the number of satellites but all of the GPS version info is grayed out.
It will only enable the GPS functions when it has a lock (so enough satellites traced).

Are you using the version string that I've provided you in the other thread?

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 02 Jul 2014, 21:55

pawelsky wrote:
stu54 wrote:I believe if FF recognizes the GPS it will enable the GPS functions, like waypoints and maps. Also, on the "about" screen in settings I can see the number of satellites but all of the GPS version info is grayed out.
It will only enable the GPS functions when it has a lock (so enough satellites traced).

Are you using the version string that I've provided you in the other thread?
Yes, I am using the string you gave me. But FF has both a hardware version and software version of the GPS
and the string you gave me may only have the software version. I don't know if FF is expecting another string
with the hardware version and maybe that's the problem. The hardware version shows up as 1.0 and software version as 0.0 and Satellites as 5 (but still grayed out). Even though I have GPS Update turned off in FF, it always gives me a message saying it failed to update the GPS firmware when FF starts.

pawelsky
Serious flight time
Posts: 1272
Joined: 02 Aug 2012, 22:01
Drone Type: Bebop
Location: Poland
Contact:

Re: GPS Version String

Post by pawelsky » 02 Jul 2014, 22:17

stu54 wrote:Yes, I am using the string you gave me. But FF has both a hardware version and software version of the GPS
and the string you gave me may only have the software version. I don't know if FF is expecting another string
with the hardware version and maybe that's the problem. The hardware version shows up as 1.0 and software version as 0.0 and Satellites as 5 (but still grayed out). Even though I have GPS Update turned off in FF, it always gives me a message saying it failed to update the GPS firmware when FF starts.
HW version 1.0 is correct. Share the exact sketch you are using so I can check if everything is correct there.

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 03 Jul 2014, 01:53

Here is the main file. Remember that I use a Ublox 6 GPS so I use the UBX syntax to set it up.
I do my development in Eclipse, not that it should matter. Let me know if you need to see
any other files.

Code: Select all

#include "Arduino.h"
#include "Parrot.h"
#include "AltSoftSerial.h"
#include "TinyGPS.h"
#include "ubx.h"

#define LED 13

//#define USE_SIRF_CHECKSUM	// uncomment to calculate checksum for SiRF messages (e.g. for testing using SiRFDemo) - ignored by AR.Drone
//#define NMEA_GPS_DEBUG	 // to see commands to/from NMEA GPS - for debug only, will not work with AR.Drne in this mode (disables SiRF messages)
//#define GPSECHO

AltSoftSerial gpsSerial;
TinyGPS gps;

int gpsInput;

long lat = 0, lon = 0;
unsigned long date = 0, time = 0, fix_age = 0;
unsigned long alt = 0, speed = 0, course = 0, hdop = 0;
unsigned short numsats = 0;
int year = 0;
byte month = 0, day = 0, hour = 0, minute = 0, second = 0, hundredths = 0;
boolean gpsInitialized;

unsigned char msgId = 0, seq = 0;
unsigned long lastTime = 0;

#define NEL(x) (sizeof(x) / sizeof(x[0]))

unsigned long GPS_BAUDRATES[] = {4800, 9600, 14400, 19200, 38400, 57600, 115200};

// Geodetic Navigation Data - ID 41
unsigned char SIRF_MSG_29[] = {
	0x29,															//	 [0] Message ID
	0x00, 0x00,													//	 [1-2] Nav Valid
	0x00, 0x00,													//	 [3-4] Nav Type
	0x00, 0x00,													//	 [5-6] Extended Week Number
	0x00, 0x00, 0x00, 0x00,										//	[7-10] Time of Week (sec x1000)
	0x00, 0x00,													// [11-12] UTC Year
	0x00,															//	[13] UTC Month
	0x00,															//	[14] UTC Day
	0x00,															//	[15] UTC Hour
	0x00,															//	[16] UTC Minute
	0x00, 0x00,													// [17-18] UTC Second (sec x1000)
	0x00, 0x00, 0x00, 0x00,										// [19-22] Satellite ID list
	0x00, 0x00, 0x00, 0x00,										// [23-26] Latitude (deg x10000000)
	0x00, 0x00, 0x00, 0x00,										// [27-30] Longitude (deg x10000000)
	0x00, 0x00, 0x00, 0x00,										// [31-34] Altitude from Ellipsoid (m x100)
	0x00, 0x00, 0x00, 0x00,										// [35-38] Altitude from MSL (m x100)
	0x15,															//	[39] Map Datum
	0x00, 0x00,													// [40-41] Speed Over Ground - SOG (m/s x100)
	0x00, 0x00,													// [42-43] Course Over Ground - COG, True (deg cw from true N x100)
	0x00, 0x00,													// [44-45] Magnetic Variation (not implemented)
	0x00, 0x00,													// [46-47] Climb Rate (m/2 x100)
	0x00, 0x00,													// [48-49] Heading Rate (deg/s x100)
	0x00, 0x00, 0x00, 0x00,										// [50-53] Estimated Horizontal Position Error (m x100)
	0x00, 0x00, 0x00, 0x00,										// [54-57] Estimated Vertical Position Error (m x100)
	0x00, 0x00, 0x00, 0x00,										// [58-61] Estimated Time Error (sec x100)
	0x00, 0x00,													// [62-63] Estimated Horizontal Velocity Error (m/s x100)
	0x00, 0x00, 0x00, 0x00,										// [64-67] Clock Bias (m x100)
	0x00, 0x00, 0x00, 0x00,										// [68-71] Clock Bias Error (m x100)
	0x00, 0x00, 0x00, 0x00,										// [72-75] Clock Drift (m/s x100)
	0x00, 0x00, 0x00, 0x00,										// [76-79] Clock Drift Error (m/s x100)
	0x00, 0x00, 0x00, 0x00,										// [80-83] Distance - travelled since reset (m)
	0x00, 0x00,													// [84-85] Distance Error (m)
	0x00, 0x00,													// [86-87] Heading Error (deg x100)
	0x00,														//	[88] Sumber of SVs in fix
	0x00,														//	[89] HDOP
	0x00														//	[90] Additional Mode Info
};

// Command Acknowledgement - ID 11
unsigned char SIRF_MSG_0B[] = {
	0x0B,														//	 [0] Message ID
	0x00														//	 [1] Ack ID
};

// Software Version String - ID 06
//unsigned char SIRF_MSG_06[] =	"\x06XXX-XXX-4.1.2-P6";
//unsigned char SIRF_MSG_06[] =	"\x06GSD4e_4.1.2-P6";
unsigned char SIRF_MSG_06[] = "\x06\x21\x01GSD4e_4.1.2-P6 F+ 08/14/2013 226\x00\x00";


void send_sirf(unsigned char payload[], unsigned char len)
{
	unsigned short chcksm = 0;

	Serial.write(0xA0); Serial.write(0xA2);					 // start sequence
	Serial.write(len >> 8); Serial.write(len & 0xFF);		 // length
	for(int i = 0; i < len; i++) {
		Serial.write(payload[i]);								 // payload
#ifdef USE_SIRF_CHECKSUM
		chcksm = (chcksm + payload[i]) & 0x7FFF;				// checksum calculation
#endif
	}
	Serial.write(chcksm >> 8); Serial.write(chcksm & 0xFF);	 // checksum (may be fake, not checked by Drone)
	Serial.write(0xB0); Serial.write(0xB3);					 // end sequence
}

void send_sirf_ack(unsigned char id)
{
	SIRF_MSG_0B[1] = id;
	send_sirf(SIRF_MSG_0B, NEL(SIRF_MSG_0B));
}

void send_nmea(const char* nmea)
{
	unsigned char chcksm = 0;

	gpsSerial.write('$');
#ifdef NMEA_GPS_DEBUG
	Serial.write(">$");
#endif
	while(*nmea) {
		gpsSerial.write(*nmea);
#ifdef NMEA_GPS_DEBUG
		Serial.write(*nmea);
#endif
		chcksm = chcksm ^ *nmea++;
	}
	gpsSerial.write('*');
	if(chcksm < 16)
		gpsSerial.write('0');
	gpsSerial.print(chcksm, HEX);
	gpsSerial.print("\r\n");
	gpsSerial.flush();
#ifdef NMEA_GPS_DEBUG
	Serial.write('*');
	if(chcksm < 16)
		Serial.write('0');
	Serial.print(chcksm, HEX);
	Serial.print("\r\n");
#endif
}

void processGpsInput()
{
	gps.get_datetime(&date, &time, &fix_age);
	if((date != TinyGPS::GPS_INVALID_DATE) && (time != TinyGPS::GPS_INVALID_TIME))
		gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &fix_age);
	else {
		year = 0;
		month = 0;
		day = 0;
		hour = 0;
		minute = 0;
		second = 0;
		hundredths = 0;
	}

	gps.get_position(&lat, &lon, &fix_age);
	if((lat != TinyGPS::GPS_INVALID_ANGLE) && (lon != TinyGPS::GPS_INVALID_ANGLE)) {
		alt = gps.altitude();
		speed = gps.speed();
		course = gps.course();
		hdop = gps.hdop();
		numsats = gps.satellites();
	} else {
		lat = 0;
		lon = 0;
		alt = 0;
		speed = 0;
		course = 0;
		hdop = 0;
		numsats = 0;
	}
}

void processDroneInput( int droneInput )
{
	if((droneInput == 0xA0) && (seq == 0))
		seq = 1;
	else if((droneInput == 0xA2) && (seq == 1))
		seq = 2;
	else if((droneInput >= 0) && (seq == 2))
		seq = 3;
	else if((droneInput >= 0) && (seq == 3))
		seq = 4;
	else if((droneInput >= 0) && (seq == 4)) {
		msgId = droneInput;
		seq = 5;
	}
	else if((droneInput == 0xB0) && (seq == 5))
		seq = 6;
	else if((droneInput == 0xB3) && (seq == 6))
		seq = 0;
}

unsigned short htons(unsigned short v)
{
	union { unsigned short w; unsigned char b[2]; } h, n;
	h.w = v;
	n.b[0] = h.b[1];
	n.b[1] = h.b[0];
	return n.w;
}

unsigned long htonl(unsigned long v)
{
	union { unsigned long l; unsigned char b[4]; } h, n;
	h.l = v;
	n.b[0] = h.b[3];
	n.b[1] = h.b[2];
	n.b[2] = h.b[1];
	n.b[3] = h.b[0];
	return n.l;
}

boolean gpsInit()
{
	// We are assuming MTK GPS is used, different configuration strings will be necessary for other GPSes
#ifdef NEVER
	// First set the frequency to 1HZ, enable only RMC and GGA messages and set the baudrate to 38400...
	for(i = 0; i < NEL(GPS_BAUDRATES); i++) {
		gpsSerial.begin(GPS_BAUDRATES[i]);
		delay(50); // small delay to let the serial port initialize
		send_nmea("PMTK220,1000");
		send_nmea("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
		send_nmea("PMTK251,38400");
	}
#endif
	gpsSerial.begin(9600);	// default
	delay(50); // small delay to let the serial port initialize

	// set baud on UART1, enable all protocols in and out
	// don't try to get ack after baud change
	if( !ubx_cfg_prt(1, 0x07, 0x07, 38400, false) )
		return false;
	gpsSerial.end();
	gpsSerial.begin( 38400 );	// default
	delay(50); // small delay to let the serial port initialize

	// 5Hz rate
	if( !ubx_cfg_rate(200, true) )
		return false;

	// SBAS on, WAAS on, SBAS test mode on
	if( !ubx_cfg_sbas(true, true) )
		return false;

	// Pedestrian mode
	if( !ubx_cfg_nav5(3, true) )
		return false;

	// Turn off all messages except GGA and RMC
	// GNS, THS, and VLW are not legal so don't try
	//   to turn them off
	ubx_msg_type_t msg;
	msg.u_class = NMEA_CLASS;
	msg.id = NMEA_ID_GGA;
	if( !ubx_cfg_msg(&msg, true, true) )
		return false;
	msg.id = NMEA_ID_GLL;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_GSA;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_GSV;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_RMC;
	if( !ubx_cfg_msg(&msg, true, true) )
		return false;
	msg.id = NMEA_ID_VTG;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_GRS;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_GST;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_ZDA;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_GBS;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;
	msg.id = NMEA_ID_DTM;
	if( !ubx_cfg_msg(&msg, false, true) )
		return false;

	if( !ubx_cfg_sbas(true, true) )
		return false;

#ifdef NEVER
	// Set Static nav: OFF, SBAS: ON, WAAS: ON, SBAS TEST MODE: ON
	send_nmea("PMTK397,0");
	send_nmea("PMTK313,1");
	send_nmea("PMTK301,2");
	send_nmea("PMTK319,0");
	// Finally set the 5Hz frequency
	send_nmea("PMTK220,200");
#endif
	return true;
}

void log_warn( const char* fmt, ... )
{
	va_list argl;
	char buf[132];

	va_start( argl, fmt );
	vsprintf( buf, fmt, argl );
	va_end( argl );
}

void setup()
{
	Serial.begin(38400);
	gpsInitialized = gpsInit();
//gpsSerial.begin(9600);	// default
//gpsInitialized = true;
	pinMode(LED, OUTPUT);
	digitalWrite(LED, LOW);
}

void loop()
{
#ifdef GPSECHO
	if( gpsInitialized ) {
		if( gpsSerial.available() ) {
			int c = gpsSerial.read();
			Serial.write( c );
		}
		if( Serial.available() ) {
			int c = Serial.read();
			gpsSerial.write( c );
		}
	}
#else
	if( gpsInitialized ) {
		if( gpsSerial.available() ) {
			gpsInput = gpsSerial.read();
#ifdef NMEA_GPS_DEBUG
			Serial.write(gpsInput);
#else
			// encode will return true when valid sentence is parsed
			if( gps.encode(gpsInput) ) {
				digitalWrite(LED, HIGH);
				processGpsInput();
				digitalWrite(LED, LOW);
			}
#endif
		}

		if( Serial.available() ) {
#ifdef NMEA_GPS_DEBUG
			gpsSerial.write(Serial.read());
#else
			processDroneInput(Serial.read());
#endif
		}

#ifndef NMEA_GPS_DEBUG
		if ((seq == 0) && (msgId > 0)) {
			if(msgId == 0x84)
				send_sirf(SIRF_MSG_06, NEL(SIRF_MSG_06));
			send_sirf_ack(msgId);
			msgId = 0;
		} else if ((millis() - lastTime) > 200) {
			lastTime = millis();

			// Prepare and send message 41 (0x29)
			SIRF_MSG_29[2] = (numsats < 5) ? 1 : 0;
			SIRF_MSG_29[3] = (numsats < 5) ? 0 : 2;
			SIRF_MSG_29[4] = (numsats >= 4) ? 4 : numsats;
			*((long *)&SIRF_MSG_29[23]) = htonl(lat * 100);
			*((long *)&SIRF_MSG_29[27]) = htonl(lon * 100);
			*((short *)&SIRF_MSG_29[11]) = htons(year);
			SIRF_MSG_29[13] = month;
			SIRF_MSG_29[14] = day;
			SIRF_MSG_29[15] = hour;
			SIRF_MSG_29[16] = minute;
			*((short *)&SIRF_MSG_29[17]) = htons((int)second * 1000 + (int)hundredths * 10);
			*((long *)&SIRF_MSG_29[35])	= htonl(alt);
			*((short *)&SIRF_MSG_29[40]) = htons(speed * 51);
			*((short *)&SIRF_MSG_29[42]) = htons(course);
			*((long *)&SIRF_MSG_29[50])	= (hdop >= 100) ? htonl((hdop - 100) * 10 + 200) : 0;	// Need to put something here e.g. EHPE = (HDOP - 1) * 10 + 2 (multiply difference from ideal HDOP by 10 and add 2m)
			SIRF_MSG_29[88] = numsats;
			SIRF_MSG_29[89] = hdop / 20;
			send_sirf(SIRF_MSG_29, NEL(SIRF_MSG_29));
		}
#endif
	}
#endif
}

pawelsky
Serious flight time
Posts: 1272
Joined: 02 Aug 2012, 22:01
Drone Type: Bebop
Location: Poland
Contact:

Re: GPS Version String

Post by pawelsky » 03 Jul 2014, 09:00

stu54 wrote:

Code: Select all

void setup()
{
	Serial.begin(38400);          <-------------- should be 115200
	gpsInitialized = gpsInit();
//gpsSerial.begin(9600);	// default
//gpsInitialized = true;
	pinMode(LED, OUTPUT);
	digitalWrite(LED, LOW);
}

Baudrate of the Drone serial port shall be 115200 not 38400

P.S. Not that it matters, but you configure the SBAS twice in your init function.

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 03 Jul 2014, 16:35

Looks like it was the baud rate because now FF recognizes the GPS. But when I am doing the GPS mission planning I don't see the map, although I can see the "google maps" logo on the screen. I expected it to zoom to my current location. I will have to read the instructions for the FF GPS mode since I have not used it before. Hopefully it is not a problem with the Ublox 6 settings.

Thanks for finding the bug!

ok found the problem - I did not have GPS enabled on the phone. Now I see the drone and the map!

stu54
Ready for take off
Posts: 10
Joined: 09 Jun 2014, 04:32
Drone Type: AR.Drone 2

Re: GPS Version String

Post by stu54 » 03 Jul 2014, 17:15

So after all that effort to get the flight recorder to work, I find that FreeFlight has no ability to preplan a flight - it just lets you set a location and fly to it. I am working on adapting someone else's Android flight planner that uses MavLink for better flight planning. Strange thing was that MavLink from the AR Drone had no problems with the baud rate set wrong. It was just FreeFlight. Hmmm...

pawelsky
Serious flight time
Posts: 1272
Joined: 02 Aug 2012, 22:01
Drone Type: Bebop
Location: Poland
Contact:

Re: GPS Version String

Post by pawelsky » 03 Jul 2014, 17:35

stu54 wrote:I am working on adapting someone else's Android flight planner that uses MavLink for better flight planning.
Why don't you just buy an Android app that already does it?

frontline500
Newcomer
Posts: 1
Joined: 10 Oct 2015, 17:12
Drone Type: AR.Drone 2

Re: GPS Version String

Post by frontline500 » 10 Oct 2015, 17:26

stu54 wrote:Here is the main file. Remember that I use a Ublox 6 GPS so I use the UBX syntax to set it up.
I do my development in Eclipse, not that it should matter. Let me know if you need to see
any other files.

Code: Select all

#include "Arduino.h"
#include "Parrot.h"
#include "AltSoftSerial.h"
#include "TinyGPS.h"
#include "ubx.h"
...

stu54, would you mind sharing the rest of the code for your project?

I've purchased a cheap Chinese UBlox 7M clone, which, as it turns out, has a faulty EEPROM. I can configure it in UCenter fine and store the config, unplug, plug back in - it's all still there. The problem is, if I keep it unpowered for more than a couple of hours, it loses all of the configuration parameters and reverts to defaults.

I've tried to put together a UBX configuration module in Arduino, so I can "hot configure" GPS module on startup, but having some problems with UBX command checksums and acknowledgement. You seemed to resolve those issues, but the code you've posted refers to a couple of external header files that I don't have or not sure which version to use. Specifically Parrot.h and ubx.h headers. Would you mind posting those in this thread? I assume the rest of the libraries you use (Arduino, AltSoftSerial and TinyGPS) are the standard ones, is it correct?

If you share your completed project, it would probably help me and other UBlox owners to save several weekends worth of coding and debugging. Thanks in advance.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests