1 / 25

M. Smith Electrical Engineering, University of Calgary Smithmr @ ucalgary

Developing a multi-thread Simulation of GPS system You’ll only need to add the threads – all functions (except correlation( )) provided. M. Smith Electrical Engineering, University of Calgary Smithmr @ ucalgary.ca. Tackled today. Why bother with a GPS example of a multi-tasking DSP problem?

nasim-white
Download Presentation

M. Smith Electrical Engineering, University of Calgary Smithmr @ ucalgary

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Developing a multi-thread Simulation of GPS systemYou’ll only need to add the threads – all functions (except correlation( )) provided M. Smith Electrical Engineering, University of Calgary Smithmr @ ucalgary.ca

  2. Tackled today • Why bother with a GPS example of a multi-tasking DSP problem? • Prototype of working product • Explanation of the provided functions • Tests are provided so you can test out your assembly code versions of the correlation functions. • Lab. 4 and Take home quiz 4 • How are they interlinked?

  3. Why bother? • Learn the basics of programming DSP within real time operation system constraints • Interesting Basic concepts to understand GPS functionality • Ability to easily visualize work load • Basic C++ correlation (provided by me) (Lab. 4) • FFT correlation (provided by Analog as part of C++ library (THQ4) • Assembly FIR algorithm modified for correlation (Lab. 4 using Lab 3 code provided by you) • Use of CLU XCORR instruction (THQ4 -- Hints from Analog, myself and Trevor) • Research side • Allows me to test out the E-TDD tool set in RTOS environment on embedded system, and gain personal familiarity with problems of doing so.

  4. GPS Positioning Concepts • For now make 2 assumptions: • We know the distance to each satellite • We know where each satellite is • Require 3 satellites for a 3-D position in this “ideal” scenario • Requires 4 satellites to account for local receiver clock drift. (1)

  5. GPS Signal Structure • Each satellite transmits 2 carrier frequencies referred to as L1 (1575 MHz) and L2 (1227 MHz) • Each carrier frequency is BPSK modulated with a unique PRN (pseudo random number) code • The PRN code on L1 is called CA code (coarse acquisition), The PRN code on L2 is called P code (precise) • CA code takes 1 ms for full PRN transmission at 1MHz chip (bit) rate. P code takes 1.5 s for full PRN transmission at ~10MHz chip rate • Also modulated on each carrier is 50 Hz data that includes the current position of the satellite

  6. Determining Time • Use the PRN code to determine time • Use time to determine distance to the satellite distance = speed of light * time (1)

  7. Algorithms to Find PRN Phase • Time-domain Cross correlation: 1/N∑x1 (n) * x2(n) • Coding equivalent to FIR filter, but need to filter N sets of data, each shifted by one data point • Correlation of perfectly matching signals gives a maximum value • Correlation of 2 random data sequences tends to 0 • PRN code from different satellites are designed to correlate to 0. • Frequency domain correlation: 1/N F-1[X1(k)X2(k)] where F-1 is the inverse Discrete Fourier Transform and the X’s are the Discrete Fourier Transforms of two sequences D

  8. Lab. 4 – Parts 1, 2 and 3 – done as pre-laboratory tasks – about 1 hour • Part 1 -- Create an Initialization Thread • Use VDK::Sleep(200) sleep as a work load • Part 2 – Launch (create) Satellite Receiver Tasks as free running tasks • Use VDK::Sleep(X) as a work load • ClearReceiverThread X = 100 • ReceiveSatellite1 X = 10 • ReceiveSatellite2 X = 20 • ReceiveSatellite3 X = 30 • Part 3 – Add semaphores to get satellite tasks running in proper time sequences

  9. Lab. 4 – Continued – details to be added • Part 4 -- Add Satellite Receiver Tasks Payloads • Download payload code from the web – code provided • Part 5 – Generate E-TTD tests for correlation function designed using your existing FIR filter code • Part 6 – Add analysis and reporting threads • Part 7 – adjust task priorities to make realistic and working • Demo and code hand-in with minor write-up

  10. Lab. 4 – Adding payloads to the threads • Thread set to receive signals from satellites • Simulation – Clear receiveBuffer. Add satelliteX’s PRN signal stream to receiveBuffer based on satellite location and speed. • Functions and their tests provided • Thread set to analyze received signal • Correlate information in receiveBuffer with satelliteX PRN stream to see if signal from satellite is present or not. • Analysis functions and their tests provided • Correlation function tests provided • Thread set to report on satellite status • ErrorX means that signal to satellite signal X was lost

  11. Final result – VDK Thread Picture Satellite thread generates signal into receiveBuffer Analysis thread – long execution time – each tick = 0.05 ms

  12. Satellite signal “received” into receiveBuffer Clear Add Add Add Startbuffer Sat1 Sat2 Sat3 Analysis

  13. Analysis errors can occur Errors occur – here one satellite is active but algorithm gets confused. Length of PRN too smallChoice of PRN poor – rand( ) poor?

  14. Satellite moving in and out of range

  15. InitializationThread::Run() InitializationThread::Run() { VDK::CreateThread(kReceiverControlThread); VDK::CreateThread(kAnalysisThread); VDK::CreateThread(kError1); VDK::CreateThread(kError2); VDK::CreateThread(kError3); VDK::CreateThread(kReportThread); VDK::CreateThread(kReceiverBufferClear); VDK::CreateThread(kReceive1Satellite); VDK::CreateThread(kReceive2Satellite); VDK::CreateThread(kReceive3Satellite); while (1) { VDK::PostSemaphore(kCaptureSignalSTART); VDK::Sleep(1500); if (VDK::GetUptime( ) > 20000) exit(0); } } You cancut-and-pastethis code from the slide PROVIDED your thread namesare the same as mine Order of creationchanges the waythings look inVDK HISTORYwindow

  16. void ReceiverControlThread::Run() // You’ll need to add #include “Satellite.h” // Generate a PRN sequence Warning -- big problems with the rand( ) generator const int prn_length = TEST_PRN_LENGTH; InitializeSatelliteData(prn_length); SetSatelliteVelocity(2, 60); SetSatelliteLocation(2, 0); while (1) { VDK::PendSemaphore(kCaptureSignalSTART, 0); VDK::PostSemaphore(kReceiverBufferClearSTART); VDK::PendSemaphore(kReceiverBufferClearDONE, 0); VDK::PostSemaphore(kReceiver1SatelliteSTART); VDK::PendSemaphore(kReceiver1SatelliteDONE, 0); VDK::PostSemaphore(kReceiver2SatelliteSTART); VDK::PendSemaphore(kReceiver2SatelliteDONE, 0); VDK::PostSemaphore(kReceiver3SatelliteSTART); VDK::PendSemaphore(kReceiver3SatelliteDONE, 0); VDK::PostSemaphore(kAnalysisSTART); VDK::PendSemaphore(kAnalysisDONE, 0); VDK::PostSemaphore(kCaptureSignalDONE); }

  17. ReceiverBufferClear::Run() #include "Satellite.h" // ReceiverBufferClear Run Function (ReceiverBufferClear's main{}) void ReceiverBufferClear::Run() { while (1) { // TODO - Put the thread's "main" body HERE VDK::PendSemaphore(kReceiverBufferClearSTART, 0); ClearReceiveBuffer( ); VDK::PostSemaphore(kReceiverBufferClearDONE); // Use a "break" instruction to exit the "while (1)" loop } // TODO - Put the thread's exit from "main" HERE // A thread is automatically Destroyed when it exits its run function }

  18. Adding satellite data void Receive2Satellite::Run() { // Data not added from this satellite while (1) { VDK::PendSemaphore(kReceiver2SatelliteSTART, 0); // TransferSatelliteDataToReceiveBuffer(1); VDK::PostSemaphore(kReceiver2SatelliteDONE); } } void Receive3Satellite::Run() { // Data added while (1) { VDK::PendSemaphore(kReceiver3SatelliteSTART, 0); TransferSatelliteDataToReceiveBuffer(2); VDK::PostSemaphore(kReceiver3SatelliteDONE); } }

  19. AnalysisThread::Run() void AnalysisThread::Run() { bool valid_results; while (1) { // TODO - Put the thread's "main" body HERE VDK::PendSemaphore(kAnalysisSTART, 0); AnalyseReceiveBuffer( ); valid_results = ValidateResults( ); if (!valid_results) { VDK::PostSemaphore(kReportSTART); VDK::PendSemaphore(kReportDONE, 0); } VDK::PostSemaphore(kAnalysisDONE); } }

  20. void ReportThread::Run( ) void ReportThread::Run() { while (1) { VDK::PendSemaphore(kReportSTART, 0); if ((satelliteActive[0] != MYsatelliteActive[0]) || (satelliteLocation[0] != MYsatelliteLocation[0])) VDK::PostSemaphore(kSatellite0LOST); if ((satelliteActive[1] != MYsatelliteActive[1]) || (satelliteLocation[1] != MYsatelliteLocation[1])) VDK::PostSemaphore(kSatellite0LOST); if ((satelliteActive[2] != MYsatelliteActive[2]) || (satelliteLocation[2] != MYsatelliteLocation[2])) VDK::PostSemaphore(kSatellite0LOST); VDK::PostSemaphore(kSatellite1LOST); VDK::PostSemaphore(kSatellite2LOST); VDK::PostSemaphore(kReportDONE); } } Just spotted a BUG

  21. What you’ll need to modify void CorrelateAlongReceiverBuffer(int *satellitePRN, int array_size, int *correlation_result){ for (int i = 0; i < RECEIVE_BUFFER_LENGTH; i++) correlation_result[i] = 0; for (int result_index = 0; result_index < RECEIVE_BUFFER_LENGTH - array_size; result_index++) { int sum = 0; for (int sum_index = 0; sum_index < array_size; sum_index++) sum = sum + satellitePRN[sum_index] * receiveBuffer[sum_index + result_index]; correlation_result[result_index] = sum; } }

  22. Provided “Satellite.h” #ifdef DECLARE_SATELLITE_VARIABLES #define EXTERN #else #define EXTERN extern #endif #define RECEIVE_BUFFER_LENGTH 256 EXTERN int receiveBuffer[RECEIVE_BUFFER_LENGTH]; void ClearReceiveBuffer(void); #define NUM_SATELLITES 3 #define MAX_PRN_LENGTH 128 #define TEST_PRN_LENGTH 128 // Generate a pseudo-random number sequence // Warning -- big problems with the rand( ) generator // when generating random bits -- (rand ( ) >> X ) % 2 #define SATELLITE_SEED 0x12397 EXTERN pm int satellitePRN[NUM_SATELLITES][MAX_PRN_LENGTH]; EXTERN pm bool satelliteActive[NUM_SATELLITES]; EXTERN pm int satelliteLocation[NUM_SATELLITES]; EXTERN pm int satelliteNextLocation[NUM_SATELLITES]; EXTERN pm int satelliteVelocity[NUM_SATELLITES]; EXTERN pm int MYsatelliteLocation[NUM_SATELLITES]; EXTERN pm bool MYsatelliteActive[NUM_SATELLITES]; EXTERN pm int MYsatelliteNextLocation[NUM_SATELLITES]; EXTERN pm int MYsatelliteVelocity[NUM_SATELLITES];

  23. Provided “Satellite.h” void TransferSatelliteDataToReceiveBuffer(int which_satellite); bool InitializeSatelliteData(int prn_length); void SetSatelliteVelocity(int which_satellite, int which_speed); void SetSatelliteLocation(int which_satellite, int which_distance); int GetSatelliteVelocity(int which_satellite); int GetSatelliteLocation(int which_satellite); bool InitializeMYSatelliteData(void); void SetMYSatelliteVelocity(int which_satellite, int which_speed); void SetMYSatelliteLocation(int which_satellite, int which_distance); int GetMYSatelliteVelocity(int which_satellite); int GetMYSatelliteLocation(int which_satellite); void CrossCorrelate(int *first, int *second, int *correlation_result, int array_size); void CorrelateAlongReceiverBuffer(int *satellitePRN, int array_size, int *correlation_result); int MaximumLocation(int *correlation_result, int array_size); int MaximumValue(int *correlation_result, int array_size); bool ValidateResults(void); void AnalyseReceiveBuffer(void); int CalculateCorrelationRange(void); int CalculateCorrelationAverage(void)

  24. Provided Tests Examples TEST(CrossCorrelationTest, DEVELOPER_TEST) { TEST_LEVEL(9); int first[ARRAY_SIZE] = {1, 0, 0, 0, 0, 0, 0, 0}; int second[ARRAY_SIZE] = {0, 1, 0, 0, 0, 0, 0, 0}; int third[ARRAY_SIZE] = {0, 0, 1, 0, 0, 0, 0, 0}; int correlation_result[ARRAY_SIZE]; int maximum_location; CrossCorrelate(first, first, correlation_result, ARRAY_SIZE); maximum_location = MaximumLocation(correlation_result, ARRAY_SIZE); CHECK_EQUAL(maximum_location, 0); CrossCorrelate(first, second, correlation_result, ARRAY_SIZE); maximum_location = MaximumLocation(correlation_result, ARRAY_SIZE); CHECK_EQUAL(maximum_location, 1); etc. ……..}

  25. Tackled today • Why bother with a GPS example of a multi-tasking DSP problem? • Prototype of working product • Explanation of the provided functions • Tests are provided so you can test out your assembly code versions of the correlation functions. • Lab. 4 and Take home quiz 4 • How are they interlinked?

More Related