Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cooja with dynamically moving motes #2690

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/circular_motion/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CONTIKI = ../..

all: circular-motion
TARGET_LIBFILES = -lm

CONTIKI_WITH_RIME = 1
include $(CONTIKI)/Makefile.include
13 changes: 13 additions & 0 deletions examples/circular_motion/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!---Author: Manish Kausik H-->

Circular Motion
================

This folder contains a demo of how dynamic mobility can be implemented in contiki-cooja setup.

There are 2 global variables in the contiki code: pos_x and pos_y. These two variables are updated in accordance with the equation of a circle.
Cooja reads these variables to update the position of the motes in GUI.

For more information, please checkout tools/cooja/Readme_Mobility.md


50 changes: 50 additions & 0 deletions examples/circular_motion/circular-motion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "contiki.h"
#include "random.h"


#include <stdio.h>
#include <math.h>

static float pos_x=100;
static float pos_y=0;


/*---------------------------------------------------------------------------*/
PROCESS(circular_motion_process, "CIRCULAR MOTION example");
AUTOSTART_PROCESSES(&circular_motion_process);
/*---------------------------------------------------------------------------*/



/*---------------------------------------------------------------------------*/
PROCESS_THREAD(circular_motion_process, ev, data)
{
static struct etimer et;

PROCESS_BEGIN();
random_init(25);



static float ang_velocity=0.5;
static float del_t=0.001;


while(1) {

/* Delay 2-4 seconds */
etimer_set(&et, del_t*CLOCK_SECOND);

PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));



pos_x = pos_x - (pos_y*ang_velocity*del_t);
pos_y = pos_y + (pos_x*ang_velocity*del_t);


}

PROCESS_END();
}
/*---------------------------------------------------------------------------*/
55 changes: 55 additions & 0 deletions tools/cooja/Readme_Mobility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!---Author: Manish Kausik H-->

# Cooja Mobility
This version of cooja has the option of moving motes via a contiki process.

## How to use this verion of Cooja?
1. To compile and launch cooja, the steps are the same as the older cooja versions:
ant jar // to compile only
ant run // to compile and launch cooja

2. To setup mote tracking :
a. Go to File ---> New Simulation
b. In the New Simulation Dialog box, enable "Track Positions of Node" checkbox
c. Fill in all other details as per your needs
d. Press "Create".

Now you can operate Cooja just as before!

## What is expected from the contiki code?
The contiki code that you upload to the virtual motes in cooja MUST define 2 Global variables called "pos_x" and "pos_y".
They must be declared like this:
static float pos_x=<value>;
static float pos_y=<value>;

These are the variables that you MUST update, so that cooja can update positions in the GUI.
Note: If these variables are not declared as Global Variables or are not declared at all, a NULL_POINTER_EXCEPTION will be thrown by Cooja.
These Variables are relevant and compulsory only if the Track Position checkbox was enabled when creating the simulation.

## Some other important details
Cooja updates the positions of the motes every 100ms. Any changes made to pos_x and pos_y before 100ms time will not be reflected in Cooja.

## Examples
the example folder in contiki parent folder contains an example of a contiki process that makes the mote moving in a circle. The folder is named "circular-motion"

## Potential Application
The dynamic mobility feature has been introduced so that motes can make decisions on how to move on the run, while communicating with other motes.
This gives a platform for research on various path planning methods in tight sync with various communication stacks already available in contiki.


















131 changes: 122 additions & 9 deletions tools/cooja/java/org/contikios/cooja/Simulation.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@

package org.contikios.cooja;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;
import java.util.Vector;
import java.util.*;
import java.nio.*; // added by manish

import javax.swing.JOptionPane;

import org.apache.log4j.Logger;
import org.jdom.Element;

import org.contikios.cooja.dialogs.CreateSimDialog;
//import org.contikios.cooja.mspmote.interfaces.SkyPositionUpdate;
//import org.contikios.cooja.mspmote.MspMoteMemory; //added by manish
import org.contikios.cooja.mote.memory.MemoryInterface; //added by manish
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; //added by manish
import org.contikios.cooja.interfaces.Position; //added by manish

/**
* A simulation consists of a number of motes and mote types.
Expand All @@ -50,7 +50,9 @@
* changed simulation state, added or deleted motes etc are observed.
* To track mote changes, observe the mote (interfaces) itself.
*
* @author Fredrik Osterlind
* Mobility related features were added by Manish Kausik H
* @author Fredrik Osterlind, Manish Kausik H

*/
public class Simulation extends Observable implements Runnable {
public static final long MICROSECOND = 1L;
Expand Down Expand Up @@ -112,6 +114,77 @@ private void newMillisecond(long time) {
private boolean hasPollRequests = false;
private ArrayDeque<Runnable> pollRequests = new ArrayDeque<Runnable>();

/*
Edit by Manish Kausik H
*/
private boolean trackPositions;
//Set trackPostions
public void setTrackPositions(boolean v){
this.trackPositions=v;
}
//Get TrackPositions
public boolean getTrackPosiions(){
return this.trackPositions;
}

private Vector<MemoryInterface> memInterfaces=new Vector<MemoryInterface>();
private Vector<Position> posInterfaces=new Vector<Position>();

private Timer position_tracking_scheduler=null;
private int position_update_interval=100;

private void setupMemoryAndPositionInterfaces(){
for(int i=0;i<motes.size();i++){
memInterfaces.add(
motes.get(i).getMemory()
);
posInterfaces.add(
motes.get(i).getInterfaces().getPosition()
);
}
}
public void updatePositions(){
for(int i=0;i<motes.size();i++){
// Map<String, Symbol> SymbolMap = memInterfaces.get(i).getSymbolMap();
// Symbol symx=null;
// Symbol symy=null;
// for(String s:SymbolMap.keySet()){
// if(s.startsWith("pos_x")){symx=SymbolMap.get(s);break;}
// }
// for(String s:SymbolMap.keySet()){
// if(s.startsWith("pos_y")){symy=SymbolMap.get(s);break;}
// }
Symbol symx = memInterfaces.get(i).getSymbolMap().get("pos_x");
Symbol symy = memInterfaces.get(i).getSymbolMap().get("pos_y");

byte[] ans_x = memInterfaces.get(i).getMemorySegment(symx.addr,symx.size);
byte[] ans_y = memInterfaces.get(i).getMemorySegment(symy.addr,symy.size);

float pos_x = ByteBuffer.wrap(ans_x).order(ByteOrder.LITTLE_ENDIAN).getFloat();
float pos_y = ByteBuffer.wrap(ans_y).order(ByteOrder.LITTLE_ENDIAN).getFloat();

System.out.println("X = "+pos_x+" , Y = "+pos_y);

posInterfaces.get(i).setCoordinates(pos_x, pos_y, posInterfaces.get(i).getZCoordinate());
}
}

public void startTrackingScheduler(){
position_tracking_scheduler = new Timer();
position_tracking_scheduler.schedule(new TimerTask() {
@Override
public void run() {
updatePositions();
}
},500,position_update_interval);
}
public void stopTrackingScheduler(){
position_tracking_scheduler.cancel();
}
/*
End of Edit by Manish Kausik H
*/


/**
* Request poll from simulation thread.
Expand Down Expand Up @@ -280,6 +353,7 @@ public void run() {
/*logger.info("Executing event #" + EVENT_COUNTER++ + " @ " + currentSimulationTime + ": " + nextEvent);*/
nextEvent.execute(currentSimulationTime);


if (stopSimulation) {
isRunning = false;
}
Expand Down Expand Up @@ -481,7 +555,21 @@ public Collection<Element> getConfigXML() {
element.setText("" + getSpeedLimit());
config.add(element);
}
/*
Edit made by Manish Kausik H
*/
/* Position Tracking Related Information */
element = new Element("trackPositions");
element.setText(""+getTrackPosiions());
config.add(element);

element = new Element("Position_tracking_interval");
element.setText(""+position_update_interval);
config.add(element);

/*
End of Edit made by Manish Kausik H
*/
// Random seed
element = new Element("randomseed");
if (randomSeedGenerated) {
Expand Down Expand Up @@ -585,7 +673,21 @@ public boolean setConfigXML(Collection<Element> configXML,
setSpeedLimit(Double.parseDouble(text));
}
}

/*
Edit made by Manish Kausik H
*/
/* Max simulation speed */
if (element.getName().equals("trackPositions")) {
String text = element.getText();
setTrackPositions(Boolean.parseBoolean(text));
}
if (element.getName().equals("Position_tracking_interval")) {
String text = element.getText();
position_update_interval=Integer.parseInt(text);
}
/*
End of edit made by Manish Kausik H
*/
// Random seed
if (element.getName().equals("randomseed")) {
long newSeed;
Expand Down Expand Up @@ -846,6 +948,17 @@ public void run() {
}

motes.add(mote);
/*
Edit by Manish Kausik H
*/
if(getTrackPosiions()){
posInterfaces.add(mote.getInterfaces().getPosition());
memInterfaces.add(mote.getMemory());
}

/*
End of Edit by Manish Kausik H
*/
motesUninit.remove(mote);
currentRadioMedium.registerMote(mote, Simulation.this);

Expand Down
44 changes: 42 additions & 2 deletions tools/cooja/java/org/contikios/cooja/dialogs/CreateSimDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
/**
* A dialog for creating and configuring a simulation.
*
* @author Fredrik Osterlind
* Mobility related features were added by Manish Kausik H
* @author Fredrik Osterlind, Manish Kausik H
*/
public class CreateSimDialog extends JDialog {
private static final long serialVersionUID = 1L;
Expand All @@ -80,6 +81,7 @@ public class CreateSimDialog extends JDialog {

private JFormattedTextField randomSeed, delayedStartup;
private JCheckBox randomSeedGenerated;
private JCheckBox trackPos; //edit by Manish Kausik H

private JTextField title;
private JComboBox radioMediumBox;
Expand Down Expand Up @@ -313,7 +315,6 @@ public void actionPerformed(ActionEvent e) {
randomSeed.setValue(new Integer(123456));
}
}

});

horizBox.add(label);
Expand All @@ -323,6 +324,34 @@ public void actionPerformed(ActionEvent e) {
advancedBox.add(horizBox);
advancedBox.add(Box.createVerticalStrut(5));

/*
Edit by Manish Kausik H
*/
horizBox = Box.createHorizontalBox();
horizBox.setMaximumSize(new Dimension(Integer.MAX_VALUE,LABEL_HEIGHT));
horizBox.setAlignmentX(Component.LEFT_ALIGNMENT);
label = new JLabel("Track Positions of Node");
label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT));
trackPos = new JCheckBox();
trackPos.setToolTipText("Tracks the positions of each node and updates them periodically");
// trackPos.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// /*
// Some changes related to how often to update etc can come here
// */
// }
// });

horizBox.add(label);
horizBox.add(Box.createHorizontalStrut(173));
horizBox.add(trackPos);

advancedBox.add(horizBox);
advancedBox.add(Box.createVerticalStrut(5));

/*
End of Edit by Manish Kausik H
*/
vertBox.add(advancedBox);
vertBox.add(Box.createVerticalGlue());

Expand Down Expand Up @@ -363,6 +392,17 @@ public void actionPerformed(ActionEvent e) {
mySimulation.setRandomSeed(((Number) randomSeed.getValue()).longValue());
}

/*
Edit Made by Manish Kausik H
*/
if(trackPos.isSelected()){
mySimulation.setTrackPositions(true);
}else{
mySimulation.setTrackPositions((false));
}
/*
End of Edit made by Manish Kausik H
*/
mySimulation.setDelayedMoteStartupTime((int) ((Number) delayedStartup.getValue()).intValue()*Simulation.MILLISECOND);

dispose();
Expand Down
Loading