Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPS Driver #50

Open
richarthurs opened this issue Mar 4, 2018 · 4 comments
Open

GPS Driver #50

richarthurs opened this issue Mar 4, 2018 · 4 comments
Assignees

Comments

@richarthurs
Copy link
Contributor

richarthurs commented Mar 4, 2018

The GPS communicates over a UART. It has a system of commands for configuring it and getting data out from it.

It is possible to put the GPS into NMEA mode. This is a standard message format, allowing us to leverage existing GPS libraries, such as tinygps/tinynmea, so this is probably a good idea.

Tasks:

  • (AODCS TEAM) figure out an appropriate configuration for the gps (ex: baud rate starts at 9600 but should go to 115200 to deal with the large amount of data). Determine which commands need to be sent for this
  • ability to reset the GPS (SFUSat command).
  • function to set NMEA mode
  • RTOS task to get and log GPS data
  • examine commands that might give us error status or health monitoring of the GPS

Most of the details (which specific commands to send to the GPS) should/will be figured out by the AODCS team. We write functions to send out the appropriate GPS commands to do a specific thing (get location, reset, etc.), and we hook those up to the existing command system so they can be executed during a mission.

http://docs.novatel.com/OEM7/Content/PDFs/OEM7_Commands_Logs_Manual.pdf

@richarthurs
Copy link
Contributor Author

richarthurs commented Apr 21, 2018

GPS will communicate over UART, and we'll use the second UART (called SCI2 in halcogen). It can be enabled by checking Enable SCI2 driver (SCILIN: LIN in SCI compatibility mode) in the driver enable tab

Then, the regular sciX family of functions can be used to talk to the GPS, and the SCI base register should be sciREG2

@richarthurs
Copy link
Contributor Author

  1. enable SCI/LIN mode as mentioned in the comment above. Generate code.
  2. create sfu_gps.h and .c
  3. Implement a function to send a command to the GPS. This will call the existing sciSend functions from halcogen. Your function will be similar to serialSendln in that it will need to loop over a buffer and send individual characters out.
  4. Start some abstraction. Create a function to reset the GPS, which will likely involve sending several individual GPS commands from the function in step 3. Consult the GPS data sheet for the commands to send.
  5. Write a function to receive data from the GPS. Again, this will use functions from halcogen such as sciReceiveByte.
  6. With read and write implemented, write another function to test full communication with the GPS. Look at the GPS data sheet, there is probably a command to return the part number (or similar). Add calls to send the appropriate command and then to receive the data back from it.

sci.c and sci.h in platform-obc-v0.4/source will be helpful, as will our existing serial functions.

This video has background on configuring SCI (UART) https://training.ti.com/hercules-how-tutorial-using-sci-uart-communication

The exact commands to send the GPS will be determined by AODCS, we just need to be ready to send them once they figure them out.

I'll give you a logic analyzer once some code is written so you can test that it works. We will also try to get the GPS for our testing once we have enough code to be able to use it.

Once send, receive, and a couple of specific functions (get position, reset) are implemented, we'll talk about integration with our command system and telemetry logging.

@richarthurs
Copy link
Contributor Author

richarthurs commented Jun 10, 2018

So @victormleon we managed to get data out of the GPS. I've pushed the code we used for the successful test.

The trick was to stop reading at the # character, or else you will keep getting data out from it repeatedly.

Here are some examples of data we got when there was no GPS lock:

CM1]#BETPOSA,CO10,.0,COARSESTEERING205,2406.000,4020,b1f6,14;ISFFIENTS,OE,000000000,0.0000000,0.00,0.00,WGS80.00000000,0000,""0.000,0.000,,0,0,00,00,00,00*3726a98

[COM1#BESTPOS,O10,.0,COASESTEERING,20052382.000,02420,b1f6,14307;UFICNTSNNE0.000000,.0000000,0000.00,WGS40.00,0.000.0000",000,0.0001,0,0,0000,00,00*44f08b2f

And here's an example of some good data:

[COM1#STPOS,M1,0,45,ARSETEERING2005,54.0,024c020,b1f6,140;IUFFICIENT_OBS,SINL,49.18747297-122.84971791218904,-19.8000WS86.495.26,4.71,""000,50.00,0,0,,000,00,00e8a3f

These results came from the log bestposa onetime 1 command.

Next up is to figure out how to parse this data as it comes in. Counting commas is probably a good way to discard data until we get to the coordinate section 49.18747297-122.84971791218904. If altitude is probably a good thing to keep as well ... not sure if that's in this data frame or not.

You will need to be able to handle locked and unlocked GPS states. If there is no lock, we should just set 0,0 as the position. For easier testing, you might want to try onlinegdb or another quick way to run C. To simulate the data coming in, you could loop through the data attached above, one character at a time and run your parser logic on each character.

The GPS data sheet probably has more details on how to parse the data. Or, since the GPS can use NMEA mode, figure out which command to issue to read NMEA-formatted data. Once that's done, there are lots of NMEA parser implementations out there that we could use.

liquiddandruff added a commit that referenced this issue Jun 10, 2018
Setup:
- OBC/RF board set 1 compiled with STX strobe in rfTxTestSequence().
- OBC/RF board set 2 compiled with SRX strobe in rfTxTestSequence().
- In UART prompt, enter on both sets: > task resume 10
- Set 1 sample output:
...
radio task (0x0)
S 0x3d
 < 0x0f
tx_underflowed:no tx_numbytes:0
S 0x3d
 < 0x0f
TX FIFO_BYTES_AVAILABLE: 0xf
S 0xbd
 < 0x00
RX FIFO_BYTES_AVAILABLE: 0x0
S 0x3d
 < 0x0f
62 Bytes Radio TX FIFO written
AFTER: tx_underflowed:no tx_numbytes:62
S 0x35
 < 0x02
STX strobed...
S 0x3d
 < 0x24
StatusByte: 0x24
radio task (0x0)
S 0x3d
 < 0x0f
tx_underflowed:no tx_numbytes:0
S 0x3d
 < 0x0f
TX FIFO_BYTES_AVAILABLE: 0xf
S 0xbd
 < 0x00
RX FIFO_BYTES_AVAILABLE: 0x0
S 0x3d
 < 0x0f
62 Bytes Radio TX FIFO written
AFTER: tx_underflowed:no tx_numbytes:62
S 0x35
 < 0x02
STX strobed...
S 0x3d
 < 0x24
StatusByte: 0x24
radio task (0x0)
S 0x3d
 < 0x0f
tx_underflowed:no tx_numbytes:0
S 0x3d
 < 0x0f
TX FIFO_BYTES_AVAILABLE: 0xf
S 0xbd
 < 0x00
RX FIFO_BYTES_AVAILABLE: 0x0
S 0x3d
 < 0x0f
62 Bytes Radio TX FIFO written
AFTER: tx_underflowed:no tx_numbytes:62
S 0x35
 < 0x02
STX strobed...
S 0x3d
 < 0x24
StatusByte: 0x24

- Set 2 sample output:
...
radio task (0x0)
S 0x3d
< 0x02
tx_underflowed:no tx_numbytes:62
S 0x3d
< 0x02
TX FIFO_BYTES_AVAILABLE: 0x2
S 0xbd
< 0x0f
RX FIFO_BYTES_AVAILABLE: 0xf
S 0x3d
< 0x02
Radio did not write
AFTER: tx_underflowed:no tx_numbytes:62
S 0x34
< 0x02
STX strobed...
S 0x3d
< 0x12
StatusByte: 0x12
RX Byte #0: 3e
RX Byte #1: 10
RX Byte #2: 02
RX Byte #3: 03
RX Byte #4: 04
RX Byte #5: 05
RX Byte #6: 06
RX Byte #7: 07
RX Byte #8: 08
RX Byte #9: 09
RX Byte #10: 0a
RX Byte #11: 0b
RX Byte #12: 0c
RX Byte #13: 0d
RX Byte #14: 0e
RX Byte #15: 0f
RX Byte #16: 10
RX Byte #17: 11
RX Byte #18: 12
RX Byte #19: 13
RX Byte #20: 14
RX Byte #21: 15
RX Byte #22: 16
RX Byte #23: 17
RX Byte #24: 18
RX Byte #25: 19
RX Byte #26: 1a
RX Byte #27: 1b
RX Byte #28: 1c
RX Byte #29: 1d
RX Byte #30: 1e
RX Byte #31: 1f
RX Byte #32: 20
RX Byte #33: 21
RX Byte #34: 22
RX Byte #35: 23
RX Byte #36: 24
RX Byte #37: 25
RX Byte #38: 26
RX Byte #39: 27
RX Byte #40: 28
RX Byte #41: 29
RX Byte #42: 2a
RX Byte #43: 2b
RX Byte #44: 2c
RX Byte #45: 2d
RX Byte #46: 2e
RX Byte #47: 2f
RX Byte #48: 30
RX Byte #49: 31
RX Byte #50: 32
RX Byte #51: 33
RX Byte #52: 34
RX Byte #53: 35
RX Byte #54: 36
RX Byte #55: 37
RX Byte #56: 38
RX Byte #57: 39
RX Byte #58: 3a
RX Byte #59: 3b
RX Byte #60: 3c
RX Byte #61: 3d
RX Byte #62: e8
RX Byte #63: ba

Misc:
- Fix calculation of fifo bytes in writeToTxFIFO.
- TODO: readFromRxFIFO changed to always queuering FIFO_RX; change to check only when needed.
- Create IS_STATE macro to check state easily.
@richarthurs
Copy link
Contributor Author

The balloon GPS will work a little differently from the satellite GPS. They just constantly send NMEA sentences once per second. So the driver will need to change a bit:

  • in sfu_uart.c, sciNotification() is the ISR callback. You should modify it so that runs the existing code if the sci that is passed in is sciREG (to support existing functionality), or if sciLINREG is the source, it will forward the characters into a GPS receive queue.

  • have a task take the characters in off the receive queue

  • you may want to place them into a large buffer (several hundred characters), and once a large number of characters come in, run through the buffer and look for the start of an NMEA sentence. From there, you can parse it out. There may be better ways to do this, and looking at the code for a library such as tinyGPS may help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants