This page, like the final project, is still under development. It will change frequently, so check it often as you are developing your Raven agent. This document, not including linked resources, was last changed on Wednesday, 18 March at 04:24 PM.
- Changes on 16 Mar 2009:
- Added pad byte to packet headers so that the 2-byte values in the payload are aligned on word boundaries if the beginning of the TOS_Msg struct is aligned.
- Fixed state machine logic (indentation) for echoing phrase packets.
- Added reply_to field to phrase_message
- Added global parameter for radio channel
- Made RSSI a signed value
- Changes on 12 Mar 2009:
- Added echo_probability variable and extra logic to WAIT_STATE so that nodes will sometimes echo what another node is saying, to boost volume in the Atrium.
- Changes on 11 Mar 2009:
- changed definition of LED color parameter to fit in an int16_t
- removed unused probability parameter
- Changes on 10 Mar 2009:
- clarified delay procedure
- Changes on 9 Mar 2009:
- Added timeout to WAIT_STATE to make slam self-starting and to ensure that it will be re-started if it dies out
- Added rules for choosing whether or not to play a phrase and which phrase to play
In this lab, you will:
The Raven Deconstructed is based on the concept of cellular automata and on the collective behavior of decentralized, self-organized systems. An example of this is the famous BOIDS, which is a visual simulation of a flying flock of birds, where each bird follows simple rules independently.
The variant of using separate physical agents derives from the field of swarm robotics.
We will appropriate the term "poetry slam," or "slam," to refer to our collective behavior in this project.
A Slam is a cloud of sound events of related phrases of a poem, in this case "The Raven" by Edgar Allen Poe, as read by James Earl Jones. The choices and the phrases derive from the execution of a set of common rules, without the intervention of any central control. Therefore, the resultant effect falls under the category of Emergent Behavior.
Slam sound-file phrases consist of several types:
Each set of partners will implement their own version of a “Cooperative compositional agent” using the specifications listed in this document. Your compiled code will run on both you and your partner’s “agents” for the Slams demonstration on the final exam day, 10:30 AM, on Thursday, March 19th in the atrium. Remember you need to qualify your “agent” before it can participate in the Slams demonstration. If for some reason you are unable to qualify your “agent”, an alternative “agent” program will be provided so that you may receive your participation points for the demonstration.
There will also be a dress rehearsal and testing session in the Atrium on Tuesday, March 17 from 6:30 to 10:00 PM.
This is the state in which your agent should start. In IDLE_STATE, your agent should be listening for control packets from the controller and the user interface should be active, but the agent is not actively participating in the slam.
During several states, your agent must delay. You should choose the amount of time to delay by evaluating the following expression:
phrase_len - trigvar >> 1 + rand() % trigvar
where phrase_len is the length of the audio file that the new sound is in response to, in milliseconds, trigvar is a global parameter, and rand() is the C function for generating a random integer.
While you are delaying, you should continue to receive and process packets:
You can implement delays with the usleep() call. The delay times do not need to be exact (in fact, some randomness is desirable.) However, don't call usleep() for the entire duration you want to delay; instead, sleep for some small timeslice, perform the tasks that you need to do while delaying, sleep some more, etc. until the entire delay has elapsed.
When choosing whether or not to respond to a phrase_message packet by playing another phrase, the following rules should be evaluated.
RSSIfactor is a boolean function of the RSSI of the node that triggered this evaluation of the rules. An RSSI value of a closer node should result in an RSSIfactor of zero, allowing sound to be played. A far away node should result in a non-zero RSSIfactor, meaning that packets from nodes that are too far away are essentially ignored. The exact details of the implementation of this function are up to you.
Phrases are categorized as complete thoughts, subject clusters (nouns), and verb clusters. The choice of which list you will play a phrase from is dependent on the type of the phrase that triggered this evaluation of the rules. The rules for this decision are as follows:
You should develop a user interface for your agent using the LED and LCD for output and the SuperBird's switches for input. Your interface should allow for the following:
Try to make your interface efficient. Remember that it will become a part of your agent program, so it should use resources effectively (e.g. don't update the display every time through a tight infinite loop.)
The LCD driver allows you to put graphics and text on the SuperBird's LCD. It allows you to update a rectangle on the LCD with raw pixel data, with or without an alpha channel, and also to draw text on the display with a few simple bitmap fonts. The driver is available through subversion/trac here. Note that you can download a zip archive of the entire driver at the bottom of the trac page.
Refer to the documentation.txt file in the driver source for information on how to use it. test.c also provides several examples of how to use the driver (make test should build it.)
A new version of the SuperBird driver that implements ioctls for reading the switches, among other things, is available here or as a package here. Documentation and a description of what all of the status bits mean is included in the superbird.h header file, which you should include in your program.
The status of the switches is also available through sysfs in /sys/bus/i2c/devices/0-004d/switches. This is how the sbstatus application you used to test the SuperBird reads the switches.
All packets should have the following format:
|1 byte||1 byte||1 byte||1 byte||0-24 bytes|
src and dest are the node numbers of the transmitter and receiver, respectively. This addressing scheme is independent of the TinyOS MAC layer, which you should always set to broadcast packets (0xFFFF) as you have done with previous labs. pad is an empty/ignored byte to eliminate alignment issues with the packets. The content and length of payload, if present, is defined by the packet type.
To make your code more readable and allow for easy changes to the packet structure, you should define all of your packet types as C structs in one of your header files. By casting a pointer to the data field of a TOS_Msg to your own type that defines the packet structure, you can access the packet fields by name. If we need to change the structure of a packet, you will then be able to do so by just editing the header file instead of fixing a bunch of manual indices.
You will be assigned a node number that will be your slam agent's address. This address should appear in the src field of all packets you transmit, and your agent should ignore packets that are not addressed to it or to the broadcast address.
There are two special node addresses:
This section defines the packet types that your agent must understand.
This packet is a request from the controller for the agent to change one of its global parameters. It should only be accepted from the controller's address.
|1 byte||1 byte||1 byte||1 byte||1 byte||2 bytes|
This packet from the controller tells the agent to stop any current sound and go to WAIT_STATE. If the agent is currently in IDLE_STATE and it receives a listen packet, it should go to WAIT_STATE.
|1 byte||1 byte||1 byte||1 byte|
This packet from the controller tells the agent to stop what it is doing, go to PLAY_STATE and to play the sound file indicated in the payload.
|1 byte||1 byte||1 byte||1 byte||1 byte||1 byte|
This packet from the controller tells the agent to stop any current sound and go to IDLE_STATE.
|1 byte||1 byte||1 byte||1 byte|
The phrase_message packet is the main packet type sent out by your agent. It contains information about what your agent is doing, such as the currently playing phrase.
|1 byte||1 byte||1 byte||1 byte||1 byte||1 byte||1 byte||1 byte||1 byte||1 byte|
This packet is triggered by the accelerometer, and indicates that the receiving agent should stop what it is doing and resend the startled_message packet after decrementing TTL.
|1 byte||1 byte||1 byte||1 byte||1 byte||1 byte||2 bytes|
As you receive phrase_message packets, you should store them in an 8-entry circular FIFO queue. The entries in this queue will be used to decide what to do next.
Entries in the queue should contain the following information:
Each new entry should overwrite the oldest entry in the queue. Make sure you initialize the data structure to a reasonable state when it starts out empty at the beginning of your program.
Your agent should have a set of global parameters that govern its behavior. These parameters should have consistent IDs across everyone's implementations and should be controllable with a set_global_parameter packet from the controller.
Note that the list of parameters and their default values will likely change as the project progresses. Expect new parameters to be added and the default values to change.
|0x05||silence||probability that this node decides to speak||10||1/x|
|0x06||hop_count||initial TTL for startle messages||3||hops|
|0x07||tx_power||transmit power that this node should use||20|
|0x08||led_color||color of the LED on the SuperBird (3 bytes, 0x0RGB)||#000|
|0x09||echo_probability||the probability that this node will echo another||4||1/x|
|0x0A||channel||the radio channel that this node is using||11|
Build your state machine as shown above. To begin, use a button push to move from state to state, showing the LED color change for each state. Use one button for trigger sound, another button for playing a phrase. Use the accelerometer to cause the startle sound.
Add code to handle and create the packet types defined in the specification document.
The source is here: TOS_MAC driver source
In SG2_CC2420.h is the following:
#define TEST_CCA_PIN() (GPLR(SG2_GPIO116_CC_CCA) & GPIO_bit(SG2_GPIO116_CC_CCA))
This is used in CC2420.c in void CC2420_try_to_send()
Let's adapt this for our purposes to determine if it's safe to transmit.