Programdesign (Sun SPOT): Forskelle mellem versioner
David (diskussion | bidrag) |
David (diskussion | bidrag) |
||
Linje 69: | Linje 69: | ||
<pre> | <pre> | ||
packet = packet_identifier packet_content | packet = packet_identifier packet_content | ||
packet_identifier = protocol_name protocol_version | packet_identifier = protocol_name protocol_version protocol_network_identifier | ||
protocol_name = "DTUSNP" | protocol_name = "DTUSNP" | ||
protocol_version = "0.1" | protocol_version = "0.1" | ||
protocol_network_identifier = "MichaelDavid" | |||
packet_content = data_to_base data_line | request_from_base address request_line | broadcast {spot | base} | packet_content = data_to_base data_line | request_from_base address request_line | broadcast {spot | base} | ||
data_line = "variables" {name type value}* | "functions" {name}* | "functionResult" name type value | "neighbours" {address rssi}* | data_line = "variables" {name type value}* | "functions" {name}* | "functionResult" name type value | "neighbours" {address rssi}* |
Versionen fra 10. apr. 2008, 20:05
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:
- 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.
- 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.
- Data. Protokollen giver mulighed for at sende variabelværdier til og fra sensorene. Datapakker håndteres konkret et andet sted.
- Ping. Hver frie sensor skal med passende interval gøre opmærksom på sin tilstedeværelse til basisstationen og nabosensorer.
- Kommunikations vedligeholdelseskommandoer, herunder:
- Hver frie sensor vil forsøge at oprette forbindelse til basisstationen. Der er således et konstant behov for, at sensorer kan kontakte basisstationen.
- 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.
- 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 data_line | request_from_base address request_line | broadcast {spot | base} data_line = "variables" {name type value}* | "functions" {name}* | "functionResult" name type value | "neighbours" {address rssi}* request_line = "get" get_type | "set" name value | "run" name {arguments}* get_type = name | "variables" | "functions" | "neighbours" name = alpha{alpha | number}* value = rnumber | alpha+ | bool rssi = number address = "0014.4F01." subaddr "." subaddr subaddr = hex{4} data_to_base = 0 request_from_base = 1 broadcast = 2 base = 0 spot = 1 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
"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.
Beskrevet med ord består en pakke altså af følgende:
- En identificering af pakken som er enten:
- 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.
- 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.
- Pakken er et broadcast til alle. Ingen yderligere data.
- 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:
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.