1 3. controlling robot car by wireless sensor the ultimate objective of the project is to control...

24
1 3. Controlling Robot Car by Wireless Sensor The ultimate objective of the project is to control the car motion using the steering wheel The only connection between the steering wheel and car racing system is the wireless marker attached to it We have to make use of the marker data to control the car motion Department of ELECTRONIC AND INFORMATION ENGINEERING 3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun Reference: 1. J.M. Hart, Windows System Programming, 3rd Ed., Addison-Wesley, 2005, Ch.7, 12

Post on 19-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

1

3. Controlling Robot Car by Wireless Sensor

The ultimate objective of the project is to control the car motion using the steering wheel

The only connection between the steering wheel and car racing system is the wireless marker attached to it

We have to make use of the marker data to control the car motion

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

Reference:1. J.M. Hart, Windows System Programming, 3rd Ed., Addison-Wesley,

2005, Ch.7, 12

2

Problem of the Previous Program The markers’ data are obtained by calling the

function Latus::UpdatePO() In the previous program, Latus::UpdatePO() are

called inside the functions EIE330ProjectApp::renderInfo and EIE330ProjectApp::processCalculation()

The above 2 functions will be called by Ogre only when it updates the screen

If the graphics is complex, the update rate can be very slow, e.g. 20 frames/sec or slower

It means that the markers’ data can only be obtained in such a slow rate

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

3

Ogre main program

processCalculation(){ : mLatus::UpdatePO() :}

Update screen

renderInfo(){ : mLatus::UpdatePO() :}

Finish update screen

:

If the screen is updated once per 100ms, markers’ data can only be obtained in the same rate, i.e. once per 100ms

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

4

Solution - Multithreading

Ogre main program

processCalculation(){ :}

Update screen

Finish update screen

:

renderInfo() { :}

Routine A

UpdatePO() { :}

Get Markers’ data

Finish

:

Routine B

Routine A and B run at the same time(virtually)

5

Processes and Threads In Windows, usually a process will be generated when an

application is executed When an application is executed m times, m processes will be

generated, each with a different process ID A Windows process contains its own independent virtual address

space with both code and data Each process contains one or more independently execution

unit, called threads The Windows thread is the basic executable unit A process can

Create new threads within the processes Create new, independent processes Manage communication and synchronization between these

objects

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

6

A Process And Its Threads

Windows

Winword

Process 1

Notepad

Process 2

Winword

Process 3

Excel

Process 4

Process 5

Threads

Lab3

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

7

Why Threads? In normal execution, a program always needs to wait

Wait for user input, wait for screen display, wait for file access, etc.

It is unwise to require programs to execute one after the finish of another Program B can make use of the waiting time of program A to

start its execution as long as program B is not waiting for the result from program A

It was first proposed to achieve this by having multiple processes However, it was soon found that the overhead (e.g. the time

required) for switching between processes is very high Besides, processes are not tightly coupled to one another, it is

difficult to share resources, such as open files They motivate the idea of further dividing a process into smaller

units, i.e. threads

8

A computer has only one CPU, which can execute one program at a time

Hence, in reality, threads are not executing at the same time, but alternatively one after the other

For a multithreading system, a thread has at least the following three states:

Ready Running

Sleeping

Start execution

Finish execution

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

How Threads Are Executed?

9

Ready state– All threads that are ready to execute but without

the CPU are at the ready state– If there is only 1 CPU in the system, all threads

except one are at the ready state

Running state– The thread that actually possesses the CPU is

at the running state– If there is only 1 CPU in the system, at most

there is only one thread is at the running state

Sleeping state– The process that is waiting for other resources,

e.g. I/O or a preset time, is at the sleeping stateDepartment of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

10

Threads will alternatively get into the CPU one after the other (called the round robin scheme)

At the time that a thread is selected to be “in” the CPU– It goes from ready state to running state

After that, it will be swapped out– It goes from running state back to ready state

Or it may due to the waiting of a preset time– It goes from running state to sleeping state

When time-up– It goes from sleeping state to ready state

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

11

Implementation - CreateThreadHANDLE CreateThread (

LPSECURITY_ATTRIBUTES lpsa,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddr,

LPVOID lpvThreadParm,

DWORD dwCreationFlag,

LPDWORD lpThreadId );

HANDLE mThread; // Handle to threadDWORD mThreadId; // Use to store the thread idUpdateParaStruct *pUPS = new UpdateParaStruct;

// Define a structure to store passing parametersmThread = CreateThread(NULL, 0, RunningUpdateThread,

(LPVOID)pUPS, 0, &mThreadId);

Example

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

12

CreateThread Parameters

Input parameters lpsa – A pointer to a security attribute structure. It determines

whether the returned handle can be inherited by child processes. If

lpsa is NULL, the handle cannot be inherited dwStackSize – Indicate thread’s stack size. Use 0 for default size lpStartAddr – A pointer to the function to be executed. For our

example, the function RunningUpdateThread will be executed. RunningUpdateThread() should be defined as follows:

DWORD WINAPI RunningUpdateThread (LPVOID parameter){

:}

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

13

CreateThread Parameters

lpvThreadParm – A pointer passed as the thread argument. For our example, the pUPS pointer, i.e. the pointer of the structure UpdateThreadStruct, is passed to the thread function.

dwCreationFlag – indicate the readiness of the thread. If 0, means that the thread is ready to run immediately

lpThreadId – A pointer to a DWORD that receives the new thread’s identifier. The system will fill in it with the thread ID

CreateThread will return the handle to the thread created. A NULL handle value indicates a failure

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

14

Passing Parameters to Thread

A thread function only accepts one input parameter, i.e. lpvThreadParm

If more than one parameters are to be passed to a thread function, the most convenient way is to put them in a struct and pass its pointer, e.g.

struct UpdateParaStruct // For passing 2 data to the Update thread{

Latus *pL;bool *pExit;

};Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

15

Receive the Passed Parameters

When the thread function receives this pointer, it should first tell the function what kind of pointer it is

Then retrieve the parameters stored in the structure

DWORD WINAPI RunningUpdateThread (LPVOID parameter){ UpdateParaStruct * pUPS = (UpdateParaStruct *) parameter;

Latus *pLatus = pUPS->pL;bool *pExit = pUPS->pExit;:

}

16

To Control the Execution Rate of a Thread

To control the execution rate, the simplest way is to force the thread to “sleep” for some timeDWORD WINAPI RunningUpdateThread (LPVOID parameter){ UpdateParaStruct * pUPS = (UpdateParaStruct *) parameter;

Latus *pLatus = pUPS->pL;bool *pExit = pUPS->pExit;

while (true){ pLatus->UpdatePO();

Sleep(10); // Force to sleep for 10msec}

return 0; }

For the about thread, assume the other part of the program uses negligible amount of time, the execution rate of this thread is approximately once per 10msec

For the about thread, assume the other part of the program uses negligible amount of time, the execution rate of this thread is approximately once per 10msec

17

How a Thread Terminates

Most common way: A thread terminates itself by returning from the

thread function using the exit code as the return value

DWORD WINAPI RunningUpdateThread (LPVOID parameter){ :

:return 0; //exit code = 0//Never return 259 since it is equal to the

// constant STILL_ACTIVE, which is used to// indicate the thread is still active

}

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

18

How to Know if a Thread is Still Alive

We can check if a thread is still alive by calling GetExitCodeThread(), e.g.

HANDLE hThread; // Handle to threadDWORD ThreadId; // Use to store the thread idUpdateParaStruct *pUPS = new UpdateParaStruct;

hThread = CreateThread(NULL, 0, StartPlayer, (LPVOID)pUPS, 0, &ThreadId);

:DWORD exitCode;if(GetExitCodeThread(hThread, (LPDWORD)&exitCode))

std::cout << exitCode << std::endl;//GetExitCodeThread will return nonzero if successful// The exit code is stored in exitCode

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

19

Force a Thread to Terminate The simplest way is to call the function TerminateThread(), but many side effects

Another way is to let the thread function to check frequently a shared variable which can be modified by the thread outside DWORD WINAPI RunningUpdateThread (LPVOID parameter){ UpdateParaStruct * pUPS = (UpdateParaStruct *) parameter;

Latus *pLatus = pUPS->pL;bool *pExit = pUPS->pExit;

while (!(*pExit)){ :}

return 0; }

Assume pExit is a pointer of a shared variable which will be updated by a thread outside. If that thread wants this thread to terminate, it just needs to change such variable to TRUE

Assume pExit is a pointer of a shared variable which will be updated by a thread outside. If that thread wants this thread to terminate, it just needs to change such variable to TRUE

20Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

Thread A Thread B

CreateThread(… &Exit … )

bool Exit = false; &Exit

if Exit == false

if Exit == true

return 0; // terminate

bool Exit = true;

21

Software Architecture for Lab 3

2 flag Exit of Pointerobj Game of Pointerobj Latus of Pointer

Thread 2Thread 1

Screen Update

Thread 3

EIE330ProjectApp RunningUpdateThread

RunningActionThread

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

Latus

Exit 1Exit 2

Latus

Exit 1Exit 2

&UpdateParaStruct

&ActionParaStruct

mLatus->UpdatePO()

mLatus->Analysis()

mLatus->Action()

GameGame

1 flag Exit of Pointer

obj Latus of Pointer

mLatusmGame

22

Analysis()

After receiving the markers’ data, we should analyze the data to determine the kind of action we should perform

The analysis is supposed to be done in a function Latus::Analysis() which should be called after each call to UpdatePO()

The analysis result should be put in an array of ActionStruct structs, each struct has 2 fields

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun

23

Array of ActionStruct

1 0

4 0

3 0

ActionStruct mActionTable[3]

mActionTable[0]

mActionTable[1]

mActionTable[2]

type data

• Based on the analysis result, a number should be put by the function Latus::Analysis() to the type of an ActionStruct to indicate the kind of action to be performed.

• E.g.type = 1 go forwardtype = 2 go backwardtype = 3 turn righttype = 4 turn left

• For some actions, you may want to provide additional data

• Put it in the data field

• In some cases, you may want to define a sequence of operations for each analysis result

• Do it by filling in all 3 structs

• For some actions, you may want to provide additional data

• Put it in the data field

• In some cases, you may want to define a sequence of operations for each analysis result

• Do it by filling in all 3 structs

24

Action()

After the action table is filled, the function Latus::Action() should be called to carry out the operations defined in the table one by one

Since the car motion is much slower than the data received from the markers, the function Action() can be called in a much slower rate

A separated thread is used to called Action() – called in thread function RunningActionThread()

The rate of execution of this thread should match with the command execution rate of Mindstorms

Department of ELECTRONIC AND INFORMATION ENGINEERING

3. Controlling Robot Car by Wireless Sensor by Dr Daniel Lun