SASO 2013 Demonstration

Bullseye

Goal: Produce an LED pattern dependent on distance from a source.
;;Bullseye (def bullseye (src) (let ((d (distance-to src))) (if (< d 15) (red 1) (if (< d 30) (green 1) (if (< d 45) (blue 1) 0))))) ;; Click on a node and hit 't' to toggle sense 1 (bullseye (sense 1))

Voronoi

Goal: A Voronoi diagram divides space into a number of regions based on a set of seed sites. Our goal is to dynamically create a Voronoi diagram based on a set of seeds with an activated sensor.
;;Voronoi (def uid2rgb (uid f) (let* ((r (mod uid f)) (g (- (mod uid (pow f 2)) r)) (b (- (mod uid (pow f 3)) (+ r g)))) (rgb (tup (/ r f) (/ g (pow f 2)) (/ b (pow f 3)))))) (def voronoi (src showedge) (let* ((closest-src (broadcast src (mid))) (edge (any-hood (not (= (nbr closest-src) closest-src)))) (vertex (and edge (let ((max-nbr (max-hood (if (not (= closest-src (nbr closest-src))) (nbr closest-src) -1))) (min-nbr (min-hood (if (not (= closest-src (nbr closest-src))) (nbr closest-src) (inf))))) (not (= max-nbr min-nbr)))))) (if (and edge showedge) (if vertex (rgb (tup 1 0 0)) (rgb (tup 0 0 0.5))) (uid2rgb closest-src 10)) (tup closest-src edge))) ;; Click on a node and hit 't' to toggle sense 1 ;; Each "sense 1" node is a seed of the Voronoi diagram (voronoi (sense 1) 1)

Channel

Goal: to identify the set of nodes within ten meters of the shortest path between two devices.
;;Channel (def channel (src dst width) (let* ((d (distance src dst)) (trail (<= (+ (gradient src) (gradient dst)) (+ d 0.01))) ) (dilate trail width))) ;; Click on a node and hit 't' to toggle sense 1 ;; Then click on another node and hit 'y' to toggle sense 2 (blue (channel (sense 1) (sense 2) 10))

Dither

Goal: to demonstrate node mobility using a random motion dispersion technique.
;;Dither ;; Click and drag on the simulation to rotate in 3 dimensions ;; Use the two-finger scrolling gesture to zoom in and out (mov (* 0.1 (dither)))

Energy-Aware Routing

Goal: to demonstrate energy-aware packet routing by gradient descent. Every device with a packet picks the lowest value neighbor and tries to hand a packet to it. The handoff will be retried until the neighbor takes up the packet. If there is no appropriate neighbor, the packet is dropped. By incorporating energy cost into metrics, this energy-routing function will change the packets' paths over time.

;; Click on a node and hit 't' to toggle sense 1 ;; Then click on another node and hit 'y' to toggle sense 2 ;; Nodes will be green when they have lots of energy, and shade ;; towards red as they run out of energy. ;; Packets are blue as they flow through the nodes. ;; Notice that the packets move farther than farther from the ;; shortest path as the energy decreases. ;;Energy-aware Routing ;; Like a gradient, except that it replaces the metric (def distance-to-metric (src init metric maxhop) (1st (rep (tup d v) (tup (inf) 0) (mux src (tup (init) 0) ; source (mux (any-hood+ (<= (+ (nbr d) (metric) (* v (+ (nbr-lag) (dt)))) d)) (tup (min-hood+ (+ (nbr d) (metric))) 0) (let ((v0 (if (= (dt) 0) 1 (/ (maxhop) (* (dt) 12))))) (tup (+ d (* v0 (dt))) v0))))))) ;; This is a simple utility function for doing gradient descent (def choose-lowest-neighbor (d) (2nd (min-hood (mux (< (nbr d) d) (tup (nbr d) (nbr (mid))) (tup (inf) -1))))) ;; The purpose of this is to demonstrate packet routing by gradient descent ;; Every device with a packet picks the lowest value neighbor and ;; tries to hand a packet to it. The handoff will be retried until ;; the neighbor takes up the packet. ;; If there is no appropriate neighbor, the packet is dropped ;; Note that this can be clearly improved by adding deconfliction ;; strategies to decrease the likelihood of neighbors trying to ;; route packets to the same locations (def route-packets (input distance) (rep packet 0 (let ((best-hop (choose-lowest-neighbor distance))) (mux input input ; input wipes any packet already there (mux packet (mux (any-hood (muxand (< (nbr distance) distance) (= (nbr packet) packet))) 0 ; packet has moved forward; discard local copy (mux (= best-hop -1) 0 ; if there's nowhere to go, wipe the packet packet)) ; otherwise hold for passing on (max-hood (mux (= (nbr best-hop) (mid)) (nbr packet) 0))))))) ;; By incorporating energy cost into metrics, this energy-routing ;; function will change where packets go over time (def energy-routing (dst packet-src init-energy) (letfed ((energy init-energy (let* ((stretch (/ init-energy energy)) (d (distance-to-metric dst (fun () 0) (fun () (* (nbr-range) stretch)) (fun () (* (radio-range) stretch)))) (packets (route-packets packet-src d))) (blue (> packets 0)) ;(green (* d 0.1)) (mux dst init-energy (max 0 (- energy (* (dt) (+ 0.01 (mux packets 1 0))))))))) energy)) ;; Once every n seconds, return true1; otherwise return false (def flash-per-n (n) (letfed ((v (rnd 0 n) (if (> v n) (- n (dt)) (if (> v (dt)) (- v (dt)) n)))) (= v n))) ;; This injects a sequence of numerically increasing packets, so that we can ;; test the integrity of the sequence (def test-packet-source (src period) (let ((inject (and src (flash-per-n period)))) (letfed ((packet-id 0 (mux inject (+ 1 packet-id) packet-id))) (mux inject packet-id 0)))) (let ((energy (* 0.01 (energy-routing (sense 1) (test-packet-source (sense 2) 10) 100)))) (red (- 1 energy)) (green energy))

Flock

Goal: to demonstrate a simple flocking behavior.
;;Flock (def flock (dir) (rep v (tup 0 0 0) (let ((d (normalize (int-hood (if (< (nbr-range) 5) (* -1 (normalize (nbr-vec))) (if (> (nbr-range) 10) (* 0.2 (normalize (nbr-vec))) (normalize (nbr v)))))))) (normalize (+ dir (mux (> (vdot d d) 0) d v)))))) (let ((phase (* (timer) 0.1))) (mov (flock (tup (sin phase) (cos phase) 0))))