GPS sensor

Development & General Chat for the superb openxvario project.

Moderator: rainer

Post Reply
advancefly
Posts: 9
Joined: Sun Jan 24, 2016 9:45 am
Country: -

Re: GPS sensor

Post by advancefly »

At my version i have downloaded //#define DEBUG_FORCE_VSPEED_TO 123 was comment out

mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

nigelsheffield wrote:Hi,
I just thought I'd update you on my attempt at getting artificial horizon on the pro mini and gy521.
I used the frsky s.port telemetry library and the i2cdevlib, https://github.com/jrowberg/i2cdevlib
Mixed in the 6050 with dmp demo( the one with tea pot demo) and had that output pitch and roll to temp 1 and 2, with no other sensors on that particular arduino., calling the telemetry.send from within the interupt sensing while loop I get really good fast results, does not show when airoplanes inverted though but not a huge deal.
This used 19.9 kb out of 30 so I presume there would not be enough room for GPS and vario code on same pro mini, I think I remember you saying this would not fit.
So I put the openxsensor GPS and IMU on the same s.port input as this and got it to work fully together.
Very pleased with results but still wondering if it would be possible to fit it all on one pro mini.... Down side is I can only use on s.port and not on hub along with the GPS etc which would have been nice to have because as I said before I like the d8r in particular...

Now I just need some flying weather to test all this stuff out, I have not even flown with the GPS or IMU based vario yet.....
Thanks mstrens....

In latest version of oXs (in master branch on github), you can have quite a lot running inside one Arduino pro mini.
When I implement a baro sensor, a GPS, an IMU and SPORT+HUB protocols I get following results
Sketch uses 25,060 bytes (81%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,193 bytes (58%) of dynamic memory, leaving 855 bytes for local variables. Maximum is 2,048 bytes.

This was possible because I rewrite the code for SPORT protocol and I removed a lot from the code I founded for IMU.
So it is still possible to add some voltages and/or current measurement (or PPM, RPM, ...)
Adding an artificial horizon, would be very easy.
Orientation is already available in the quaternion returned by IMU DMP.
Pitch and Roll can easily be calculated from quaternion.
Then you just have to copy pitch and roll in TEST1 and TEST2 (and send them as TEMP1, TMP2 or ACCx.y.z).
It will only be a few lines of code.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

That sounds great,
I've been looking through but I can't figure out how to do it, is the compass heading available too?
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

Currently oXs does not read the compass. This was not needed for a vario.
So, you would have to discard Yaw because I expect that it will not be accurate (due to gyro drift).
Still I presume that Yaw is not important for artificial horizon.
You can calculate pitch and roll using following lines (after gravity has been calculated in function read6050 () in oXs_imu.cpp ):
pitch = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2])); //Pitch
roll = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2])); // Roll
Probably you have to add conversion from rad to deg.

I did not test it.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

thanks i tried adding those lines
after bool read6050() in osx_imu.cpp after gravity calc
but got errors about expected operands etc. seemed to be to do with brackets.
i presume i need to declare pitch and roll as float as i got errors for that too but added this.
sorry my programming skills are very weak lol...

mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

Yes, adding those lines generates a compilation error.
It is because in oXs gravity uses a structure instead of an array and the lines of code I provided where extracted from a program where gravity was in an array.

I just put a new version on github (in master branch) that
- calculates pitch and roll in degre
- put thoses 2 values in TEST_1 and TEST2.
You can put those 2 fields in the telemetry fields that you want (e.g. TEMP1 and TEMP2)

I did not test it. Let me know if it works.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

Yes, it works!
Looks great with this lua script!
http://www.rcgroups.com/forums/showthread.php?t=2271315
I modified the lua script a little to change accel for inputs to temp1 and temp2 and removed a bit of code that looks for IMU heading if speed is under 5, this would be for quads I guess but for gliders GPS heading is fine( unless maybe in a very strong wind where it won't go forwards).

On s.port it updates fast and smooth too, on hub its a little jerky but still usable.
Thanks again!
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

mstrens wrote:I expect that if you use this set up, you will get the data twice a second.
#define INTERVAL_FRAME1 200
#define INTERVAL_FRAME2 400 // used by GPS

This should send each 200 msec a frame (frame 1 and 2 alternating)

Perhaps you can even reduce a little like
#define INTERVAL_FRAME1 150
#define INTERVAL_FRAME2 300 // used by GPS


Testing this with GPS and pitch and roll, the GPS transmition effects the smoothness of the pitch and roll, so either I have fast GPS and jerky pitch roll or slow GPS and smooth pitch roll.
A reasonable compromise was frame1 100 and frame2 400.
I guess this just down to hub data being slower then d16 and nothing can be done but thought I'd report.
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

Thanks for the feedback.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

No problem, note that the GPS effecting the pitch roll is only on hub series, d16 works fine ...
Out of interest would the hub frame rates be changeable during flight or maybe at power up?
For the GPS racing script it would be better to have fast GPS, but for general flying GPS would not need to be fast at all.
I will experiment a bit more today to see how this GPS frame rate effects vario tones as they seem to be not as good as they were were without GPS.
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

I expect that when the frame rate increase above some level, the Rx can't follow and some frames are totally lost.
So it could that above some level the quality of data falls dramatically.

The frame with GPS data is quite long. Perhaps you do not need all GPS data. If so, you could try putting some lines as comment in file oXs_out_frsky.cpp in the function OXS_OUT::SendFrame2()
If GPS frame contains less data, you can probably increase the rate of transmission.

If required, it would be possible to change frame rates. Change it during flight is possible based on PPM signal but the problem is that PPM signal is already used for a lot of other topics (sensitivity, Vspeed switch,...). Using a jumper on an arduino pin and reading the voltage on this pin at startup would be easier.

Another way to increase the troughput could be to change the code in such a way that the delay between 2 frames depends on the length of the first frame. In this case, the setup would be based on a delay per value and on a ratio between frame 1 and frame 2.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

"Another way to increase the troughput could be to change the code in such a way that the delay between 2 frames depends on the length of the first frame. In this case, the setup would be based on a delay per value and on a ratio between frame 1 and frame 2."
This sounds like a good idea,
are the 2 frames synchronized so that when one frame finishes sending the other starts right away ( if it is due to send )?
I will have a look at the gps data to see what i can do without.
thanks Mstrens.
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

The 2 frames are not synchronised.
In fact there are 2 independant tasks (one fill a buffer with the data of frame 1 or frame 2 and another task sent the data in the buffer - in fact it happens in an interrupt).
The current "delay" parameter take care that there is some msec between starting filling data in the buffer. Filling the buffer is very fast (less than 1 mesc).
I could change the delay in such a way that it takes care of the amount of byte previously written in the buffer.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

I tried removing gps speed and heading but only noticed small improvement, not enough to make it worth losing that data.
I think your idea of adjusting the delay may work( but I dont know enough lol).
I presume sending frame2 data has to be done all at once and cant be split like
frame1
frame2(lat)
frame1
frame2(long)
etc
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

Within 1 hour, I will try to put a new version on github to adjust the delay.
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

I put on github (branch master) a new version where the delay between 2 frames depends on the number of bytes to be transmitted.
In file oxs_out_frsky.cpp, you now have 2 parameters (at lines 495):
#define FRAME2_EVERY_N_FRAME1 1 // n means that there is n frame1 after "one" frame2(gps); so here there will 1 frame1 after each frame2
#define MSEC_PER_BYTE 7 // number of msec per byte to transmit; I expect that a value of 7 ms should work; probably it can even be reduced

I checked the signal and with MSEC_PER_BYTE = 10, you have between 1 and 2 frames (1+2) per second.
Reducing the number of data being transmitted, would increase the rate (with the same value of MSEC_PER_BYTE)
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

thanks ,
i found this to be the best setting
#define FRAME2_EVERY_N_FRAME1 3
#define MSEC_PER_BYTE 4

it gives gps every 400ms roughly according to logs which is good enough
vario tones seem ok still logging at between 5 and 10 times per second.
pitch and roll still jerky once gps has lock but seems maybe slightly less erratic then before though not much difference to be honest.
Maybe it is just the fact that it is switching frames and so timing will always be a problem with the slower hub protocol?
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

I had a little play at trying to send gps data in chunks,
not sure if i understand properly but here is what I tried.
it works but not sure if it made any real difference again, I wonder if the rx itself accumulates data for gps and then sends it one big block?
I declared a variable hubgpsCount as 1 and then changed the following.

void OXS_OUT::SendFrame2(){
hubMaxData = 0 ; // reset of number of data to send
// here we fill the buffer with all GPS data
// GPS_lon // longitude in degree with 7 decimals, (neg for S)
// GPS_lat // latitude in degree with 7 decimals, (neg for ?)
// GPS_altitude; // altitude in mm
// GPS_speed_3d; // speed in cm/s
// GPS_speed; // speed in cm/s
// GPS_ground_course ; // degrees with 5 decimals
uint32_t absLongLat = abs(GPS_lat) ;
uint32_t decimalPartOfDegree = (absLongLat % 10000000 );
uint32_t minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 1){
SendValue(FRSKY_USERDATA_GPS_LAT_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Latitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LAT_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Latitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LAT_EW , (uint16_t)(GPS_lat < 0 ? 'S' : 'N')) ;
hubgpsCount ++;}
absLongLat = abs(GPS_lon) ;
decimalPartOfDegree = (absLongLat % 10000000 );
minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 2) {
SendValue(FRSKY_USERDATA_GPS_LONG_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Longitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LONG_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Longitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LONG_EW , (uint16_t)(GPS_lon < 0 ? 'W' : 'E')) ;
hubgpsCount ++;
}
if(hubgpsCount == 3){
SendValue(FRSKY_USERDATA_GPS_ALT_B , (int16_t) GPS_altitude / 1000 ); // Altitude m
SendValue(FRSKY_USERDATA_GPS_ALT_A , (uint16_t) ( (abs(GPS_altitude) % 1000 ) / 10 ) ) ; // Altitude centimeter
hubgpsCount ++;}
#ifdef GPS_SPEED_3D
uint32_t GPSSpeedKnot = GPS_speed_3d * 1944L ; // speed in knots with 5 décimals (1 cm/sec = 0,0194384 knot)
#else
uint32_t GPSSpeedKnot = GPS_speed_2d * 1944L ;
#endif
if (hubgpsCount ==4){
SendValue(FRSKY_USERDATA_GPS_SPEED_B , (uint16_t) ( GPSSpeedKnot / 100000) ) ; // Speed knots
SendValue(FRSKY_USERDATA_GPS_SPEED_A , (uint16_t) ( (GPSSpeedKnot % 100000 ) /1000) ) ; // Speed 2 decimals of knots
SendValue(FRSKY_USERDATA_GPS_CURSE_B , (uint16_t) ( GPS_ground_course / 100000 ) ) ; // Course degrees
SendValue(FRSKY_USERDATA_GPS_CURSE_A , (uint16_t) ( (GPS_ground_course % 100000) / 1000 ) ) ; // Course 2 decimals of degrees
hubgpsCount = 1;}
if( hubMaxData > 0 ) {
sendHubByte(0x5E) ; // End of Frame 2!
setHubNewData( ) ;
}
kcaldwel
Posts: 40
Joined: Wed Mar 12, 2014 7:49 pm
Country: Canada

Re: GPS sensor

Post by kcaldwel »

OXS GPS Connector.JPG
I have now built three OXS vario/altimeter/GPS modules. They are all working great! Thanks to mstrens for all his work.

I found some nice little connectors on eBay with wires on both sides that makes having a connector for the GPS fairly easy. It fits on the board nicely with hot glue:

http://www.ebay.com/itm/161746168876?_t ... EBIDX%3AIT

I have been flying a bit with the system, although we've had a very wet January. I've attached a Google Earth trace of a flight in Dec with just a foamy glider for testing.

Thanks for everyone's help!

Kevin
Attachments
Calypso Dec20_15.png
Last edited by kcaldwel on Thu Feb 04, 2016 6:56 pm, edited 2 times in total.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

Nice one Kevin,
Looks good!

I uploaded a video of the script I am trying out with the pitch and roll and GPS navigation.
Working very well with the x6r .
https://www.youtube.com/watch?v=gwwgY8Oa6vE

This is gonna be great fun when weather allows me to fly!
Thanks mstrens!

I was thinking about the yaw reading from the IMU and wondering if it would be feasible to output that and maybe have it calibrated by GPS every so often when speed is over a certain amount?
What do you think? Worth doing or not really, as I've not tested GPS in real world yet I don't know how well the GPS heading works on its own, I should think it would be good enough though especially at 5hz...
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

nigelsheffield wrote:I had a little play at trying to send gps data in chunks,
not sure if i understand properly but here is what I tried.
it works but not sure if it made any real difference again, I wonder if the rx itself accumulates data for gps and then sends it one big block?
I declared a variable hubgpsCount as 1 and then changed the following.

void OXS_OUT::SendFrame2(){
hubMaxData = 0 ; // reset of number of data to send
// here we fill the buffer with all GPS data
// GPS_lon // longitude in degree with 7 decimals, (neg for S)
// GPS_lat // latitude in degree with 7 decimals, (neg for ?)
// GPS_altitude; // altitude in mm
// GPS_speed_3d; // speed in cm/s
// GPS_speed; // speed in cm/s
// GPS_ground_course ; // degrees with 5 decimals
uint32_t absLongLat = abs(GPS_lat) ;
uint32_t decimalPartOfDegree = (absLongLat % 10000000 );
uint32_t minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 1){
SendValue(FRSKY_USERDATA_GPS_LAT_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Latitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LAT_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Latitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LAT_EW , (uint16_t)(GPS_lat < 0 ? 'S' : 'N')) ;
hubgpsCount ++;}
absLongLat = abs(GPS_lon) ;
decimalPartOfDegree = (absLongLat % 10000000 );
minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 2) {
SendValue(FRSKY_USERDATA_GPS_LONG_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Longitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LONG_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Longitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LONG_EW , (uint16_t)(GPS_lon < 0 ? 'W' : 'E')) ;
hubgpsCount ++;
}
if(hubgpsCount == 3){
SendValue(FRSKY_USERDATA_GPS_ALT_B , (int16_t) GPS_altitude / 1000 ); // Altitude m
SendValue(FRSKY_USERDATA_GPS_ALT_A , (uint16_t) ( (abs(GPS_altitude) % 1000 ) / 10 ) ) ; // Altitude centimeter
hubgpsCount ++;}
#ifdef GPS_SPEED_3D
uint32_t GPSSpeedKnot = GPS_speed_3d * 1944L ; // speed in knots with 5 décimals (1 cm/sec = 0,0194384 knot)
#else
uint32_t GPSSpeedKnot = GPS_speed_2d * 1944L ;
#endif
if (hubgpsCount ==4){
SendValue(FRSKY_USERDATA_GPS_SPEED_B , (uint16_t) ( GPSSpeedKnot / 100000) ) ; // Speed knots
SendValue(FRSKY_USERDATA_GPS_SPEED_A , (uint16_t) ( (GPSSpeedKnot % 100000 ) /1000) ) ; // Speed 2 decimals of knots
SendValue(FRSKY_USERDATA_GPS_CURSE_B , (uint16_t) ( GPS_ground_course / 100000 ) ) ; // Course degrees
SendValue(FRSKY_USERDATA_GPS_CURSE_A , (uint16_t) ( (GPS_ground_course % 100000) / 1000 ) ) ; // Course 2 decimals of degrees
hubgpsCount = 1;}
if( hubMaxData > 0 ) {
sendHubByte(0x5E) ; // End of Frame 2!
setHubNewData( ) ;
}
In order to split GPS data you can use a variable like hubgpsCount and put some condition on it to omit some data.
Still, the way you did it does not provide the expected result because you increase hubgpsCount inside one "if" statement and the next "if" statement checks on the next value.
It means that each time the function is called, all conditions are valid and so, the frame contains all data.
You have to use "else" statement or to increase hubgpsCount only once (and reset it to 1 if it is greater than the max value).
Here some code that applies the second solution.

Code: Select all

void OXS_OUT::SendFrame2(){
  hubMaxData = 0 ; // reset of number of data to send
// here we fill the buffer with all GPS data
// GPS_lon             // longitude in degree with 7 decimals, (neg for S)
// GPS_lat             // latitude   in degree with 7 decimals, (neg for ?)
// GPS_altitude;       // altitude in mm
// GPS_speed_3d;       // speed in cm/s
// GPS_speed;          // speed in cm/s
// GPS_ground_course ; // degrees with 5 decimals
  uint32_t absLongLat = abs(GPS_lat) ;
  uint32_t decimalPartOfDegree = (absLongLat % 10000000 );
  uint32_t minWith7Decimals = decimalPartOfDegree * 60 ;
  if (hubgpsCount == 1){
  SendValue(FRSKY_USERDATA_GPS_LAT_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) +  (minWith7Decimals / 10000000L )) ) ; // Latitude (DDMM)
  SendValue(FRSKY_USERDATA_GPS_LAT_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ;                              // Latitude (.MMMM)
  SendValue(FRSKY_USERDATA_GPS_LAT_EW , (uint16_t)(GPS_lat < 0 ? 'S' : 'N')) ;
 }
  absLongLat = abs(GPS_lon) ;
  decimalPartOfDegree = (absLongLat % 10000000 );
  minWith7Decimals = decimalPartOfDegree * 60 ;
  if (hubgpsCount == 2) {
  SendValue(FRSKY_USERDATA_GPS_LONG_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) +  (minWith7Decimals / 10000000L )) ) ; // Longitude (DDMM)
  SendValue(FRSKY_USERDATA_GPS_LONG_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ;                              // Longitude (.MMMM)
  SendValue(FRSKY_USERDATA_GPS_LONG_EW , (uint16_t)(GPS_lon < 0 ? 'W' : 'E')) ;
    }
  if(hubgpsCount == 3){
  SendValue(FRSKY_USERDATA_GPS_ALT_B ,  (int16_t) GPS_altitude / 1000 );                                                      // Altitude m
  SendValue(FRSKY_USERDATA_GPS_ALT_A , (uint16_t) ( (abs(GPS_altitude) % 1000 ) / 10 ) ) ;                                    // Altitude centimeter
  }
#ifdef GPS_SPEED_3D
  uint32_t GPSSpeedKnot = GPS_speed_3d * 1944L ;                                                                               // speed in knots with 5 décimals (1 cm/sec = 0,0194384 knot)
#else  
  uint32_t GPSSpeedKnot = GPS_speed_2d * 1944L ;
#endif 
if (hubgpsCount ==4){ 
  SendValue(FRSKY_USERDATA_GPS_SPEED_B , (uint16_t) ( GPSSpeedKnot / 100000) ) ;                                              // Speed knots
  SendValue(FRSKY_USERDATA_GPS_SPEED_A , (uint16_t) ( (GPSSpeedKnot % 100000 ) /1000) ) ;                                     // Speed 2 decimals of knots
  SendValue(FRSKY_USERDATA_GPS_CURSE_B , (uint16_t) ( GPS_ground_course / 100000 ) ) ;                                        // Course degrees
  SendValue(FRSKY_USERDATA_GPS_CURSE_A , (uint16_t) ( (GPS_ground_course % 100000) / 1000 ) ) ;                               // Course 2 decimals of degrees
  }
  hubgpsCount ++;
  if ( hubgpsCount > 4) hubgpsCount = 1;
  if( hubMaxData > 0 ) {
    sendHubByte(0x5E) ; // End of Frame 2!
    setHubNewData(  ) ;
  }
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

Oh of course silly me !!
Thanks mstrens.
I will try that out again soon and see what results are like.
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

nigelsheffield wrote:Nice one Kevin,
Looks good!

I uploaded a video of the script I am trying out with the pitch and roll and GPS navigation.
Working very well with the x6r .
https://www.youtube.com/watch?v=gwwgY8Oa6vE

This is gonna be great fun when weather allows me to fly!
Thanks mstrens!

I was thinking about the yaw reading from the IMU and wondering if it would be feasible to output that and maybe have it calibrated by GPS every so often when speed is over a certain amount?
What do you think? Worth doing or not really, as I've not tested GPS in real world yet I don't know how well the GPS heading works on its own, I should think it would be good enough though especially at 5hz...
I expect that with a glider (or a plane) flying at more than e.g. 10 km/h, the course provided by the GPS would give good approximation of yaw.
If this is not good enough then it would be required to use some algorithm in order to merge yaw from Gyro with data from magnetometer.
Still I am not sure that there will enough flash memory in Arduino to achieve it.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

Would just outputting the yaw along with pitch and roll be much impact on memory?
Then I could do any adjustments and algorithms in the taranis in a lua script.
The lua script could take into account the speed and decide if calibration is needed, something like
If speed >10 and 5 seconds has passed since last calibration then apply an offset to the calibrated yaw reading based on the difference between raw yaw reading and GPS heading.
This would if it worked give smoother yaw reading then just GPS and also if speed was slow or reversed even due to head winds winds the calibrated yaw reading would be accurate for a while ...

Like I said I don't know how much this may be useful or not as I have not flown with it...yet!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

Adding yaw does not have a big impact.
I put on github a version which calculates yaw and where test_3 is filled with yaw.
You can test it.
I suggest that Lua script take into account GPS speed AND the fact that GPS course is quite stable. E.g. if you are just circling, it does not make sense to recalibrate yaw.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

Thanks , will test it .
Agreed the GPS needs to be stable perhaps a simple calculation like if GPS course is within a certain value of itself from 5 seconds ago then calibrate IMU heading..... Would need some experimenting but I can display both on taranis display to see if its working or not.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

its working but i notice a difference between hub reading and d16 reading when sending over accx or accz, the d16 goes to 1.7 where the hub goes to .17 max so out by a decimal place.
if i send over t1 or t2 the reading the same.
nigelsheffield
Posts: 308
Joined: Fri Nov 08, 2013 9:56 pm
Country: -

Re: GPS sensor

Post by nigelsheffield »

this works really well for smoothing out the hub data,once gps has lock vario tones are better and pitch roll is smoother then before wihtout splitting gps.
a setting of 1 frame per frame and msec per byte 4 seems perfect.
Can this be added to master as I think its very good improvment.



void OXS_OUT::SendFrame2(){
hubMaxData = 0 ; // reset of number of data to send
// here we fill the buffer with all GPS data
// GPS_lon // longitude in degree with 7 decimals, (neg for S)
// GPS_lat // latitude in degree with 7 decimals, (neg for ?)
// GPS_altitude; // altitude in mm
// GPS_speed_3d; // speed in cm/s
// GPS_speed; // speed in cm/s
// GPS_ground_course ; // degrees with 5 decimals
uint32_t absLongLat = abs(GPS_lat) ;
uint32_t decimalPartOfDegree = (absLongLat % 10000000 );
uint32_t minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 1){
SendValue(FRSKY_USERDATA_GPS_LAT_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Latitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LAT_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Latitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LAT_EW , (uint16_t)(GPS_lat < 0 ? 'S' : 'N')) ;
}
absLongLat = abs(GPS_lon) ;
decimalPartOfDegree = (absLongLat % 10000000 );
minWith7Decimals = decimalPartOfDegree * 60 ;
if (hubgpsCount == 2) {
SendValue(FRSKY_USERDATA_GPS_LONG_B , (uint16_t) (((absLongLat / 10000000L) * 100 ) + (minWith7Decimals / 10000000L )) ) ; // Longitude (DDMM)
SendValue(FRSKY_USERDATA_GPS_LONG_A , (uint16_t) (( minWith7Decimals % 10000000L) / 1000 ) ) ; // Longitude (.MMMM)
SendValue(FRSKY_USERDATA_GPS_LONG_EW , (uint16_t)(GPS_lon < 0 ? 'W' : 'E')) ;
}
if(hubgpsCount == 3){
SendValue(FRSKY_USERDATA_GPS_ALT_B , (int16_t) GPS_altitude / 1000 ); // Altitude m
SendValue(FRSKY_USERDATA_GPS_ALT_A , (uint16_t) ( (abs(GPS_altitude) % 1000 ) / 10 ) ) ; // Altitude centimeter
}
#ifdef GPS_SPEED_3D
uint32_t GPSSpeedKnot = GPS_speed_3d * 1944L ; // speed in knots with 5 décimals (1 cm/sec = 0,0194384 knot)
#else
uint32_t GPSSpeedKnot = GPS_speed_2d * 1944L ;
#endif
if (hubgpsCount ==4){
SendValue(FRSKY_USERDATA_GPS_SPEED_B , (uint16_t) ( GPSSpeedKnot / 100000) ) ; // Speed knots
SendValue(FRSKY_USERDATA_GPS_SPEED_A , (uint16_t) ( (GPSSpeedKnot % 100000 ) /1000) ) ; // Speed 2 decimals of knots
SendValue(FRSKY_USERDATA_GPS_CURSE_B , (uint16_t) ( GPS_ground_course / 100000 ) ) ; // Course degrees
SendValue(FRSKY_USERDATA_GPS_CURSE_A , (uint16_t) ( (GPS_ground_course % 100000) / 1000 ) ) ; // Course 2 decimals of degrees
}
hubgpsCount ++;
if ( hubgpsCount > 4) hubgpsCount = 1;
if( hubMaxData > 0 ) {
sendHubByte(0x5E) ; // End of Frame 2!
setHubNewData( ) ;
}
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

nigelsheffield wrote:its working but i notice a difference between hub reading and d16 reading when sending over accx or accz, the d16 goes to 1.7 where the hub goes to .17 max so out by a decimal place.
if i send over t1 or t2 the reading the same.
I expect that the difference between the 2 protocols is generated by openTx because in oXs I send the same value in both protocols.
Still it should be possible to fix it in oXs.
In order to get the same value, you could multiply the value by 10 in Hub protocol.
This can be done in lines like the next one (in oXs_out_frsky.cpp

Code: Select all

#if defined(ACCX_SOURCE) && ( ACCX_SOURCE == TEST_1)
   SendValue( FRSKY_USERDATA_ACC_X , (int16_t) test1.value) ; // could become SendValue( FRSKY_USERDATA_ACC_X , (int16_t) test1.value * 10 ) ;

mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: GPS sensor

Post by mstrens »

I put a new version with the parameters your asked for.
It contains the code to split GPS data too.

Post Reply

Return to “OpenXVario - an open source vario supported by the open source firmwares!!”