GPS sensor
Moderator: rainer
-
- Posts: 9
- Joined: Sun Jan 24, 2016 9:45 am
- Country: -
Re: GPS sensor
At my version i have downloaded //#define DEBUG_FORCE_VSPEED_TO 123 was comment out
Re: GPS sensor
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
That sounds great,
I've been looking through but I can't figure out how to do it, is the compass heading available too?
I've been looking through but I can't figure out how to do it, is the compass heading available too?
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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...
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...
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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!
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!
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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.
Re: GPS sensor
Thanks for the feedback.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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.
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.
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
"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.
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.
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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
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
Re: GPS sensor
Within 1 hour, I will try to put a new version on github to adjust the delay.
Re: GPS sensor
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)
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)
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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?
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?
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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( ) ;
}
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( ) ;
}
Re: GPS sensor
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
Last edited by kcaldwel on Thu Feb 04, 2016 6:56 pm, edited 2 times in total.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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...
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...
Re: GPS sensor
In order to split GPS data you can use a variable like hubgpsCount and put some condition on it to omit some data.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( ) ;
}
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( ) ;
}
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
Oh of course silly me !!
Thanks mstrens.
I will try that out again soon and see what results are like.
Thanks mstrens.
I will try that out again soon and see what results are like.
Re: GPS sensor
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.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...
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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!
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!
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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.
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.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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.
if i send over t1 or t2 the reading the same.
-
- Posts: 308
- Joined: Fri Nov 08, 2013 9:56 pm
- Country: -
Re: GPS sensor
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( ) ;
}
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( ) ;
}
Re: GPS sensor
I expect that the difference between the 2 protocols is generated by openTx because in oXs I send the same value in both protocols.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.
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 ) ;
Re: GPS sensor
I put a new version with the parameters your asked for.
It contains the code to split GPS data too.
It contains the code to split GPS data too.