Programdesign (Sun SPOT): Forskelle mellem versioner

Fra DAMNWiki
Spring til navigationSpring til søgning
 
(9 mellemliggende versioner af 2 andre brugere ikke vist)
Linje 73: Linje 73:
protocol_version = "0.1"
protocol_version = "0.1"
protocol_network_identifier = "MichaelDavid"
protocol_network_identifier = "MichaelDavid"
packet_content = data_to_base id data_line | request_from_base id address request_line | broadcast {spot | base}
packet_content = data_to_base id base_address data_line |
                request_from_base id base_address address request_line |
                broadcast {spot | base}
data_line = variables {name type value}* | functions {name type {name type}* "EOF"}* |  
data_line = variables {name type value}* | functions {name type {name type}* "EOF"}* |  
             function_result name type value | neighbours {address rssi {spot | base}}* |
             function_result name type value | neighbours {address rssi {spot | base}}* |
             packet_ack
             packet_ack {yes | no} | aodv_update source {destination next_hop}*
request_line = get get_type | set name value | run name {arguments}* | route address address
request_line = get get_type | set name value | run name {arguments}* | route address address | routing_mode {central | distributed}
get_type = specific_variable name | variables | functions | neighbours
get_type = specific_variable name | variables | functions | neighbours


Linje 84: Linje 86:
run = 2
run = 2
route = 3
route = 3
routing_mode = 4


variables = 0
variables = 0
Linje 91: Linje 94:
function_result = 4
function_result = 4
packet_ack = 5
packet_ack = 5
aodv_update = 6


name = alpha{alpha | number}*
name = alpha{alpha | number}*
Linje 97: Linje 101:
id = number
id = number


base_address = address
address = "0014.4F01." subaddr "." subaddr
address = "0014.4F01." subaddr "." subaddr
subaddr = hex{4}
subaddr = hex{4}
Linje 103: Linje 108:
request_from_base = 1
request_from_base = 1
broadcast = 2
broadcast = 2
source = number (long)
destination = number (long)
next_hop = number (long)


base = 0
base = 0
spot = 1
spot = 1
central = 0
distributed = 1
yes = 1
no = 0


type = byte | int | long | float | double | char | string | boolean  
type = byte | int | long | float | double | char | string | boolean  
Linje 117: Linje 132:
boolean = 7
boolean = 7
void = 8
void = 8
null = 9
</pre>
</pre>



Nuværende version fra 4. jun. 2008, 09:39

Denne artikel indeholder informationer omkring den konkrete udformning af Sun SPOT programmet. Designet ligger tæt op ad kravspecifikationen

Generelt

Vi vil som altid i forbindelse med grafisk brugerflade programmering benytte os af model-view-control design mønstret.

Model

Modellen er den del af systemet, som skal håndtere alle data, hvilket inkluderer positionsbestemmelse samt protokol. Disse punkter bliver behandlet selvstændigt nedenfor.

Modellen kommunikerer med den grafiske brugerflade igennem interfaces. Brugerfladen må ikke i sig selv indeholde vigtige oplysninger såsom variabler, sensor lister osv. Disse gemmes og vedligeholdes i modellen.

Protokol

Protokollen opdeles som i kravspecifikationen i to dele. En for basisstationen og en for de frie sensorer.

Grundlæggende dataudveksling og -manipulering

I vores tidligere Sun SPOT projekter, har vi savnet bedre muligheder for at manipulere med vores frie sensorer i runtime. Tidligere har vi været nød til at overføre en ny version af programmet til sensoren hver gang en ændring skulle foretages. Dette er meget tidskrævende, hvis man f.eks. sidder i en debugging situation. Til dette projekt forestiller vi os en løsning, som giver mulighed for både at læse og skrive en sensors variabler samt kalde bestemte metoder direkte fra basisstationen i runtime. Dette vil gøre hele systemet mere fleksibelt, da vi derved lettere kan teste og debugge samt eksperimentere med sensoreren uden at skulle overføre nye programmer hele tiden.

Løsningen bygges op omkring datagram pakker!

Generelt

Husk:

setMaxBroadCastHops(1);
Variabler

Vi er nød til at håndtere variablerne på sensoren anderledes end normalt. Helt konkret skal alle de variabler som basisstationen skal kunne manipulere med være objekter, der organiseres i en Hashtable. Nøglerne i denne Hashtable er variabelnavnene og til hver nøgle knytter sig et objekt som repræsenterer variablens værdi. Basisstationen kan få tilsendt en enkelt variabel eller en hel liste med variabelnavne i en pakke, hvis de f.eks. skal vises i en grafisk brugergrænseflade.

Metoder

For at give basisstationen mulighed for at kalde en sensors metoder, skal følgende overvejelser gøres:

  1. Må en metode kunne returnere en værdi/objekt?
Dette kan muligvis godt lave sig gøre, så længe den værdi der returneres er en primitiv datatype (int, long, double, string, boolean mm.). Når metoden returere sin værdi, skal den dermed sendes i en pakke tilbage til basisstationen.
  1. Må en metode tage argumenter?
Ja, når basisstationen sender en pakke med et metodekald til sensoren, skal pakken indeholde de argumenter som metoden kræver. Basisstationen ved ikke hvilke argumenter en bestemt metode kræver, det skal brugeren/programmøren vide!

Basisstation

Basisstationenen skal kunne holde styr på mange ting på en gang. Det er derfor nødvendigt at benytte trådet programmering.

Opgaver (ukomplet liste):

  • Håndtering af indkomne datapakker.
    1. Data. Protokollen giver mulighed for at sende variabelværdier til og fra sensorene. Datapakker håndteres konkret et andet sted.
    2. Ping. Hver frie sensor skal med passende interval gøre opmærksom på sin tilstedeværelse til basisstationen og nabosensorer.
    3. Kommunikations vedligeholdelseskommandoer, herunder:
      1. Hver frie sensor vil forsøge at oprette forbindelse til basisstationen. Der er således et konstant behov for, at sensorer kan kontakte basisstationen.
      2. Hvis en sensor pludselig mister forbindelse til en anden sensor, skal dette rapporteres. Konkret "opdages" en mistet forbindelse ved at en ping pakke udebliver i længere tid end normalt.
      3. Basisstationen skal kende alle sensorer i netværket. Derfor skal alle frie sensorer sende en liste over nabosensorer, så basisstationen på den måde kan blive bekendt med eventuelle sensorer, som ligger uden for dens rækkevidde.
  • Håndtering af data.
Som beskrevet i kravspecifikationen skal det være muligt til hver en tid at se en sensors målinger. Vi ved endnu ikke, om disse målinger skal gemmes eller blot være den seneste måling.
Pseudokode
Broadcast til alle
    Fortæl at det er basisstatation, der broadcaster
Lyt til alle
    Opfanges et signal, tilføj til naboliste

Fri sensor (Sun SPOT)

De frie sensorer er primært kommunikationled i en kæde/rute, som forbinder hele sensornetværket. Kravspecifikationen beskriver, hvad de frie sensorer skal kunne, hvilket uddybes her. Der er ligesom for basisstationen behov for at benytte trådet programmering.

Hver af de følgende opgaver håndteres af en enkelt tråd:

  • Oprettelse af forbindelse og efterfølgende pings til både nabosensorer og basisstation.
  • Modtagelse og distribuering af indkommende opgaver samt forespørgsler.
  • Opgavehåndtering, herunder:
    • Videresendelse af beskeder.
    • Besvarelse på forespørgsler.
Opgave/forespørgelsprotokol

Overvejelse: Skal en sensor kunne sende en slags fejlmeddelser til basisstationen? F.eks. hvis der sendes ugyldige argumenter til et metodekald

packet = packet_identifier packet_content
packet_identifier = protocol_name protocol_version protocol_network_identifier
protocol_name = "DTUSNP"
protocol_version = "0.1"
protocol_network_identifier = "MichaelDavid"
packet_content = data_to_base id base_address data_line |
                 request_from_base id base_address address request_line |
                 broadcast {spot | base}
data_line = variables {name type value}* | functions {name type {name type}* "EOF"}* | 
            function_result name type value | neighbours {address rssi {spot | base}}* |
            packet_ack {yes | no} | aodv_update source {destination next_hop}*
request_line = get get_type | set name value | run name {arguments}* | route address address | routing_mode {central | distributed}
get_type = specific_variable name | variables | functions | neighbours

get = 0
set = 1
run = 2
route = 3
routing_mode = 4

variables = 0
functions = 1
neighbours = 2
specific_variable = 3
function_result = 4
packet_ack = 5
aodv_update = 6

name = alpha{alpha | number}*
value = rnumber | alpha+ | bool
rssi = number
id = number

base_address = address
address = "0014.4F01." subaddr "." subaddr
subaddr = hex{4}

data_to_base = 0
request_from_base = 1
broadcast = 2

source = number (long)
destination = number (long)
next_hop = number (long)

base = 0
spot = 1

central = 0
distributed = 1

yes = 1
no = 0

type = byte | int | long | float | double | char | string | boolean 
byte = 0
int = 1
long = 2
float = 3
double = 4
char = 5
string = 6
boolean = 7
void = 8
null = 9

"hex" betegner et hexadecimal tal. Altså 0 til F. "alpha" betegner bogstaver fra a-z og A-Z. "number" er et positivt heltal bestående af cifrene 0-9. "rnumber" er et rationelt tal. "bool" er en sandhedsværdi, som kan være enten true eller false. DTUSNP i protokol_name er en forkortelse for DTU Sensor Network Protocol.

Alle steder hvor der står et specifikt tal, er det et tal af Java type byte.

Beskrevet med ord består en pakke altså af følgende:

  • En identificering af pakken som er enten:
    1. Pakken er data, der skal sendes til basen. De efterfølgende linjer består af de data, som basisstationen skal modtage. Disse kan være enten:
      • Variabelnavne, typer og værdier.
      • Funktionsnavne.
      • Et funktionsresultat og type.
      • Nabosensorers adresser og signalstyrke.
    2. Pakken skal sendes til en bestemt fri sensor. Der specificeres yderligere:
      • Adressen på den frie sensor, der skal sendes til.
      • Om der skal læses data fra den frie sensor eller skrives til den, eller om der skal køres en funktion på sensoren.
    3. Pakken er et broadcast til alle. Ingen yderligere data.
Pseudokode

Dette punkt vil løbende blive opdateret eftersom protokollen udvikler sig.

Tråd 1: Oprettelse af forbindelse og efterfølgende pings

while (true)
{
    while (!connected)
    {
        broadcast(this.id);
        pause(random long); // milisecs
    }

    while (connected)
    {
        sendToBaseStation(ping & sensordata);
        pause(10000); // milisecs
    }
}

Tråd 2: Modtagelse af opgaver samt distribuering:

while (true)
{
    while (connected)
    {
        receive(request);
        distributeRequest(request); // Tilføj til en kø eller lignende
        pause(100);
    }
    pause(5000);
}

Tråd 3: Opgavehåndtering

while (true)
{
    while (!requestQueue.isEmpty)
    {
        handleRequest(requestQueue.poll); // Videresend besked
        pause(100);
    }
    pause(1000);
}

Positionsbestemmelse

Model design

Ovenstående beskrivelser giver anledning til følgende programopbygning for modellen.

View - GUI

GUI design

Husk

  • For at kunne understøtte større netværk med mere end to led, skal hver sensor have en hashtable med adresser over de sensorer som den er mellemled for. Til hver adresse i denne hashtable skal knyttes adressen på den nabo sensor, der skal sendes til for at komme et skridt tættere på sensoren yderst i netværket.