Revised 12/14/03 9:00 p.m. -- Check for
Revisions-- Use the current Version!!!
This is the final lab; in it you will:
- Use your TOS and PWM skills to implement two nodes of a
cellular automata-like system for distributing bird songs
- Take the completed "birds" to the atrium to join the flock
In this lab you will learn the following:
- How to build a multi-module radio application
- How well the proposed flock algorithm works in practice
Flock Algorithm:
Within a single "bird", the flock algorithm that you will implement is
as follows:
A.0)
A.1)
A.2)
|
Do
some initialization
set SONG = Local # % 16 (see below)
Wait to receive a packet of type AdjustGlobals (see
below) then go to A.2
Wait to receive a packet of type AdjustGlobals (see
below) or SingSongN
set SONG = random song
On AdjustGlobals go to A.2
radio off
Clear Table Data (all historical data)
Wait for random amount of time (1000- 4000
milliseconds)
|
B) |
With radio off, sing
birdiesong(SONG)
|
C) |
Start the radio and set
listen timer for random t є [minListen, maxListen] milliseconds (see below)
|
D) |
Set the send timer for minListen/2 milliseconds and
send
the "I sang song" message (see below)
|
E) |
When listen timer runs out,
decide next SONG (see below)
|
F) |
Repeat steps B through F. |
Implement the above algorithm with attention to the implementation
details below.
Some Implementation Details:
The Atrium Group ID will be 122. Each mote will use the same
group ID, and Node ID (Local #)
== the number on your mote's label.
The average bird song length is 2.845 sec, the sum of all the
song lengths is 45.52 sec.
Our 16 bird songs in numbered order are:
songNum |
Length (sec) |
Filename |
Bird |
0 |
1.995 |
bbwa.txt |
Black-throated Blue Warbler |
1 |
2.045 |
bpwa.txt |
Blackpoll Warbler |
2 |
2.34 |
brcr.txt |
Brown Creeper |
3 |
3.565 |
cardinal.txt |
Northern Cardinal |
4 |
3.115 |
indigobu.txt |
Indigo Bunting |
5 |
2.11 |
junco.txt |
Dark-eyed Junco |
6 |
1.625 |
mowa.txt |
Mourning Warbler |
7 |
2.71 |
oriole.txt |
Baltimore Oriole |
8 |
1.885 |
osprey.txt |
Osprey |
9 |
3.335 |
oven.txt |
Ovenbird |
10 |
4.815 |
songspar.txt |
Song sparrow |
11 |
4.905 |
towhee.txt |
Rufous-sided Towhee |
12 |
3.17 |
tuftedti.txt |
Tufted Titmouse |
13 |
3.705 |
veery.txt |
Veery |
14 |
2.35 |
whthsprw.txt |
White-throated Sparrow |
15 |
1.85 |
wiwa.txt |
Wilson's Warbler |
Store your songs in flash program space. Here is progspace.h which shows how to do that.
There are 4 types of Active Messages your
program must handle; they are as follows:
AM # |
Flock Message / Packet |
50 |
AdjustGlobals - A message
from Node 0 containing global parameters for all birdies.
|
u_int16_t |
Node0 |
|
|
u_int16_t |
Repetition |
default 3
|
|
u_int16_t |
minListen |
default 2000
millisec.
|
|
u_int16_t |
maxListen |
default 15000
millisec.
|
|
u_int16_t |
Threshold |
default 600
|
|
u_int16_t |
minThreshold |
default 100
|
|
u_int16_t |
Probability |
default 10
|
|
u_int16_t |
Silence
|
default 10 |
|
u_int16_t |
TransmitPower |
default 1
|
|
51 |
StopandListen - A
message from Node 0 telling you to stop and listen.
|
u_int16_t |
Node0 |
On receipt, go to
A.1 |
|
42 |
SangSong - The "I sang song"
message; a message from some other birdie indicating what song it sang.
You also send this packet after singing.
Note: if you are
sending this after a packet 52 SingSongN, set all data = 0 except your
node num and song #.
|
u_int16_t |
TransmittingNodeNum |
local # of node
singing
|
|
u_int16_t |
SequenceNum
|
start at 1,
increment each time you send this packet
|
|
u_int16_t |
songNum |
song# that was sung
|
|
u_int16_t |
songWeight |
usually same as Weightmax |
|
u_int16_t |
WeightmaxSongNum |
|
|
u_int16_t |
Weightmax |
|
|
u_int16_t |
TopSong2Num |
|
|
u_int16_t |
TopSong2Weight |
runner-up weight
|
|
u_int16_t |
WeightminSongNum |
|
|
u_int16_t |
Weightmin |
|
|
u_int16_t |
TopNodeNum |
Strongest node
you've heard
|
|
u_int16_t |
TopNodeStrength |
Highest
TOS_msg_strength |
|
52 |
SingSongN - A message from
Node 0 telling you to sing song N immediately.
|
u_int16_t |
Node0 |
SingSongN
immediately, then
|
|
u_int16_t |
SingSongN |
send SangSong AM 42,
then Go To A.1
|
|
While listening, we collect the information
we hear (AM #42 type packets) in a 64-entry circular FIFO queue.
Each queue entry looks as follows:
|
u_int16_t |
TransmittingNodeNum |
|
u_int16_t |
songNum |
|
u_int16_t |
TOS_msg_strength |
Each entry writes over the oldest entry in the queue.
The algorithm for deciding the song to sing is
as follows:
For all entries in our circular FIFO queue{
// calculate weighti for songNum i == 0 to 15
Weighti = sum of TOS_msg_strength
in circular
FIFO
queue for each songNum
}
Find Weightmax
== Largest Weight; WeightmaxSongNum
is song with Weightmax
Find Weightmin == Smallest non-zero Weight; WeightminSongNum is song with Weightmin
x = rand() % Probability
y = rand() % Silence
if(x == 0 )
SONG = WeightminSongNum
else if(y == 0)
Don't sing a song-- go to C.
else{
if(Weightmax < minThreshold)
||
((Weightmax > Threshold)
&& (You have already sung WeightmaxSongNum more than Repetition
times)) )
SONG = random song not among the last
three songs you've sung more than Repetition
times
else
SONG = WeightmaxSongNum
}
Notes:
The threshold and Repetition count are
meant to ensure that songs are
allowed to propagate through
the flock, but then die off after a while.
The repetition allows a
strong song to propagate to a large number of
nodes, but then once a song
has played for a while, it should die off.
This growth and dieoff is
accomplished by limiting the number of
repetitions once the
threshold is reached.
The count of the number of
times you've sung a song should be incremented
only when you sing the
weightMax song and the weight of that song is above
the threshold value.
This count is what you'll compare against Repetition
to determine whether or not
to add the song to the set of three songs that
you'll NOT choose from when
choosing a random song. This do-not-sing list
causes the very strong songs
to die off. Once a song falls off the
do-not-sing list (3 other
songs have been put on) its count should be
reset to 0.
TOS_Msg.strength is automatically updated with the packet
strength during reception.
You can set the transmission power level using the function
CC1000Control.SetRFPower(int)
Use the component CC1000ControlM.
Random numbers:
/* Return the next 16 bit random number */
async command uint16_t Random.rand()
Returns unsigned 16 bit number.
It's seeded from the node ID, so each mote will have a different number
sequence:
/* Initialize the seed from the ID of the node */
async command result_t Random.init()
See tos/system/RandomLFSR.nc
For the purposes of the final project assume that the timer
function takes milliseconds. If we give you a time of 1 second assume
if
you set a timer to fire in 1000ms it will fire 1 second later. For the
flock to be successful we all must use the same assumptions.
You can remove your light sensor, but you'll need to add a
sound transducer to your second mote.
Extra Credit: Improve
your sound quality by modifying your PWM software.
Hints: 1) consider using 5-bit instead of 8-bit PWM
2) consider using timer 3
CTC mode and output compare interrupt
NOBODY WILL HELP YOU WITH
THIS!!! DON'T ASK HOW!!!
Deliverables
Note: If you use the atomic statement, you MUST justify its
use in your comments in your source. The indiscriminate use of
atomic blocks will be count against you! Be sure to describe in your
comments why an atomic block was necessary, and why it is better than a
different design. Your compile should not show any atomic or async
warnings; we may check this during the grading process.
1) Use the test program provided by the course staff to test
your algorithm. (The test program will be distributed near the end of
this week) Feel free to modify the test program to generate more
elaborate testing scenarios and to share the testing scenarios with
other members of the class. The more testing completed before the final
check off the better.
2) A final test will be applied by the course staff to see
if your bird is following the algorithm protocol. This final test will
be given before the final and will account for the largest chunk of the
project grade. You should show up to the final test highly confident
that there are no errors.
3) Once your birds pass the final screening test, you may
proceed to the atrium for the final demonstration.
TURN-IN: Hand in a COMMENTED print-out of all
your code. Put your name(s) on the print-out.
End
|