Download presentation
Presentation is loading. Please wait.
Published byMaurice White Modified over 6 years ago
1
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 ucalgary.ca 9/21/2018
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? 9/21/2018
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. 9/21/2018
4
GPS Positioning Concepts
(1) 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. 9/21/2018
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 9/21/2018
6
Determining Time Use the PRN code to determine time
(1) Use the PRN code to determine time Use time to determine distance to the satellite distance = speed of light * time 9/21/2018
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 9/21/2018
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 ReceiveSatellite X = 10 ReceiveSatellite X = 20 ReceiveSatellite X = 30 Part 3 – Add semaphores to get satellite tasks running in proper time sequences 9/21/2018
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 9/21/2018
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 9/21/2018
11
Final result – VDK Thread Picture
Satellite thread generates signal into receiveBuffer Analysis thread – long execution time – each tick = 0.05 ms 9/21/2018
12
Satellite signal “received” into receiveBuffer
Clear Add Add Add Start buffer Sat Sat2 Sat Analysis 9/21/2018
13
Analysis errors can occur
Errors occur – here one satellite is active but algorithm gets confused. Length of PRN too small Choice of PRN poor – rand( ) poor? 9/21/2018
14
Satellite moving in and out of range
9/21/2018
15
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 can cut-and-paste this code from the slide PROVIDED your thread names are the same as mine Order of creation changes the way things look in VDK HISTORY window 9/21/2018
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); } 9/21/2018
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 9/21/2018
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 VDK::PendSemaphore(kReceiver3SatelliteSTART, 0); TransferSatelliteDataToReceiveBuffer(2); VDK::PostSemaphore(kReceiver3SatelliteDONE); 9/21/2018
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); 9/21/2018
20
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])) if ((satelliteActive[2] != MYsatelliteActive[2]) || (satelliteLocation[2] != MYsatelliteLocation[2])) VDK::PostSemaphore(kSatellite1LOST); VDK::PostSemaphore(kSatellite2LOST); VDK::PostSemaphore(kReportDONE); } Just spotted a BUG 9/21/2018
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; } 9/21/2018
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]; 9/21/2018
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) 9/21/2018
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); CHECK_EQUAL(maximum_location, 1); etc. …….. } 9/21/2018
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? 9/21/2018
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.