0% found this document useful (0 votes)
47 views70 pages

Akash Kukadiya Graduate Report Fall2012

Uploaded by

Ly Trần
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views70 pages

Akash Kukadiya Graduate Report Fall2012

Uploaded by

Ly Trần
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

CALIFORNIA STATE UNIVERSITY, NORTHRIDGE

AUTONOMOUS INDOOR LOCALIZATION SYSTEM

A graduate project submitted in partial fulfillment of the requirements


For the degree of Masters of Science
in Electrical Engineering

By

Akash Pankajkumar Kukadiya

December 2012
This graduate project of Akash Pankajkumar Kukadiya is approved:

------------------------------------------------------------------ --------------------
Porf. Xiaojun Geng Date

------------------------------------------------------------------ --------------------
Prof. Ichiro Hashimoto Date

------------------------------------------------------------------ ---------------------
Prof. Ronald Mehler, chair Date

California State University, Northridge


ii
ACKNOWLEDGEMENT

I would like to thank Prof. Ronald Mehler as the graduate project advisor. Prof.

Mehler helped me to understand the real challenges to address the problem. Not only did

he provide different approaches, but he has been a source of guidance throughout my

project development and has been support for my financial aid. I also would like to thank

Prof. Xiaojun (Ashley) Geng and Prof. Ichiro Hashimoto as the committee members for

this project. Apart from that, I thank Prof. Ali Amini (ECE Dept. chair) for the extension

of my graduate term to complete my project and Prof. Ramin Roosta for providing

asic/eda lab access.

My special thanks to Robert Santogrossi for providing me with all free major

hardware components needed to accomplish this project.

Lastly, I want to thank my parents for giving their unconditional support and

encouragement towards my present and future endeavors.

iii
TABLE OF CONTENTS

SIGNATURE PAGE……………………………………………………………………ii

ACKNOWLEDGEMENT………………………………………………………………iii

LIST OF FIGURES……………………………………………………………………...v

LIST OF TABLES………………………………………………………………………vii

ABSTRACT…………………………………………………………………………….viii

CHAPTER 1 INTRODUCTION……………………………………………………….1

CHAPTER 2 SYSTEM OVERVIEW ACCORDING TO DEFINED LOCATION…...3

CHAPTER 3 HARDWARE COMPONENTS AND THEIR CONFIGURATION…11

CHAPTER 4 ANTENNA CALIBRATION………………………………………….20

CHAPTER 5 SOFTWARE DEVELOPMENT AND TESTING…………………….36

CONCLUSION…………………………………………………………………………31

REFERANCES…………………………………………………………………………32

APPENDIX……………………………………………………………………………..33

iv
LIST OF FIGURES

Figure 2.1 Outer dimension of Arena……………………………………………………………3

Figure 2.2 Actual arena built form cubes at competition venue…………………………………4

Figure 2.3 strategically mounted two RF station………………………………………………..6

Figure 2.4 System component diagram (“Design of autonomous indoor localization system” by

Robert Santogrossi)………………………………………………………………………………6

Figure 2.5 Tracking algorithm step1……………………………………………………………..8

Figure 2.6 Tracking algorithm step2……………………………………………………………..9

Figure 2.7 Tracking algorithm step3……………………………………………………………..9

Figure 2.8 Tracking algorithm step4……………………………………………………………10

Figure 3.1 select single/multi-processor system………………………………………………...11

Figure 3.2 Microblaze system definition………………………………………………………..12

Figure 3.3 Available peripheral options to be connected with Microblaze……………………..13

Figure 3.4 Embedded system view with selected IP components………………………………14

Figure 3.5 Memory mapped addresses belong to each IP component…………………………..15

Figure 3.6 XBIB-U-DEV-REV 3 board………………………………………………………...16

Figure 3.7 X-CTU setup window……………………………………………………………….17

v
Figure 3.8 Spartan 3e FPGA board with two Xbee pro RF modules connected through RS-232

ports……………………………………………………………………………………………..18

Figure 3.9 Xbee pro RF module in loopback mode…………………………………………….18

Figure 4.1 Parameter configuration window in X-CTU software………………………………21

Figure 4.2 Experiment set up to find received power for variable distance…………………….22

Figure 4.3 Range test……………………………………………………………………………23

Figure 4.4 Reading DB register value…………………………………………………………..23

Figure 4.5 Black colored area from two RF stations shows 3m blind area……………………..24

vi
LIST OF TABLES

Table 4.1 Distance verses Received power……………………………………………………..24

vii
ABSRTACT

Autonomous Indoor Localization System

By

Akash Pankajkumar Kukadiya

Master of Science in Electrical Engineering

The Autonomous indoor localization system is a sub system of the project that

needs to be built in order to compete in the International Aerial Robotics Competition

(IARC), 6th mission. The system helps to locate the flying vehicle in a given indoor

situation. With help from the location data, the moving vehicle can easily navigate and

determine the next desired direction to achieve the goal in the competition. The challenge

of navigation becomes more complex due to several competition criteria. Among them,

one of the criteria is that the interior arrangement of the building is variable. So the

number of obstacles, the materials used as obstacles and the navigation path are subject to

change. Moreover, the navigation system cannot use a GPS system; instead, two wireless

posts are allowed to help the flying vehicle. To address such a problem, several

techniques are workable like calculating the time differential and measuring signal

strength between wireless devices. This project uses signal strength analysis to figure out

the distance between the flying vehicle and the RF station to calculate location into two

dimensions.

viii
CHAPTER 1

INTRODUCTION

The Autonomous Indoor Localization System was developed for utilization in the

International Aerial Robotics Competition (IARC), as a 6th mission to take place in late

summer 2013, which is organized by Association for Unmanned Vehicle Systems

International (AUVSI). This competition takes place every year, and this competition is

now in its 20th year. The objective of this competition is as follows. A fully autonomous

vehicle must be able to maneuver inside a fixed confined area arranged with a variable

number and nature of obstacles like walls and furniture. The vehicle must have

computation capability to maneuver inside the built structure either fully on the vehicle

itself or through communication with remote computers without any human intervention.

The communication between a vehicle and the computer can be unidirectional or

bidirectional. It has been observed that the built structure is generally made from

materials like plastic or paper. It strictly has one square meter entrance and one meter

wide inter-room passages. In the 6th mission, the vehicle must be able to maneuver and

steal an object (flash drive) and replace it with a similar object in order to delay the

detection of the operation. In order to maneuver, the vehicle can communicate with two

RF stations pre-posted inside the given confined area and must not use GPS to locate the

vehicle as per the competition rule guidelines. This paper gives a functional description

and fundamental logic to carry out the navigation computation.

To solve the problem, lets breakdown it in to two simple steps. First, the

computation logic should be able to determine the current location of the moving vehicle

1
inside the built structure. Second, these data should be feedback to help the vehicle to

decide the next possible direction to follow without collision with any structure and find

the desired object. This paper discusses the first part explained here which require both

hardware and software components. Moreover, this paper is in continuation to the system

which was developed and described in the “DESIGE OF AN AUTONOMOUS INDOOR

LOCALIZATION SYSTEM” paper submitted in spring 2011 by Robert Santogrossi at

the college of engineering and computer science, California State University Northridge.

This paper uses a different approach which is described in next chapter of this paper.

However, it uses the same hardware components.

2
CHAPTER 2

SYSTEM OVERVIEW ACCORDING TO DEFINED LOCATION

As per the IARC rules, the competition venue dimensions are crucial to build an

autonomous localization system on the vehicle and determine where the two remote RF

stations need to be placed. Figure 2.1 describes the fixed confined arena.

Figure 2.1 Outer dimension of Arena

As we can see, the arena is 33m x 18m. This area is covered by the 3 meter placement

space, which is the initial placement area for the vehicle. To enter the arena a minimum

of one square meter and maximum of 2.44m window will be placed. Figure 2.2 gives a

more clear idea of an actual arena. The walls of the cubes could be made of Styrofoam

insulation, a thin sheathing material or a heavy paper. These materials will be used to

3
build the 2.44m cubes.

Figure 2.2 Actual arena built form cubes at competition venue

Here, cube arrangement is variable, but the outer dimensions remain the same. Having

this information, we can determine the overall map in which the two RF stations can be

mounted.

To calculate the distance between the vehicle and the RF station, two approaches

have been proposed. The first is to send signals from the vehicle to the RF stations and

send them back, counting the time difference. This approach has been carried out in the

earlier experiment and has a fundamental flaw. Since the area is small to navigate, time

differential is proportionally small between the vehicle and the RF post. In this situation,

we cannot expect reasonable resolution of the system. To calculate the perfect time

differential, the clocks of two RF stations should be synchronous to each other. Also, the

4
clock of the processor (mounted on the vehicle) must be very high. The second is to send

RF signals from the vehicle to the RF stations and receive them back and measure the

received power to determine the distance. This technique involves a number of factors

that affect the received power strength. These factors include the power transmission,

obstacles between devices, antenna orientation, type of antenna used, multipath and

antenna receiving sensitivity. All the factors mentioned here can be overcome accurately

enough, so the second approach has been used.

Transmit power  Here for the given arena; transmitting power should be enough to

cover the extreme points in the arena. The selected RF modules are powerful enough to

cover the arena boundaries.

Obstacles between two devices  This is a fundamental concern, since there could be

any number of walls and other objects which have different power attenuation

coefficient. The concrete walls, human body and different kind of metals have a high

power attenuation coefficient, but they are unlikely to appear in this scenario. The

materials have a low power attenuation coefficient which have been used. As a result, the

power attenuation can be ignored. A few tests have been carried out and are discussed in

chapter four, which suggests low effect on power attenuation for the materials used.

Mutipath  Multipath is a phenomenon where a transmitted radio signal reaches to a

receiver from more than one path because of the reflection for the given geographic

condition. This phenomenon is impossible to avoid, but the question is how severely it

affects reception of the signal.

Antenna orientation and type of antenna  Here the RF modules contain isotropic

antennas. An isotropic antenna has a uniform power pattern in all directions. So, the RF

5
stations do not need to orient in a specific direction. However, the height of the RF

stations is crucial because this project provides the location of the moving vehicle in two

dimensions. In this situation, the RF stations should be place roughly at the same height

as the vehicle maneuvers inside the arena. Figure 2.3 shows how the vehicle maneuvers

roughly in the two dimensional plane, which co-inside with the two RF stations.

Figure 2.3 strategically mounted two RF station

FPGA Development Board

Output Pins

Transceiver Development Board

FPGA

UART / RS232 Port Transceiver

LCD Display Microprocessor UART / Rs232 Port

Transceiver Development Board

UART / Rs232 Port

UART / RS232 Port Transceiver

Transceiver Development Board Transceiver Development Board


Loopback Loopback

UART / RS232 Port Transceiver UART / RS232 Port Transceiver

Figure 2.4 System component diagram (“Design of autonomous indoor localization

system” by Robert Santogrossi)

6
Further we need to fix the reference point (0,0) to one of the given RF stations. After

fulfilling the conditions previously explained, an algorithm has been written as given

below to calculate the distance in two dimensions. To understand the algorithm, consider

Figure 2.4

1. Determine the distance between the vehicle and transceiver A and the distance

between the vehicle and transceiver B.

2. Calculate the interior angle of transceiver A or transceiver B of the generated

imaginary triangle.

3. Calculate the exterior angle of transceiver A or transceiver B of the generated

triangle.

4. Calculate the remaining two sides of the similar triangle.

5. Calculate the ratios of the hypotenuses of the similar triangles and calculate the X and

Y coordinate of the vehicle.

Step by step explanation:

1. Determining the distance between two RF stations which are posted in the two

corners of the building can be done by measuring the received signal strength. For an

accurate measurement, the received power drop per unit distance has a

significant role. So, the RF transceivers must be optimized for the given area. For the

area of 30m x 15m, the diagonal of 33.54m is the longest distance. If the vehicle is

33.54m apart from one of the RF stations, the received power should be the minimum

of the RF station’s receiving capability. The X-bee pro module is capable to measure

-100dBm (0.1 Pico-watt) and store the receiving power in the hex notation which was

used as an RF station. A register is provided in the embedded microcontroller with

7
the wireless transceiver. The register only stores the value of the last successfully

received packet. This value can be read by three different ways.

 The PWM0/RSSI output produces a pulse width providing RSSI level

indication.

 In the AT Command Mode, the value may polled by using the ATDB

command.

 When receiving in the API Mode, a byte in the packet contains the RSSI level.

This paper uses the second method which reads the DB register using the ATDB

command. The method is fully described in the next section. With the help of this

information, antenna calibration had been carried out; in other words, a detailed

experiment had been carried out on the distance verses receiving power. These data had

been used to determine the distance between the vehicle and the RF transceiver station.

9m
A

15m
12m
B

30m

Figure 2.5 Tracking algorithm step1

2. Calculate the interior angle of transceiver A or transceiver B of the generated triangle:

 Angle C in degrees: → ( ) →

8
A’ 9m
53.13°

15m
12m

30m

Figure 2.6 Tracking algorithm step2

3. Calculate the exterior angle of transceiver A or transceiver B of the generated

triangle:

 Angle in degrees:

36.87° 9m

15m
12m
D E

30m

Figure 2.7 Tracking algorithm step3

4. Calculate the remaining two sides of the similar triangle

 Side D in meters: ( )

 Side E in meters: √

9
X

Y 9m

15m
12m
22.50m 37.50m

30m

Figure 2.8 Tracking algorithm step4

5. Calculate the ratios of the hypotenuses of the similar triangles and calculate the X and

Y coordinates of the vehicle

 Ratio of hypotenuses:

 Coordinate X in meters:

 Coordinate Y in meters:

The algorithm setup explains how to find a relative location in two dimensions. The

algorithm written in the C language and implemented on the Xilinx Microblez softcore

processor gives seamless results while the vehicle is moving inside the building. The next

chapter explains all hardware components and their configuration.

10
CHAPTER 3

HARDWARE COMPONENTS AND THEIR CONFIGURATION

As shown in figure 2.4, the Xilinx Spartan 3e FPGA starter board had been used

as a computation base. It is assumed for this experiment that the Xilinx Spartan 3e FPGA

board is a part of the moving vehicle. The Spartan 3e is the FPGA chip capable of

implementing midscale embedded design logic. The Spartan 3e FPGA board supports the

Microblaze softcore processor. The processor is a 32-bit RISC processor with highly

scalable features. The Xilinx Platform Studio (XPS) had been used to define the

processor components and the peripherals. Along with that, two RS-232 ports provided in

the board were used to communicate with the remote RF stations. The Spartan 3e board is

equipped with both DTE and DCE types of serial connection. Since it has been

implemented on FPGA board, modifications become very easy and handy as application

requirements change during the development cycle.

3.1 Defining embedded system in Xilinx Platform Studio (XPS) :

Figure 3.1 select single/multi processor system

11
Figure 3.2 Microblaze system definition

Figure 3.2 shows different parameter options for the Microblaze softcore

processor. The processor clock was kept default to the Spartan 3e FPGA board, which

was 50 MHz. Local memory refers to the on-chip BRAM memory blocks which can be

defined maximum at 64 KB. The Microblaze is Harvard architecture; therefore, it has two

separate buses. One bus is connected to the data-memory, and another is connected to the

instruction-memory.

12
Figure 3.3 Available peripheral options to be connected with Microblaze

RS232 DCE, RS232 DTE, LCD 2x16, 6-bit LEDs, dlmb_cnlr and ilmb_cnlr has been

selected as basic peripherals needed in the system.

13
Figure 3.4 Embedded system view with selected IP components

Figure 3.4 shows the GUI representation of Microblaze system with all connection and

direction details.

14
Figure 3.5 Memory mapped addresses belong to each IP component

Figure 3.5 shows the memory mapped IP components. After completing the definition of

embedded system, it is ready to be generated (generate bitstream to program FPGA) and

exported to SDK (Xilinx software development kit) to implement the software

application.

3.2 X-bee pro RF modules:

Important features:

Indoor/Urban range: Up to 90m at maximum transmit power

Outdoor line of sight: Up to 1 mile

Transmit power: 63mW (18dBm) at maximum

Receiving sensitivity: -100dBm

15
RF data rate: 250 kbps

Power down current: <10 uA

Unicast and broadcast communication support

Free X-CTU software for testing and configuration

API and AT command mode for configuring module parameters

Operating frequency: 2.4 GHz

Figure 3.6 XBIB-U-DEV-REV 3 board

Figure 3.6 shows an Xbee-pro configuration board with the USB support. The

board had been used to configure and test all RF modules used in the system with the X-

CTU software support.

16
Figure 3.7 X-CTU setup window

Figure 3.7 shows a user-interface with the XBIB-DEV-REV 3 board. The

Test/Query tab enables a modem test with given setting like baud rate, flow control, data

bits, parity and stop bits. All Xbee pro modules should be setup to the same settings and

then devices could communicate with each other.

17
Figure 3.8 Spartan 3e FPGA board with two Xbee pro RF modules connected through RS-

232 ports

Figure 3.9 Xbee pro RF module in loopback mode

18
To achieve the loopback mode in the above diagram, the Data Carrier Direct (pin

1), Date Terminal Ready (pin 4), Data Set Ready (pin 6), and Ring Indicator (pin 9)

signals must be wired together, the Received Data (pin 2) and Transmitted Data (pin 3)

signals must be wired together, and the Request To Sent (pin 7) and Clear To Send (pin

8) signals must be wired together. This wiring was accomplished on the RS232 ports of

the two transceivers set up as remote RF posts.

19
CHAPTER 4

ANTENNA CALIBRATION

The Xbee-pro RF modules are equipped with an isotropic antenna. These modules

should be placed in the arena such that the antenna stands vertical. As a result, the

radiation pattern of the antenna exists strongest across the horizon. The RF modules

should not be placed inside any metal case to avoid misbehavior in the antenna radiation

pattern. Along with that, objects such as metal poles, metal studs or beams in structures,

concrete (it is usually reinforced with metal rods), elevators and the human body should

be avoided between the transmitting and receiving devices.

The PL parameter is used to select and read the power level at which the RF

module transmits power. When operating in Europe, XBee-PRO 802.15.4 modules must

operate at or below a transmit power output level of 10dBm. Users have five choices

ranging from 0(10dBm), 1(12dBm), 2(14dBm), 3(16dBm), 4(18dBm) (Referance-

www.digi.com). In this project, ‘0’ (10 dBm) transmit power level was selected since the

power level of 10dBm is sufficient to cover the maximum distance for the given scenario.

The RF module should not be configured so that it covers a distance more than required

because it causes a low power drop per unit distance. This leads to a decrease in the

system resolution. Figure 4.1 shows how to configure the power level using the X-CTU

software.

Additionally, to establish communication between the Transceiver A with the

Transceiver A’, they were configured with the same channel[C] and PAN ID[3332]. The

Transceiver B and the Transceiver B’ were configured with the different channel [D] and

PAN ID [3334]. The configuration setting can be seen in Figure 4.1

20
The DB parameter was used to read the received signal strength (in dBm) of

the last received packet. The reported values are accurate between -40 dBm and the RF

module's receiver sensitivity. The absolute values are reported. For example: 0x58 = -88

dBm (decimal). 0x0 will be reported if no packets have been received (since last reset,

power cycle or sleep event). (Referance-www.digi.com)

AT command: ATDB

Parameter range for Xbee-pro: 0x24 to 0x64

Figure 4.1 Parameter configuration window in X-CTU software

21
Having this information, the manual tests, shown in figure 4.2, were carried out to

find the relation between the distances against the received power.

Figure 4.2 Experiment set up to find received power for variable distance

 One RF module was connected to a PC which interacts with the X-CTU software and

another RF module set in the loopback mode.

 From the range test tab in X-CTU software, hit the start button to test the communication

setup. The successful connection can be determined by looking at the “Good” packet

numbers shown in Figure 4.3

 The RF module with loopback mode has been moved in each step of 1 meter in

increasing fashion.

 To get the exact value of the received power, open the terminal window. Hit random

characters. The characters colored in blue are transmitting packets and the characters

colored in red are received packets.

 By typing “+++” sets the RF module in the AT command mode. In response, ‘OK’

indicates that the module entered in the AT command mode successfully.

 Send “ATDB” command to read the “DB” register. This Command returns value in hex.

22
This step can be seen in figure 4.4

Figure 4.3 Range test

Figure 4.4 Reading DB register value


23
Table 4.1 shows the results that indicate the received power against the distance.

For a given distance, the received power often fluctuated during the experiment, but the

value shown in the table is the value that has been read the majority of the time. Because

of these fluctuations, the moving vehicle has to send the data (let say character) several

times and read the DB register and finalize the value. For example, if the moving vehicle

reads -58 dBm (0x3A) register value several times, that means the vehicle is 15m apart

from the specific RF transceiver station.

Distance in Meters Received power in hex


0 to 3 0x24
4 0x27
5 0x29
6 0x2A
7 0x2D
8 0x2E
9 0x30
10 0x33
11 0x34
12 0x36
13 0x38
14 0x39
15 0x3A

Table 4.1 Distance verses Received power

Figure 4.5 Black colored area from two RF stations shows 3m blind area

24
It was observed that from 0m to 3m the DB register shows the minimum possible

value (highest value of received power) it can measure. Therefore, if the vehicle comes in

this area, we cannot determine the correct distance from the RF station. It is shown as a

blind spot in figure 4.5

25
CHAPTER 5

SOFTWARE DEVELOPMENT AND TESTING

As described in the chapter 3, after configuring the embedded hardware system

based on single Microblaze system, the hardware can be export to Xilinx software

development kit (SDK) to build a software application in the C language. The SDK

environment used to develop and debug the software which has been stored in the on-

chip memory, BRAM.

Peripheral_test.c is the application written to test the system described in chapter

3. After the completion of the C code, the SDK automatically built the application and

generate an elf (executable and linker file) file along with the board support package.

Then the elf file can be downloaded with the .bit, and the .bmm file to the FPGA board.

According to the application written, all LEDs are set to the off state initially. Then the

XUartLite_Send function sends a character and the XUartLite_Recv function receives a

character. After reception of the sent character, all LEDs are turned on.

/*
* Microblaze system peripheral test program
* Author: Kukadiya Akash
* peripheral_test.c
*
* This program checks whether microblaze processor and peripheral connected
* are correctly instantiated inside FPGA
*/
#include <stdio.h>
#include "xparameters.h"
#include "xgpio.h"
#include "xstatus.h"
#include "platform.h"
#include "xuartlite.h"

//Global Variables
XGpio lcd;
XGpio sixLeds;
XTmrCtr timer;

26
XUartLite uartA, uartB;

int i;
char j;
int main()
{

print("Hello World\n\r");
print("Jay swaminarayan\n\r");

u8 sndData = 'a';
u8 recvData = 0;

XGpio_Initialize(&sixLeds, XPAR_LEDS_6BIT_DEVICE_ID);
XUartLite_Initialize(&uart, XPAR_RS232_DTE_DEVICE_ID);

XGpio_SetDataDirection(&sixLeds, 1, 0x00);

XGpio_DiscreteSet(&sixLeds, 1, 0x2A);

XUartLite_Send(&uart, &sndData, 1);

for(i=0; i<3000000; i++) //approximate 1 minute of wait


{
}

do { XUartLite_Recv(&uart, &recvData, 1);


} while(recvData != sndData);

for(i=0; i<3000000; i++) //approximate 1 minute of wait


{
}

XGpio_DiscreteSet(&sixLeds, 1, 0x3F); //All led blinks

printf("%c", recvData); //print received character

return 0;
}

Function to map RF transceiver DB register value to distance:

The function “Map_distance” was written to find the distance between the vehicle

and the RF station by using Table 4.1. The system application must be able to read the

RF module register value in order to find the distance. However, after setting the RF

module to the AT command mode, we cannot simply send “ATDB” command in order to

27
read the value of receiving power. To do so, a separate software driver is needed to be

written that is able to send the AT commands from the Microblaze to the X-bee pro

modem. Due to unfamiliarity of the software driver development process, it hadn’t been

written. However, the function was written to map the received power values with the

distance. Steps below explain the “Map_distance” function.

 The transceiver A was connected with the RS 232 DTE port on the FPGA board. The

transceiver B was connected with the RS 232 DCE port on the FPGA board.

 Send a data (here a character) from the transceiver A and wait till it receives back. Then

change the transceiver A to the AT command mode. Send the ‘ATDB’ command to get

the ‘DB’ register value.

 Store the register value to the variable ‘DB_register_value’. Call the function

‘Map_distance’ to assign the distance value associated with the received power level.

 Repeat above steps for the transceiver B.

 As a result, the distance between the vehicle and the two RF stations can be achieved.

The rest of the development code was taken from the reference “DESIGE OF AN

AUTONOMOUS INDOOR LOCALIZATION SYSTEM” paper submitted in spring 2011

by Robert Santogrossi, to locate the moving vehicle. The section is shown in Appendix

A.

//Global Variables
XGpio lcd;
XGpio sixLeds;
XTmrCtr timer;
XUartLite uartA, uartB;

//Function Declaration
int Map_distance(int *DB_register_value);

28
/*
* This function maps register value to associated distance
*
* @param * DB_register_value(pointer to the DB_register_value)
*
* @return integer
*/
int Map_distance(int *DB_register_value) {

switch (DB_register_value){

case 1:
if (DB_register_value = 27)
Distance = 4;
break;

case 2:
if (DB_register_value = 29)
Distance = 5;
break;

case 3:
if (DB_register_value = 2A)
Distance = 6;
break;

case 4:
if (DB_register_value = 2D)
Distance = 7;
break;

case 5:
if (DB_register_value = 2E)
Distance = 8;
break;
case 6:
if (DB_register_value = 30)
Distance = 9;
break;

case 7:
if (DB_register_value = 33)
Distance = 10;
break;

case 8:
if (DB_register_value = 34)
Distance = 11;
break;

case 9:
if (DB_register_value = 36)
Distance = 12;
break;

case 10:
if (DB_register_value = 38)

29
Distance = 13;
break;

case 11:
if (DB_register_value = 39)
Distance = 14;
break;

case 12:
if (DB_register_value = 3A)
Distance = 15;
break;

//more case statements can be used, if have more distance verses received
//power data available
}

30
CONCLUSION

This paper is a study to solve the problem of given complexity that combines

hardware and software components together which is one of the important tasks to be

accomplished in order to qualify and compete in the International Aerial Robotics

Competition (IARC), as a 6th mission. From this paper, one can understand the theory,

basic algorithm and how to use receiving power to determine the distance between two

wireless devices. This paper doesn’t show a fully functional system on hardware.

However, this new approach of measuring distance with help of signal strength analysis

is useful and also vary practical. It has been observed that for the given indoor scenario

we can achieve approximate resolution of 1 meter. To implement this methodology in a

general scenario that may have large obstacle like walls, concrete beams, metal and even

human body can give a wrong distance value of the moving object. This is due to variable

power attenuation. Another drawback in this project is the computation logic was carried

out on the FPGA board which is a more power and space consuming circuitry to mount

on the flying vehicle. To address this problem, a customized microcontroller based PCB

needs to be designed to connect with the Xbee pro wireless modules.

31
REFERANCES

 Xbee Pro user manual available at

ftp://ftp1.digi.com/support/documentation/90000982_A.pdf

 Quick_start_guide_xbs2_development-kit.pdf

 Sparatn 3 generation configuration guide available at www.xilinx.com/documents

 EDK concepts, tools and techniques available at

http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/edk_ctt.pdf

 Xilinx MicroBlaze Development Kit Spartan-3E 1600E Edition User Guide available at

http://www.xilinx.com/support/documentation/sw_manuals/

 http://www.xilinx.com/forum

 IARC Competition Rules available at http://iarc.angel-strike.com

 “DESIGE OF AN AUTONOMOUS INDOOR LOCALIZATION SYSTEM” paper

submitted in spring 2011 by Robert Santogrossi at California state university Northridge

32
APPENDIX

(Reference taken from “DESIGE OF AN AUTONOMOUS INDOOR LOCALIZATION SYSTEM”

paper submitted in spring 2011 by Robert Santogrossi)

Includes and Main Function

The main function serves as the entry point for all functional codes in the system. The

main function along with required included files and associated defines and global variables are

shown below.

/*
* Author: Robert John Santogrossi
*
* Title: Localization Program
*
* Description: This code serves to track the location of
* an autonomous vehicle inside a defined building. Code
* for directing the vehicle to and into the building should
* be added. Code for moving the vehicle while inside the
* building should be added by utilizing the output of the
* tracking algorithm implemented in this code.
*
* Edited by: Akash Kukadiya
*/

#include "math.h"
#include "xgpio.h"
#include "xparameters.h"
#include "xtmrctr.h"
#include "xuartlite.h"

//Defines
#define BUILDING_LENGTH 30
#define DISTANCE_BETWEEN_POSTS 15
#define SYSTEM_RESOLUTION 3
#define TRANSCEIVER_A 0
#define TRANSCEIVER_B 1
#define TRANSCEIVER_A_ANGLE 0

int main()
{
int outsideBuilding = 1;
double DB_register_value_A = 0, DB_register_value_B = 0;
double distanceA = 0, distanceB = 0;
double xPosition = 0, yPosition = 0;
int xMap[BUILDING_LENGTH / SYSTEM_RESOLUTION];

33
int yMap[DISTANCE_BETWEEN_POSTS / SYSTEM_RESOLUTION];

initialize(xMap, yMap);

for(;;) {
while(outsideBuilding) {
/*Add Code to allow vehicle to enter building
and then toggle outsideBuilding to 0*/
}

while(!outsideBuilding) {
DB_register_value_A = get_received_power(TRANSCEIVER_A);
DB_register_value_B = get_received_power(TRANSCEIVER_B);
distanceA = Map_distance(DB_register_value_A);
distanceB = Map_distance(DB_register_value_B);
findPosition(&xPosition, &yPosition, TRANSCEIVER_A_ANGLE,
distanceA, distanceB);
logPosition(xMap, yMap, xPosition, yPosition);
displayPosition();

/*Add code to move the wehicle and perform its


indoor objective while utalizing the current X
and Y position and the X and Y position map
arrays and exit the building then toggle
outsideBuilding to 1*/
}

//Add code to return vehicle to starting position


}

return 0;
}

Figure 31: Main function, include files, and necessary code

All of the included files shown in the code above are required for full functionality of the

tracking system. In the main function, various necessary variables are declared and initialized

including the x any map arrays which are sized according to the system resolution and the

outside building flag variable. After the variable declarations the initialize function is called to

prepare the system for functionality. Inside the non-terminating for-loop, the code will first enter

a while loop. The code must be written inside this loop to allow the vehicle to enter the building

and toggle the outside building variable to 0. This code is outside the scope of this paper. Once

the vehicle is inside the building, program execution will enter the next while loop where the

34
indoor tracking algorithm is executed. More code must be written to move the vehicle while

inside the building to accomplish its objective while utilizing the output of the tracking algorithm

for assistance and toggle the outside building variable when exiting the building. This code, and

the code needed to return the vehicle back to its starting location are also outside the scope of

this paper. Necessary function definition can be seen.

4.1.Initialization and Delay Functions

The initialization function is the first function to be entered from the program’s main

function. This function must be executed first because it prepares the system for all of the

functionality it is expected to perform. The delay functions are core pieces of code needed in

many aspects of the program and are very useful during the development of the code. These

types of functions are explained below.

4.1.1. Initialize

The initialization function serves to initialize and set registers for all of the peripherals

used in the remainder of the program. The initialize function also resets the X and Y position

maps. The function declaration, definition, and associated defined and global variables are

shown below.

//Defines
#define BUILDING_LENGTH 30
#define DISTANCE_BETWEEN_POSTS 15
#define ROW_2_COLUMN_1 0x40
#define SYSTEM_RESOLUTION 1
#define X_POS "X Pos: "
#define Y_POS "Y Pos: "

//Global Variables
XGpio lcd;
XGpio sixLeds;
XTmrCtr timer;
XUartLite uartA, uartB;

void initialize(int *xMap, int *yMap);

35
/*Associate the objects with the addresses for the LCD,
timer, and UARTs*/
XGpio_Initialize(&lcd, XPAR_CHARACTER_LCD_2X16_DEVICE_ID);
XGpio_Initialize(&sixLeds, XPAR_LEDS_6BIT_DEVICE_ID);
XUartLite_Initialize(&uartA, XPAR_RS232_DTE_DEVICE_ID);
XUartLite_Initialize(&uartB, XPAR_RS232_DCE_DEVICE_ID);
XTmrCtr_Initialize(&timer, XPAR_XPS_TIMER_1_DEVICE_ID);
/*Set data direction as output for the ports connected
to the LEDs and the LCD display*/
XGpio_SetDataDirection(&sixLeds, 1, 0x00);
XGpio_SetDataDirection(&lcd, 1, 0x00);

//Set the timer to count down


XTmrCtr_SetOptions(&timer, 1, XTC_DOWN_COUNT_OPTION);

//Initialize the LCD display


initializeLcd();

//Write initial data to the LCD display


writePhrase(X_POS);
moveCursor(ROW_2_COLUMN_1);
writePhrase(Y_POS);

int i = 0;

/*Loop for the size of the map arrays defined by the


system resolution and fill them with 0's*/
for(i = 0; i < (BUILDING_LENGTH / SYSTEM_RESOLUTION); i++) {
xMap[i] = 0;

if(i < (DISTANCE_BETWEEN_POSTS / SYSTEM_RESOLUTION)) {


yMap[i] = 0;
}
}
}
Figure 8: Initialization function and necessary code

The initialization function has no return value and requires two integer pointers as

parameters. The function first associates the global variable objects for the system peripherals

with the addresses they physically occupy in the system using initialization functions provided

by the generated Microblaze library. The GPIO ports of the LCD display and the LEDs are then

set to the data direction of output and timer channel 1 of the timer is set to count downwards.

Timer channel 1 is left in its default state of counting upwards. Next the LCD display is

initialized, the phrase “X Pos: ” is written on the display, the cursor is moved to the second row,

and the phrase “Y Pos: ” is written on the display. These custom LCD display functions will be

36
discussed later in the paper. The last task for the initialization function is to clear the memory

contents of the xMap array and the yMap array. Pointers to these arrays were passed as

parameters to the function so that they could be modified within the function. The outer for loop

iterated ten times clearing the xMap array on every iteration and clearing the yMap on only the

first five iterations. If the system resolution changes because of possible faster clock frequencies

all that needs to change is the SYSTEM_RESOLUTION define because size of the mapping

arrays and their clearing loop will adjust appropriately.

4.1.2. Millisecond Delay

The millisecond delay function serves only to halt program execution for a specified

period of time in milliseconds. The function declaration, definition, and associated global

variable are shown below.

//Global Variables
XTmrCtr timer;

//Function Declaration
void msDelay(unsigned int time);

/*
* msDelay
* This function generates a millisecond time delay.
* Requires a timer that counts down.
*
* @param time (the amount of time in ms to delay)
*
* @return void
*/
void msDelay(unsigned int time) {

//Set the reset value based on a 100MHz clock speed


XTmrCtr_SetResetValue(&timer, 1, time * 100000);

//Start the timer


XTmrCtr_Start(&timer, 1);

//While the timer value has not expired do nothing


while(!(XTmrCtr_IsExpired(&timer, 1))) {
}

//Stop the timer

37
XTmrCtr_Stop(&timer, 1);
}
Figure 9: Millisecond delay function and necessary code

The millisecond delay function has no return value and requires one unsigned integer

parameter. The function first sets the reset value of timer channel 1 to the input parameter

multiplied by 100,000. The reset value is the value that the timer will be set to when it is reset or

expires by reaching a count of zero. At a 100MHz clock speed, every count on the timer counts

10ns. The time variable is multiplied by 100,000 because 10ns times 100,000 equates to 1ms.

The timer is then started and an empty while loop executes as long at the generated Microblaze

function XTmrCtr_IsExpired returns a value of true. When the value of true is returned, the loop

is exited and the timer is stopped.

4.1.3. Microsecond Delay

The microsecond delay function functions in the same fashion as the millisecond function

except that the unsigned integer time parameter is multiplied by 100 instead of 100,000 because

10ns times 100 equates to 1us.

//Global Variables
XTmrCtr timer;

//Function Declaration
void usDelay(unsigned int time);

/*
* usDelay
* This function generates a microsecond time delay.
* Requires a timer that counts down.
*
* @param time (the amount of time in us to delay)
*
* @return void
*/
void usDelay(unsigned int time) {

//Set the reset value based on a 100MHz clock speed


XTmrCtr_SetResetValue(&timer, 1, time * 100);

//Start the timer

38
XTmrCtr_Start(&timer, 1);

//While the timer value has not expired do nothing


while(!(XTmrCtr_IsExpired(&timer, 1))) {
}

//Stop the timer


XTmrCtr_Stop(&timer, 1);
}
Figure 10: Microsecond delay function and necessary code

4.2. LCD Functions

The LCD functions were written so that the output of the tracking algorithm can be

displayed. The LCD functions were written early in the development cycle of the software

because it provides a very useful debugging tool. These types of functions are explained below.

4.2.1. Write LCD Port

The write LCD port function serves to write an 8-bit byte to the GPIO port connected to

the LCD display peripheral on the FPGA board. The function declaration, definition, and

associated defines and global variables are shown below.

//Defines
#define INSTRUCTION 0
#define DATA 1
#define LCD_RS 0x20

//Global Variables
XGpio lcd;

//Function Declaration
void writeLcdPort(unsigned int type, unsigned int data);

/*
* writeLcdPort
* This function writes a byte to the LCD port
*
* @param type (the type of data to be written)
* @param data (the nibble of data to be written)
*
* @return void
*/
void writeLcdPort(unsigned int type, unsigned int data) {
switch (type) {

39
/*If the data is an instruction write the low nibble
Without asserting any bits on the high nibble*/
case INSTRUCTION:
XGpio_DiscreteWrite(&lcd, 1, data);
break;

/*If the data is a data write the low nibble while


Asserting the RS bit on the high nibble*/
case DATA:
XGpio_DiscreteWrite(&lcd, 1, (LCD_RS | data));
break;
default:
break;
}
}
Figure 11: Write LCD port function and necessary code

The write LCD port function has no return value and requires two unsigned integer

parameters. The LCD peripheral accepts a byte of data at a time. The high nibble tells the LCD

to configure to read or write mode, whether the low nibble is a part of data or an instruction, and

to clock in the bits on the low nibble. If the instruction define is passed into the function, the

data are written to the port. The low nibble is written and the high nibble is left as its default 0.

A 0 on the high nibble enables write mode and the instruction register on the LCD display. If the

data define are passed into the function, a bitwise OR function is performed with the data and the

define LCD_RS. The low nibble is written and the high nibble is loaded with 2. A 2 on the high

nibble enables write mode and the data register on the LCD display.

4.2.2. Pulse Enable

The pulse enable function serves to assert and de-assert the enable line in the high nibble

while keeping the low nibble unchanged. The function declaration, definition, and associated

defines and global variables are shown below.

//Defines
#define INSTRUCTION 0
#define DATA 1
#define LCD_E 0x40
#define LCD_RS 0x20

40
//Global Variables
XGpio lcd;

//Function Declaration
void pulseEnable(unsigned int type, unsigned int data);

/*
* pulseEnable
* This function asserts and deasserts the enable signal without
* modifying the data
*
* @param type (the type of data to be written)
* @param data (the nibble of data to be written)
*
* @return void
*/
void pulseEnable(unsigned int type, unsigned int data) {
switch (type) {

/*If the data is an instruction assert and deassert


the enable bit on the high nibble without modifying
the data*/
case INSTRUCTION:
XGpio_DiscreteWrite(&lcd, 1, (LCD_E | data));
usDelay(1);
XGpio_DiscreteWrite(&lcd, 1, data);
break;

/*If the data is a data assert and deassert the enable


bit while keeping the RS bit high on the high nibble
without modifying the data*/
case DATA:
XGpio_DiscreteWrite(&lcd, 1, (LCD_E | LCD_RS | data));
usDelay(1);
XGpio_DiscreteWrite(&lcd, 1, (LCD_RS | data));
break;
default:
break;
}
}
Figure 12: Pulse enable function and necessary code

The pulse enable function has no return value and requires two unsigned integer

parameters. Pulsing the enable line of the high nibble clocks the low nibble data or instruction

into the LCD controller. If the instruction define is passed into the function, a bitwise OR

operation is executed with the data and the LCD_E define. The low nibble data is unchanged

and the value 4 is loaded into the high nibble. A high nibble of 4 asserts the enable line and

41
keeps the mode set to instruction. After a 1us delay the only data are written which de-asserts

the enable line. This sequence causes an enable pulse. If the data define is passed into the

function, the same sequence of steps is performed except that the LCD_RS define is included in

the bitwise OR operations to keep the mode set to data.

4.2.3. Initialize LCD

The initialize LCD function serves to put the LCD controller into the proper mode to start

accepting instructions and data those will modify the display. The function declaration,

definition, and associated define are shown below.

//Defines
#define INSTRUCTION 0

//Function Declaration
void initializeLcd(void);

/*
* initializeLcd
* This function initialized the LCD display to prepare
* for display of data
*
* @param void
*
* @return void
*/
void initializeLcd() {

//4-bit mode sequence sequence


msDelay(40);
writeLcdPort(INSTRUCTION, 0x3);
pulseEnable(INSTRUCTION, 0x3);
msDelay(5);
pulseEnable(INSTRUCTION, 0x3);
usDelay(100);
pulseEnable(INSTRUCTION, 0x3);
usDelay(40);
writeLcdPort(INSTRUCTION, 0x2);
pulseEnable(INSTRUCTION, 0x2);
usDelay(40);

//Function set sequence


writeLcdPort(INSTRUCTION, 0x2);
pulseEnable(INSTRUCTION, 0x2);
msDelay(2);
writeLcdPort(INSTRUCTION, 0x8);

42
pulseEnable(INSTRUCTION, 0x8);
msDelay(2);

//Entry mode set sequence


writeLcdPort(INSTRUCTION, 0x0);
pulseEnable(INSTRUCTION, 0x0);
msDelay(2);
writeLcdPort(INSTRUCTION, 0x6);
pulseEnable(INSTRUCTION, 0x6);
msDelay(2);

//Display on sequence
writeLcdPort(INSTRUCTION, 0x0);
pulseEnable(INSTRUCTION, 0x0);
msDelay(2);
writeLcdPort(INSTRUCTION, 0xC);
pulseEnable(INSTRUCTION, 0xC);
msDelay(2);

//Display clear sequence


writeLcdPort(INSTRUCTION, 0x0);
pulseEnable(INSTRUCTION, 0x0);
msDelay(2);
writeLcdPort(INSTRUCTION, 0x1);
pulseEnable(INSTRUCTION, 0x1);
msDelay(2);
}
Figure 13: Initialize LCD function and necessary code

The initialize LCD function has no return value and requires no parameters. The LCD

display on the FPGA board is wired to use a 4 bit data bus. As stated before, the high nibble

carries configuration bits and the lower nibble carries instructions or data. The instructions and

data however are 8 bits long. The FPGA board user guide and LCD documentation state that the

high nibble is clocked in first followed by the low nibble to complete one data or instruction

write to the LCD controller. The same documentation provides guidance on the sequence of

writes to the LCD controller and delay times that are needed to initialize the display. It is this

guidance that is implemented in this function. The LCD initialize function makes use of the

write LCD port and pulse enable functions passing in the instruction define, and delay functions

to complete its task. Two writes of 0x33 and 0x32 inform the controller that the 4-bit

communication protocol is being used. A write of 0x06 sets the entry mode with the option that

43
the LCD cursor auto-increment with every character written to the display. A write of 0x0C

turns on the display with the options that the characters written to the controllers DD RAM be

displayed, the cursor does not blink, and the cursor is not displayed. The final write of 0x01

clears the display and moves the cursor to the top left position of the display.

4.2.4. Write Character

The write character function serves to write a character to the LCD display. The function

declaration, definition, and associated define are shown below.

//Defines
#define DATA 1

//Function Declaration
void writeCharacter(unsigned int character);

/*
* writeCharacter
* This function writes a character to the LCD display
*
* @param character (the character to be written)
*
* @return void
*/
void writeCharacter(unsigned int character) {

//Isolate the high nibble and low nibble of the character


unsigned int highNibble = ((character >> 4) & 0x0F);
unsigned int lowNibble = (character & 0x0F);

//Write the high nibble and pulse the enable signal


writeLcdPort(DATA, highNibble);
pulseEnable(DATA, highNibble);

//Write the low nibble and pulse the enable signal


writeLcdPort(DATA, lowNibble);
pulseEnable(DATA, lowNibble);
}
Figure 14: Write character function and necessary code

The write character function has no return value and requires an unsigned integer

parameter. A character is 8 bits of data, but as mentioned previously, the high nibble must be

written first followed by the low nibble. To accomplish this, the high nibble is isolated by

44
shifting the character data to the right by 4 bits and performing a bitwise AND with 0x0F. This

moves the high nibble to the low nibble and clears the new high nibble. The low nibble is then

isolated by just performing the high nibble clearing bitwise AND function. The write LCD port

and pulse enable functions are then utilized with the data define to write the high nibble followed

by the low nibble. After the execution of this function, a character is actually viewable on the

display.

4.2.5. Write Phrase

The write phrase function serves to write a character string to the LCD display. The

function declaration and definition are shown below.

//Function Declaration
void writePhrase(char *phrase);

/*
* writePhrase
* This function writes a character string to the LCD display
*
* @param *phrase (pointer to the character string to write)
*
* @return void
*/
void writePhrase(char *phrase) {

/*As long as the character string is not null write


the character to the LCD display and increment to the
next character*/
while(*phrase) {
writeCharacter(*phrase++);
}
}
Figure 15: Write phrase function and necessary code

The write phrase function has no return type and requires a pointer to a character string

parameter. This function dereferences the phrase pointer so that the data it pointed to is written

on the LCD display using the write character function. The address is then incremented to point

45
to the next character. This sequence continues until the data are a null value meaning that the

end of the phrase has been reached.

4.2.6. Write Number

The write number function serves to write a number to the LCD display. The function

declaration and definition are shown below.

//Function Declaration
void writeNumber(int number);

/*
* writeNumber
* This function writes a number to the LCD display
*
* @param number (number to be written)
*
* @return void
*/
void writeNumber(int number) {

//Convert the number integer to a character string


char buffer[10];
sprintf(buffer, "%d", number);

//Write the character string to the LCD display


writePhrase(buffer);
}
Figure 16: Write number function and necessary code

The write number function has no return type and requires an integer parameter. The

function must convert an integer into a character string in order to write the number to the LCD

screen. To do this, the character array to hold the to-be-converted integer is created and limited

to a reasonable 10 digits. The standard sprintf function is used to convert the number into a

character string and store it in the buffer character array. Once the character string is created, it

is passed into the write phrase function to be written on the LCD display.

46
4.2.7. Move Cursor

The move cursor function serves to move the cursor of the LCD controller to a specific

location on the display. The function declaration, definition, and associated define are shown

below.

//Defines
#define INSTRUCTION 0

//Function Declaration
void moveCursor(unsigned int position);

/*
* moveCursor
* This function moves the cursor on the LCD display
*
* @param position (the position to move the cursor to)
*
* @return void
*/
void moveCursor(unsigned int position) {

//Isolate the high nibble and low nibble of the command


unsigned int highNibble = (((position | 0x80) >> 4) & 0x0F);
unsigned int lowNibble = (position & 0x0F);

//Write the high nibble and pulse the enable signal


writeLcdPort(INSTRUCTION, highNibble);
pulseEnable(INSTRUCTION, highNibble);

//Write the low nibble and pulse the enable signal


writeLcdPort(INSTRUCTION, lowNibble);
pulseEnable(INSTRUCTION, lowNibble);
}
Figure 17: Move cursor function and necessary code

The move cursor function has no return value and requires an unsigned integer parameter.

This function performs much like the write character function in the fact that it first isolates the

high and low nibbles and then writes them to the LCD controller. Setting the MSB of the byte to

a 1 followed by the address to move the cursor to represent data needed to be sent in order to

move the cursor. To do this, the high nibble is isolated by using a bitwise OR function to

combine the cursor position with a 1 in the MSB, the result’s high nibble is shifted to the low

47
nibble and the new high nibble is cleared. The low nibble is isolated and the high and low

nibbles are written just as they are in the write character function.

4.2.8. Display Position

The display position function serves to display the current x and current y positions of the

vehicle on the LCD display. The function declaration, definition, and associated defines and

global variables are shown below.

//Defines
#define ROW_1_COLUMN_8 0x07
#define ROW_2_COLUMN_8 0x47

//Global Variables
int currentXPosition;
int currentYPosition;

//Function Declaration
void displayPosition();

/*
* displayPosition
* This function displays the x and y position on the
* LCD display
*
* @param void
*
* @return void
*/
void displayPosition() {

/*Move the cursor to the 8th column of the 1st row


and write the current x position*/
moveCursor(ROW_1_COLUMN_8);
writeNumber(currentXPosition);

/*Move the cursor to the 8th column of the 2nd row


and write the current y position*/
moveCursor(ROW_2_COLUMN_8);
writeNumber(currentYPosition);
}
Figure 18: Display position function and necessary code

The display position function has no return value and requires no parameters. In this

function, the move cursor function is used to move the cursor before writing each global position

48
integer to the LCD display using the write number function. The cursors are moved to the eighth

column of the first and second rows of the LCD display because, at this point in the program

execution, the phrases “X Pos: ” and “Y Pos: ” are already written on the display.

4.3. Tracking Algorithm Functions

The tracking algorithm functions were designed to implement the algorithm described in

the system theory section of this paper. Due to the sequential nature of the algorithm presented,

most of the functions were written in a cascade function in which one uses the other in a long

string of function calls to execute the algorithm. The functions are also written to accommodate

both reference angles when calculating the vehicle position. It is left to the main function to

decide which transceiver angle will be used.

4.3.1. Get received power value

The Get_received_power function sends a character from the uartA and uartB ten times

and receives back, and every time it reads the DB register value. The variable

“DB_register_value” stores the date and passes it to the Map_distance function.

//Defines
#define TRANSCEIVER_A 0
#define TRANSCEIVER_B 1

//Global Variables
XTmrCtr timer;
XUartLite uartA, uartB;

//Function Declaration
int get_received_power (unsigned int transceiver);

/*
* get_received_power
* This function initiates data transfer to two URATs connected through DTE
* and DCE pins and receives back the data and reads the received power
* strength in hex notation
*
* @param transceiver (the transceiver to use)
*
* @return read_DB_register (register value in hex)

49
*/
char get_received_power (unsigned int transceiver) {
int counter = 0;
u8 sndData1 = 0;
u16 sndData2 = ''+++'';
u16 sndData3 = ''ATDB'';
u8 recvData = 0;
u8 DB_register_value = 0;

switch (transceiver) {
case TRANSCEIVER_A:

for(counter=0; counter<10; counter++){

//Data to send through transceiver A


sndData1 = 'A';

XUartLite_Send(&uartA, &sndData1, 1);


do {
XUartLite_Recv(&uartA, &recvData, 1);
} while(recvData != sndData);
XUartLite_Send(&uartA, &sndData2, 1);
XUartLite_Send(&uartA, &sndData3, 1);

//read register value

do {
XUartLite_Recv(&uartA, &recvData, 1);
} while(recvData != sndData);

DB_register_value = recvData;
}
counter=0;
break;
case TRANSCEIVER_B:

for(counter=0; counter<10; counter++){

//Data to send through transceiver B


sndData1 = 'A';

XUartLite_Send(&uartB, &sndData1, 1);


do {
XUartLite_Recv(&uartB, &recvData, 1);
} while(recvData != sndData);
XUartLite_Send(&uartB, &sndData2, 1);
XUartLite_Send(&uartB, &sndData3, 1);

//read register value

XUartLite_Recv(&uartA, &recvData, 1);


} while(recvData != sndData);

DB_register_value = recvData;
}
counter=0;
break;

50
default:
break;

4.3.2. Find Interior Angle

The find interior angle function serves to calculate an interior angle of the generated

triangle based on the angle required and the distance measurement of the two variable

sides and return the angle in degrees. The function declaration, definition, and associated

defines are shown below.

//Defines
#define DISTANCE_BETWEEN_POSTS 15
#define TRANSCEIVER_A_ANGLE 0
#define TRANSCEIVER_B_ANGLE 1
#define POST_ANGLE 2

//Function Declaration
double findInteriorAngle(int angleToFind, double sideA, double sideB);

/*
* findInteriorAngle
* This function calculates an interior angle of the generated
* triangle using the rule of cosines
*
* @param angleToFind (the interior angle to find)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return angle (the interior angle in degrees)
*/
double findInteriorAngle(int angleToFind, double sideA, double sideB) {
double a = 0;
double b = 0;
double c = 0;
double angle = 0;

/*Set the variables for using the rule of cosines based


on the angle to find*/
switch (angleToFind) {
case TRANSCEIVER_A_ANGLE:
a = sideA;
b = DISTANCE_BETWEEN_POSTS;
c = sideB;
break;
case TRANSCEIVER_B_ANGLE:
a = sideB;
b = DISTANCE_BETWEEN_POSTS;
c = sideA;
break;
case POST_ANGLE:

51
a = sideA;
b = sideB;
c = DISTANCE_BETWEEN_POSTS;
break;
default:
break;
}

/*Calculate the angle using the rule of cosines and


convert from radians to degrees*/
angle = (a * a) + (b * b) - (c * c);
angle = angle / (2 * a * b);
angle = (acos(angle)) * (DEG_180 / PI);

//Return the angle


return angle;
}
Figure 22: Find interior angle function and necessary code

The find interior angle function returns a double and requires an integer and two double

parameters. By the time this function is executed in the normal flow of the program, a triangle

has been generated by finding the distance between the vehicle and each transceiver post. The

third side of the triangle is constant at 15m which is the distance between the posts. This

function can find any interior angle of that generated triangle. When the define for the desired

angle to find is passed into the function, the function first sets the distance parameters and

constant to the appropriate variables used in the rule of cosines. Once the variables are set for

the desired angle, the angle is calculated using the rule of cosines, converted from radians to

degrees, and returned.

4.3.3. Find Exterior Angle

The find exterior angle function serves to calculate an exterior angle of the generated

triangle based on the angle required and the distance measurement of the two variable sides and

return the angle in degrees. The function declaration, definition, and associated defines are

shown below.

//Defines

52
#define DEG_90 90

//Function Declaration
double findExteriorAngle(int angleToFind, double sideA, double sideB);

/*
* findExternalAngle
* This function calculates an exterior angle of the generated
* triangle using the interior angle
*
* @param angleToFind (the interior angle to find)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return angle (the exterior angle in degrees)
*/
double findExteriorAngle(int angleToFind, double sideA, double sideB) {

//Find the interior angle and subtract it from 90deg


double angle = findInteriorAngle(angleToFind, sideA, sideB);
angle = DEG_90 - angle;

//Return the angle


return angle;
}
Figure 23: Find exterior angle function and necessary code

The find exterior angle function returns a double and requires an integer and two double

parameters. In this function the angle to find and distances are first passed through to the find

interior angle function. After the interior angle is found, the exterior angle needed for the

tracking algorithm can simply be found by subtracting the interior angle from 90°. The exterior

angle is returned in degrees.

4.3.4. Find Similar Opposite Side

The find similar opposite side function serves to calculate the opposite side of the larger

similar triangle based on a reference angle and the distance measurement of the two variable

sides and return the side in meters. The function declaration, definition, and associated defines

and global variables are shown below.

//Defines
#define BUILDING_LENGTH 30

53
#define DEG_180 180
#define PI 3.14159265

//Global Variables
double similarOppositeSide;

//Function Declaration
double findSimilarOppositeSide(int referenceAngle, double sideA, double
sideB);

/*
* findSimilarOppositeSide
* This function calculates the opposite side of the
* reference angle of the larger similar triangle
*
* @param referenceAngle (the angle to reference)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return side (the opposite side in meters)
*/
double findSimilarOppositeSide(int referenceAngle, double sideA, double
sideB) {

/*Find the exterior angle, convert it to radians,


calculate its tangent and multiply by the building length*/
double side = findExteriorAngle(referenceAngle, sideA, sideB);
side = side * PI / DEG_180;
side = BUILDING_LENGTH * tan(side);

//Store value as a global variable and return the side


similarOppositeSide = side;
return side;
}
Figure 24: Find similar opposite side function and necessary code

The find similar opposite side function returns a double and requires an integer and two

double parameters. This function first calls the find exterior angle function which returns the

requested exterior angle in degrees. The angle is then converted into radians so that it can be

used in a tangent function. The tangent of the angle equals the opposite side over the adjacent

side. To use this equation to find the opposite side, the tangent of the angle is calculated and

multiplied by the adjacent side which is the length of the building. This result is stored in a

global variable for efficient use in the find position function do be discussed later in this paper

and returned in meters.

54
4.3.5. Find Similar Hypotenuse

The find similar hypotenuse function serves to calculate the hypotenuse of the larger

similar triangle based on a reference angle and the distance measurement of the two variable

sides and return the hypotenuse in meters. The function declaration, definition, and associated

defines are shown below.

//Defines
#define BUILDING_LENGTH 30

//Function Declaration
double findSimilarHypotenuse(int referenceAngle, double sideA, double sideB);

/*
* findSimilarHypotenuse
* This function calculates the hypotenuse of the
* larger similar triangle
*
* @param referenceAngle (the angle to reference)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return side (the hypotenuse in meters)
*/
double findSimilarHypotenuse(int referenceAngle, double sideA, double sideB)
{

/*Find the similar opposite side and use the Pythagorean


theorem to find the hypotenuse*/
double side = findSimilarOppositeSide(referenceAngle, sideA, sideB);
side = (side * side) + (BUILDING_LENGTH * BUILDING_LENGTH);
side = sqrt(side);

//Return the hypotenuse in meters


return side;
}
Figure 25: Find similar hypotenuse function and necessary code

The find similar hypotenuse function returns a double and requires an integer and two

double parameters. This function first calls the find similar opposite side function which returns

the larger similar triangle opposite side in meters. The adjacent side is also known because it is

the constant length of the building. Knowing these two sides, the Pythagorean Theorem can be

used to find the hypotenuse and return it in meters.

55
4.3.6. Find Ratio

The find ratio function serves to calculate the ratio of the generated triangle to the larger

similar triangle based on a reference angle and the distance measurement of the two variable

sides and return the ratio. The function declaration, definition, and associated defines are shown

below.

//Defines
#define TRANSCEIVER_A_ANGLE 0
#define TRANSCEIVER_B_ANGLE 1

//Function Declaration
double findRatio(int referenceAngle, double sideA, double sideB);

/*
* findRatio
* This function calculates the ratio of the generated
* triangle to the similar triangle
*
* @param referenceAngle (the angle to reference)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return ratio (the ratio)
*/
double findRatio(int referenceAngle, double sideA, double sideB) {

//Find the similar triange hypotenuse


double ratio = findSimilarHypotenuse(referenceAngle, sideA, sideB);

//Calculate the ratio based on the angle referenced


switch (referenceAngle) {
case TRANSCEIVER_A_ANGLE:
ratio = sideA / ratio;
break;
case TRANSCEIVER_B_ANGLE:
ratio = sideB / ratio;
break;
default:
break;
}

//Return the ratio


return ratio;
}
Figure 26: Find ratio function and necessary code

56
The find ratio function returns a double and requires an integer and two double

parameters. This function first calls the find similar hypotenuse function which returns the larger

similar triangle’s hypotenuse in meters. Depending on if the similar triangle was found from the

corresponding transceiver post A or transceiver post B angle, the ratio is calculated using the

corresponding distance to the vehicle from transceiver post A or transceiver post B. The ratio is

calculated from the hypotenuses of the similar triangles and returned.

4.3.7. Find Position

The find position function serves to find the physical position of the vehicle within the

building based on a reference angle and the distance measurement of the two variable sides and

store the position. The function declaration, definition, and associated defines and global

variables are shown below.

//Defines
#define BUILDING_LENGTH 30

//Global Variables
double similarOppositeSide;

//Function Declaration
void findPosition(double *xPosition, double *yPosition, int referenceAngle,
double sideA, double sideB);

/*
* findPosition
* This function calculates x and y position of the vehicle
* and modifies the data pointed to by the parameters
*
* @param *xPosition (pointer to the x position variable)
* @param *yPosition (pointer to the y position variable)
* @param referenceAngle (the angle to reference)
* @param sideA (the distance from post A to vehicle)
* @param sideB (the distance from post B to vehicle)
*
* @return void
*/
void findPosition(double *xPosition, double *yPosition, int referenceAngle,
double sideA, double sideB) {

//Find the ratio of triangles


double ratio = findRatio(referenceAngle, sideA, sideB);

57
/*Multiply the ratio by the appropriate side and update
the data pointed to by the pointers*/
*xPosition = ratio * BUILDING_LENGTH;
*yPosition = ratio * similarOppositeSide;
}
Figure 27: Find position function and necessary code

The find position function has no return value and requires two pointers to doubles, an

integer, and two double parameters. This function first calls the find ratio function which returns

the ratio of the two similar triangles. The sides of similar triangles are proportional to each other

and this proportion is the ratio that was found. Multiplying this ratio by the building length in

the X axis gives the distance the vehicle is from the transceiver post in the X axis and

multiplying this ratio by the opposite side of the larger similar triangle in the Y axis gives the

distance the vehicle is from the transceiver post in the Y axis. These distances are calculated and

stored as the data pointed to by the pointers parameters passed into the function. The global

variable for the opposite side of the larger similar triangle is used in this function instead of

calling the find opposite similar side function for a performance gain. Each function that has a

role in calculating the position from the timer values should only be called once in the execution

of the tracking algorithm. This convention keeps the code running efficiently.

4.3.8. Scale Position

The scale position function serves to scale an x or y position value down to the scale

limited by the system resolution and return the scaled position. The function declaration,

definition, and associated defines are shown below.

//Defines
#define BUILDING_LENGTH 30
#define DISTANCE_BETWEEN_POSTS 15
#define SYSTEM_RESOLUTION 3
#define X_AXIS 0
#define Y_AXIS 1

58
//Function Declaration
double scalePosition(double position, int axis);

/*
* scalePosition
* This function scales the vehicle position according to the
* system resolution
*
* @param position (the x or y position)
* @param axis (the axis that the position variable represents)
*
* @return scaledPosition (the scaled x or y position)
*/
double scalePosition(double position, int axis) {
double scaledPosition = 0;

/*Using either the X or Y axis, scale the position using


the system resolution and an equal proportion equation*/
switch (axis) {
case X_AXIS:
scaledPosition = BUILDING_LENGTH / SYSTEM_RESOLUTION;
scaledPosition = scaledPosition * position;
scaledPosition = scaledPosition / BUILDING_LENGTH;
break;
case Y_AXIS:
scaledPosition = DISTANCE_BETWEEN_POSTS / SYSTEM_RESOLUTION;
scaledPosition = scaledPosition * position;
scaledPosition = scaledPosition / DISTANCE_BETWEEN_POSTS;
break;
default:
break;
}

//Return the scaled position


return scaledPosition;
}
Figure 28: Scale position function and necessary code

The scale position function returns a double and requires a double and an integer

parameter. As stated earlier in the system theory section of this paper, the system resolution

determines the size of the data structure used to map the building and track the vehicle. If the

resolution of the system is blocks of three square meters and the building is 30m by 15m, the

data structure used to map the building must be 10 units in the X axis and 5 units in the Y axis.

This function scales the actual distances down to the resolution of the system in the X axis and in

the Y axis using the following equal proportion equations.

59
After the requested scaled value is calculated it is returned.

4.3.9. Round and Normalize Position

The round and normalize position function serves to prepare a scaled position to index

into a position map array. The function declaration, definition, and associated defines are shown

below.

//Defines
#define X_AXIS 0
#define Y_AXIS 1

//Function Declaration
int roundAndNormalizePosition(double scaledPosition, int axis);

/*
* roundAndNormalizePosition
* This function transforms the scaled position to the
* position in the map
*
* @param position (the position of the vehicle scaled)
* @param axis (the axis of the scaled position)
*
* @return roundNormalPosition
*/
int roundAndNormalizePosition(double position, int axis) {
double scaledPosition = scalePosition(position, axis);

//Take the floor of the scaled position and cast to an int


int roundNormalPosition = (int)(floor(scaledPosition));

switch (axis) {
case X_AXIS:
//Handle the case where the position is exactly 10
if(roundNormalPosition == 10) {
roundNormalPosition--;
}
break;
case Y_AXIS:
//Handle the case where the position is exactly 5
if(roundNormalPosition == 5) {

60
roundNormalPosition--;
}
break;
default:
break;
}

//Return the round and normal position


return roundNormalPosition;
}
Figure 29: Round and normalize position function and necessary code

The round and normalize position function returns an integer and requires a double

parameter. This function first calls the scale position function which returns the scaled position

based on the system resolution. At this point, the position is still not ready to index into the X

and Y position map arrays because the value is a double. The floor of the position is taken and

then the value is casted to an integer. In the case where the X position becomes exactly 10, the

value is decremented by 1 and in the case where the Y position becomes exactly 5 the value is

decremented by 1. All other cases will index perfectly into the X and Y position mapping arrays.

4.3.10. Log Position

The log position function serves to populate the x and y position map arrays with a

marker based on the position of the vehicle. The function declaration, definition, and associated

defines and global variables are shown below.

//Defines
#define X_AXIS 0
#define Y_AXIS 1

//Global Variables
int currentXPosition;
int currentYPosition;

//Function Declaration
void logPosition(int *xMap, int *yMap, double xPosition, double yPosition);

/*
* logPosition
* This function prepares the position data, sets the
* global position variables, and log the vehicle position

61
* in the map arrays
*
* @param *xMap (pointer to the x position map)
* @param *yMap (pointer to the y position map)
* @param xPosition (the x position of the vehicle)
* @param yPosition (the y position of the vehicle)
*
* @return void
*/
void logPosition(int *xMap, int *yMap, double xPosition, double yPosition) {
int roundNormalXPosition = roundAndNormalizePosition(xPosition, X_AXIS);
int roundNormalYPosition = roundAndNormalizePosition(yPosition, Y_AXIS);

//Store the scaled and round position into global variables


currentXPosition = roundNormalXPosition;
currentYPosition = roundNormalYPosition;

//Populate the x and y mapping arrays with a marker


xMap[roundNormalXPosition] = 1;
yMap[roundNormalYPosition] = 1;
}
Figure 30: Log position function and necessary code

62

You might also like