Permalink
Browse files

checkpoints, auto settings fetching protocol (on mote bootup)

ReportingMote software:
	* added tabulaRasa flag. When node is freshly booted, tabulaRasa=true, what means it is in default settings. It keeps sending identification packets regurarly until some command is received from base station (as indicator that packet was received and settings will be pushed to node)
	* BUG: single identification packet right after boot up is problem to send. It sends only 2 packets, drived by timer. FIXME.
	
Workers:
	* game worker: when received identification packet with tabulaRasa flag, settings are automatically pushed to node to minimize latency due to suddenly mote reset.
	* game: checkpoints added. This version is based on static checkpoint register, current checkpoint is checkpoint with maximal score thresholded RSSI limit. 
	* screen: checkpoint textual information. No graphical.

todo: game logic with checkpoint, graphical representation of checkpoints.
  • Loading branch information...
1 parent 27c44de commit 25b6e223008beb054a3e6b9ee5490280b4cda31d ph4r05 committed Sep 22, 2011
@@ -46,9 +46,21 @@
public static final int COMMAND_SENSORREADING=21;
public static final int COMMAND_SETSAMPLESENSORREADING=24;
+ //
// pinning
+ //
public static final int COMMAND_SETPIN=22;
public static final int COMMAND_GETPIN=23;
+
+ //
+ // settings
+ //
+ /**
+ * Fetching is request sent to base station after booting node up.
+ * Base station will then re-send node settings from node register to
+ * booted node (can be after reset already)
+ */
+ public static final int COMMAND_FETCHSETTINGS=25;
// identity types
public static final int NODE_STATIC=1;
@@ -142,17 +142,36 @@ public void sendMyCommandToSelectedNodes(CommandMsg payload){
logToTextarea("Cannot add commands to send queue.", JPannelLoggerLogElement.SEVERITY_ERROR);
}
- for(int i=0, cnI=selectedNodes.length; i<cnI; i++)
- {
- // increment send counter
- counter+=1;
- payload.set_command_id(counter);
+ for(int i=0, cnI=selectedNodes.length; i<cnI; i++) {
+ this.sendMyCommandToNode(payload, selectedNodes[i]);
+ }
- // send packet
- logToTextarea("Sending command msg=" + payload.toString());
- this.getMsgSender().add(selectedNodes[i], payload, "CommandMsg for="+selectedNodes[i]+"; Command_code="+payload.get_command_code());
+ } catch (Exception ex) {
+ logToTextarea("NullPointer exception: " + ex.getMessage(), JPannelLoggerLogElement.SEVERITY_ERROR);
+ Logger.getLogger(RSSI_graphApp.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * Send selected defined packet to node.
+ * Another methods may build custom command packet, it is then passed to this method
+ * which sends it to all selected nodes
+ *
+ * @param CommandMsg payload data packet to send. Is CommandMessage
+ */
+ public void sendMyCommandToNode(CommandMsg payload, int nodeId){
+ try {
+ if (this.getMsgSender().canAdd()==false){
+ logToTextarea("Cannot add commands to send queue.", JPannelLoggerLogElement.SEVERITY_ERROR);
}
+
+ // increment send counter
+ counter+=1;
+ payload.set_command_id(counter);
+ // send packet
+ logToTextarea("Sending command msg=" + payload.toString());
+ this.getMsgSender().add(nodeId, payload, "CommandMsg for="+nodeId+"; Command_code="+payload.get_command_code());
} catch (Exception ex) {
logToTextarea("NullPointer exception: " + ex.getMessage(), JPannelLoggerLogElement.SEVERITY_ERROR);
Logger.getLogger(RSSI_graphApp.class.getName()).log(Level.SEVERE, null, ex);
@@ -177,6 +196,24 @@ public void sendSimpleCommand(int commandCode, int commandData, int[] auxData){
}
/**
+ * Sends simple commands to destination nodes.
+ * Simple command consist of command code and single command data.
+ *
+ * @param commandCode command code.
+ * @param commandData command data to send
+ * @param auxData auxiliary data to send
+ * @param destination node id to send command
+ */
+ public void sendSimpleCommand(int commandCode, int commandData, int[] auxData, int destination){
+ CommandMsg payload = new CommandMsg();
+ payload.set_command_version((short) 0);
+ payload.set_command_code((short) commandCode);
+ payload.set_command_data(commandData);
+ payload.set_command_data_next(auxData != null ? auxData : new int[] {0,0,0,0});
+ this.sendMyCommandToNode(payload, destination);
+ }
+
+ /**
* Sets General Input Output pin
*
* @param pinnum
@@ -391,7 +428,7 @@ public void messageReceived(int to, Message msg) {
// get node for sender
GenericNode node = null;
- if (this.nodeRegister.existsNode(source)){
+ if (this.nodeRegister != null && this.nodeRegister.existsNode(source)){
node = this.nodeRegister.getNode(source);
// automatically set lastSeen indicator
@@ -404,7 +441,6 @@ public void messageReceived(int to, Message msg) {
// is sensor reading?
// if so update record in node register and trigger update
if (Message.get_command_code() == (short) MessageTypes.COMMAND_SENSORREADING
- && this.nodeRegister != null
&& node!=null){
if (Message.get_command_data_next() != null
@@ -0,0 +1,151 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package rssi_graph.game;
+
+import rssi_graph.localization.CoordinateRecord;
+
+/**
+ * Game checkpoint.
+ * Represents static positions on ring whose player must pass to complete one round.
+ *
+ * Checkpoint is activated/passed iff RSSI received is over defined threshold
+ * @author ph4r05
+ */
+public class GameCheckpoint {
+ /**
+ * Node of checkpoint
+ */
+ protected int checkpointId;
+
+ /**
+ * Node id of checkpoint
+ */
+ protected int nodeId;
+
+ /**
+ * RSSI of input signal to activate this checkpoint
+ */
+ protected double rssi_threshold;
+
+ /**
+ * Position of checkpoint
+ */
+ protected CoordinateRecord position = null;
+
+ /**
+ * Constructor
+ * @param nodeId
+ * @param checkpointId
+ * @param rssi_threshold
+ */
+ public GameCheckpoint(int checkpointId, int nodeId, double rssi_threshold) {
+ this.nodeId = nodeId;
+ this.checkpointId = checkpointId;
+ this.rssi_threshold = rssi_threshold;
+ }
+
+ /**
+ * Constructor
+ * @param nodeId
+ * @param checkpointId
+ */
+ public GameCheckpoint(int checkpointId, int nodeId) {
+ this.nodeId = nodeId;
+ this.checkpointId = checkpointId;
+ }
+
+ /**
+ * Constructor
+ * @param checkpointId
+ */
+ public GameCheckpoint(int checkpointId) {
+ this.checkpointId = checkpointId;
+ }
+
+ /**
+ * Constructor
+ */
+ public GameCheckpoint() {
+ }
+
+ /**
+ * True if checkpoint is active now
+ *
+ * @param curRssi
+ * @return
+ */
+ public boolean isActive(double curRssi){
+ return this.getRssi_threshold() < curRssi;
+ }
+
+ /**
+ * Score in RSSI values. Higher the score is, the closer is node to checkpoint.
+ * Can be used to compare multiple active checkpoints.
+ *
+ * @param curRssi
+ * @return
+ */
+ public double getActiveScore(double curRssi){
+ return curRssi - this.getRssi_threshold();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final GameCheckpoint other = (GameCheckpoint) obj;
+ if (this.nodeId != other.nodeId) {
+ return false;
+ }
+ if (this.checkpointId != other.checkpointId) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 97 * hash + this.nodeId;
+ hash = 97 * hash + this.checkpointId;
+ return hash;
+ }
+
+ public int getCheckpointId() {
+ return checkpointId;
+ }
+
+ public void setCheckpointId(int checkpointId) {
+ this.checkpointId = checkpointId;
+ }
+
+ public int getNodeId() {
+ return nodeId;
+ }
+
+ public void setNodeId(int nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ public double getRssi_threshold() {
+ return rssi_threshold;
+ }
+
+ public void setRssi_threshold(double rssi_threshold) {
+ this.rssi_threshold = rssi_threshold;
+ }
+
+ public CoordinateRecord getPosition() {
+ return position;
+ }
+
+ public void setPosition(CoordinateRecord position) {
+ this.position = position;
+ }
+}
@@ -0,0 +1,111 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package rssi_graph.game;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Register of known checkpoints
+ *
+ * @author ph4r05
+ */
+public class GameCheckpointRegister {
+
+ protected Map<Integer, GameCheckpoint> checkpointDb = null;
+
+ protected Map<Integer, GameCheckpoint> checkpointDbByNodeId=null;
+
+ /**
+ * Arbitrary init method
+ *
+ * @UGLY_CODE: this is programmed by bad way, I know it, but there is no time left
+ * and I need to have it working. It may be later refactored to bether form,
+ * but now it must be enought.
+ */
+ public void initThis(){
+ this.checkpointDb = new HashMap<Integer, GameCheckpoint>(24);
+ checkpointDbByNodeId = new HashMap<Integer, GameCheckpoint>(24);
+
+ // manualy inserting checkpoints to source code (and thresholds)
+ this.checkpointDb.put(Integer.valueOf(1), new GameCheckpoint(1, 17, 0.0));
+ this.checkpointDb.put(Integer.valueOf(2), new GameCheckpoint(2, 19, 0.0));
+ this.checkpointDb.put(Integer.valueOf(3), new GameCheckpoint(3, 20, 0.0));
+
+ // sync maps
+ this.syncMaps();
+ }
+
+ /**
+ * Returns iterator for key set of db
+ */
+ public Iterator<Integer> getKeyIterator(){
+ return this.checkpointDb.keySet().iterator();
+ }
+
+ /**
+ * Returns checkpoint with given ID from database
+ *
+ * @param id
+ * @return
+ */
+ public GameCheckpoint getCheckpoint(Integer id){
+ if (id==null) return null;
+ if (this.getCheckpointDb().containsKey(id)==false) return null;
+ return this.getCheckpointDb().get(id);
+ }
+
+ /**
+ * Return checkpoint by node id
+ * @param nodeId
+ * @return
+ */
+ public GameCheckpoint getCheckpointByNodeId(Integer nodeId){
+ if (this.getCheckpointDbByNodeId().containsKey(nodeId)==false) return null;
+ return this.getCheckpointDbByNodeId().get(nodeId);
+ }
+
+ /**
+ * Returns size of checkpoint database
+ *
+ * @return
+ */
+ public int getDbSize(){
+ return this.checkpointDb.size();
+ }
+
+ /**
+ * Synchronize maps
+ */
+ protected void syncMaps(){
+ this.checkpointDbByNodeId.clear();
+ Iterator<Integer> it = this.getKeyIterator();
+
+ while(it.hasNext()){
+ GameCheckpoint check = this.checkpointDb.get(it.next());
+ this.checkpointDbByNodeId.put(Integer.valueOf(check.getNodeId()), check);
+ }
+ }
+
+ /**
+ * Is checkpoint database empty?
+ */
+ public boolean isEmpty(){
+ return this.checkpointDb.isEmpty();
+ }
+
+ public Map<Integer, GameCheckpoint> getCheckpointDb() {
+ return checkpointDb;
+ }
+
+ public void setCheckpointDb(Map<Integer, GameCheckpoint> checkpointDb) {
+ this.checkpointDb = checkpointDb;
+ }
+
+ public Map<Integer, GameCheckpoint> getCheckpointDbByNodeId() {
+ return checkpointDbByNodeId;
+ }
+}
Oops, something went wrong.

0 comments on commit 25b6e22

Please sign in to comment.