Skip to content

Commit

Permalink
omni directional agents
Browse files Browse the repository at this point in the history
  • Loading branch information
klavins committed Mar 7, 2020
1 parent 66565bf commit 8ab5a7c
Show file tree
Hide file tree
Showing 28 changed files with 642 additions and 58 deletions.
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ src/
my_robot.cc // Contains the implementation of the classes in my_robot.h
```

Note that `esm generate` only makes directional robots. For an omni-directional robot, you need to subsequently edit the `defs/my_robot.json` file and change "shape" to "omni" and add a "radius" field (see below). 🔷 New in 1.1.

To compile the robot code, do
```
make
Expand Down Expand Up @@ -90,6 +92,11 @@ enviro
```
and see a green square in the environment. That's your robot!

More Examples
===

See the [examples directory](https://github.com/klavinslab/enviro/tree/master/examples) for more examples of agent definitions and controllers.

Defining Agents
===

Expand Down Expand Up @@ -118,7 +125,11 @@ Either "dynamic" or "static". If "dynamic", then the agent will move, have mass,
A string describing the agent.

> `shape`<br>
A list of pairs of the form `{ "x": 10, "y": 12 }` defining the vertices of a polygon. The physics engine will use this to determine the moment of initial and collision shape of the robot, and the user interface will use it to render the agent. All points are relative to the robot's center.
> ***polygon shaped:*** A list of pairs of the form `{ "x": 10, "y": 12 }` defining the vertices of a polygon. The physics engine will use this to determine the moment of initial and collision shape of the robot, and the user interface will use it to render the agent. All points are relative to the robot's center.<br>
> ***circular:*** The string "omni", which makes a circular omni-directional agent. If you choose this option, you also need to specify a "radius". &#x1F537; New in 1.1.
> `radius`<br>
The radius of a circular, omnidirectional robot. Only used when the `shape` field is "omni". &#x1F537; New in 1.1.

> `friction`<br>
An object with three numerical fields, `collision`, `linear`, and `rotational` defining the fricition coefficients of the robot with other robots and with the environment. Note that the latter two coefficients are only used if you apply a control in your `update()` methods such as `damp_movement()` or `track_velocity()`.
Expand Down Expand Up @@ -189,10 +200,13 @@ This method returns the position of the agent. The `cpVect` structure has fields
> `cpVect velocity()`<br>
This method returns the velocity of the agent. The `cpVect` structure has fields `x` and `y` that can be treated as `doubles`.
> `cpFloat angle()`<br>
> `x()`, `y()`, `vx()`, `vy()`<br>
The horizontal and verical positions, and the horizonal and vertical velocities -- separated out so you do not need to about the structure. &#x1F537; New in 1.1.
> `double angle()`<br>
This method returns the angle of the agent in radians and can be treated as a `double`.
> `cpFloat angular_velocity()`<br>
> `double angular_velocity()`<br>
This method returns the angular velocity of the agent in radians per second and can be treated as a `double`.
> `int id()`<br>
Expand All @@ -208,7 +222,7 @@ This method makes the agent attempty to track the given linear and angular veloc
This method slows the agent down using the linear and angular friction coefficients defined in the agent's JSON definition file.
> `void move_toward(double x, double y, double vF=75, double vR=20)`<br>
This method attepts to move the agent to the given (x,y) location. If something in the way, the agent will not get there. The robot simultaneously attempts to rotate so that it is pointing toward the target and also moves forward, going faster as its angular error is reduced. The optional arguments are the desired velocities of rotation and forward motion.
This method attepts to move the agent to the given (x,y) location. If something in the way, the agent will not get there. The robot simultaneously attempts to rotate so that it is pointing toward the target and also moves forward, going faster as its angular error is reduced. The optional arguments are the gains on the rotational and forward motion.
> `void teleport(double x, double y, double theta)`<br>
This method instantaneously moves the agent to the given position and orientation.
Expand All @@ -219,6 +233,21 @@ This method returns the value of the specificed index. It is the distance from t
> `std::vector<double> sensor_values()`<br>
This method returns a list of all the sensor values, in the same order as the sensors appear in the agent's JSON definition.
For Omni Directional Robots
---
> `void omni_apply_force(double fx, double fy)`<br>
This methied applies a force specified by the arguments. The agent's mass comes in to play here using Newton's laws of motion. &#x1F537; New in 1.1.
> `void omni_track_velocity(double vx, double vy, double k=10)` <br>
This method makes the agent attempty to track the given translational velocity. If other elements are in the way, or if it is experience collisions, it may not be able to exactly track these values. The optional argument is the proportional gain on the feedback controller that implements the tracking controller. &#x1F537; New in 1.1.
> `void omni_damp_movement()`<br>
This method slows the agent down using the linear and angular friction coefficients defined in the agent's JSON definition file. &#x1F537; New in 1.1.
> `void omni_move_toward(double x, double y, double v=1)`<br>
This method attepts to move the agent to the given (x,y) location. If something in the way, the agent will not get there. The robot simultaneously attempts to rotate so that it is pointing toward the target and also moves forward, going faster as its angular error is reduced. The optional argument is the desired velocity of rotation and forward motion. &#x1F537; New in 1.1.
Project Configuration
===
Expand Down
5 changes: 5 additions & 0 deletions client/enviro.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ a {

button:focus {
outline:0;
}

.rotation-indicator {
stroke: #888;
stroke-width:1
}
27 changes: 20 additions & 7 deletions client/src/enviro.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,26 @@ class Agent extends React.Component {

render() {
let agent = this.props.agent;
let p = agent.specification.definition.shape.map(p => `${p.x},${p.y}`).join(" ");
let rot = `rotate(${180*agent.position.theta/Math.PI})`;
let tra = `translate(${agent.position.x} ${agent.position.y})`;
return <g key={agent.id} transform={tra + rot} ref={el => this.findSize(el)}>
<polygon points={p} className="agent" style={agent.specification.style} onClick={e=> this.click(e) }/>
{agent.sensors.map((value,i) => <Sensor value={value} agent={agent} i={i} key={i} />)}
</g>
if ( agent.specification.definition.shape == "omni" ) {
let rot = `rotate(${180*agent.position.theta/Math.PI})`;
let tra = `translate(${agent.position.x} ${agent.position.y})`;
return <g key={agent.id} transform={tra + rot} ref={el => this.findSize(el)}>
<circle cx={0} cy={0} r={agent.specification.definition.radius}
className="agent"
style={agent.specification.style}
onClick={e=> this.click(e) }/>
<line x1={0} y1={0} x2={agent.specification.definition.radius} y2={0} className="rotation-indicator"></line>
{agent.sensors.map((value,i) => <Sensor value={value} agent={agent} i={i} key={i} />)}
</g>
} else {
let p = agent.specification.definition.shape.map(p => `${p.x},${p.y}`).join(" ");
let rot = `rotate(${180*agent.position.theta/Math.PI})`;
let tra = `translate(${agent.position.x} ${agent.position.y})`;
return <g key={agent.id} transform={tra + rot} ref={el => this.findSize(el)}>
<polygon points={p} className="agent" style={agent.specification.style} onClick={e=> this.click(e) }/>
{agent.sensors.map((value,i) => <Sensor value={value} agent={agent} i={i} key={i} />)}
</g>
}
}

}
Expand Down
12 changes: 11 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
This page intentionally left blank
Note, if you want to copy these examples to your own directory and compile them, you may need to change `src/Makefile` as follows:

```make
ENVIRODIR := ../../../server/include
```

should read

```make
ENVIRODIR := /usr/local/src/enviro/server/include
```
2 changes: 1 addition & 1 deletion examples/avoiders/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ SRCEXT := cc

# Directories
CHIPDIR := /usr/local/src/Chipmunk2D
ENVIRODIR := /usr/local/src/enviro/server/include
ENVIRODIR := ../../../server/include

#Flags, Libraries and Includes
CFLAGS := -ggdb -shared -fPIC
Expand Down
10 changes: 10 additions & 0 deletions examples/omni/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
TARGET := bin/enviro

all:
$(MAKE) -C src all

clean:
$(MAKE) -C src clean



77 changes: 77 additions & 0 deletions examples/omni/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{

"name": "Omni Demo. Click and/or press w, s, a or d",
"ip": "0.0.0.0",
"port": 8765,

"agents": [
{
"definition": "defs/player.json",
"style": { "fill": "lightgreen", "stroke": "black" },
"position": {
"x": 0,
"y": 0,
"theta": 0
}
},
{
"definition": "defs/mover.json",
"style": { "fill": "lightblue", "stroke": "black" },
"position": {
"x": 100,
"y": 0,
"theta": 0
}
},
{
"definition": "defs/tracker.json",
"style": { "fill": "red", "stroke": "black" },
"position": {
"x": -100,
"y": -46,
"theta": 0
}
}
],

"statics": [
{
"style": { "fill": "gray", "stroke": "none" },
"shape": [
{ "x": -350, "y": -200 },
{ "x": -350, "y": 200 },
{ "x": -340, "y": 200 },
{ "x": -340, "y": -200 }
]
},
{
"style": { "fill": "gray", "stroke": "none" },
"shape": [
{ "x": 350, "y": -200 },
{ "x": 350, "y": 200 },
{ "x": 340, "y": 200 },
{ "x": 340, "y": -200 }
]
},
{
"style": { "fill": "gray", "stroke": "none" },
"shape": [
{ "x": -350, "y": 200 },
{ "x": 350, "y": 200 },
{ "x": 350, "y": 190 },
{ "x": -350, "y": 190 }
]
},
{
"style": { "fill": "gray", "stroke": "none" },
"shape": [
{ "x": -350, "y": -200 },
{ "x": 350, "y": -200 },
{ "x": 350, "y": -190 },
{ "x": -350, "y": -190 }
]
}

]

}
1 change: 1 addition & 0 deletions examples/omni/defs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Put agent definitions in this folder.
15 changes: 15 additions & 0 deletions examples/omni/defs/mover.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Mover",
"type": "dynamic",
"description": "Replace this string with a description",
"shape": "omni",
"radius": 10,
"friction": {
"collision": 1,
"linear": 1,
"rotational": 600
},
"sensors": [],
"mass": 1,
"controller": "lib/mover.so"
}
21 changes: 21 additions & 0 deletions examples/omni/defs/player.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "Player",
"type": "dynamic",
"description": "Replace this string with a description",
"shape": "omni",
"radius": 20,
"friction": {
"collision": 1,
"linear": 1,
"rotational": 1000
},
"sensors": [
{
"type": "range",
"location": { "x": 20, "y": 0 },
"direction": 0
}
],
"mass": 1,
"controller": "lib/player.so"
}
15 changes: 15 additions & 0 deletions examples/omni/defs/tracker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Tracker",
"type": "dynamic",
"description": "Replace this string with a description",
"shape": "omni",
"radius": 5,
"friction": {
"collision": 5,
"linear": 40,
"rotational": 600
},
"sensors": [],
"mass": 1,
"controller": "lib/tracker.so"
}
1 change: 1 addition & 0 deletions examples/omni/lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Shared object libraries will be place here by make.
38 changes: 38 additions & 0 deletions examples/omni/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#Architecture
ARCH := $(shell uname -m)

#Compilers
CC := g++ -std=c++17 -Wno-psabi

#The Target Library

#The Directories, Source, Includes, Objects, Binary and Resources
SRCEXT := cc

# Directories
CHIPDIR := /usr/local/src/Chipmunk2D
ENVIRODIR := ../../../server/include

#Flags, Libraries and Includes
CFLAGS := -ggdb -shared -fPIC
INCLUDE := -I $(ENVIRODIR) -I $(CHIPDIR)/include/chipmunk

#Files

TARGETDIR := ../lib
SOURCES := $(wildcard *.cc)
HEADERS := $(wildcard *.h)
TARGETS := $(patsubst %.cc,%.so,$(wildcard *.cc))
FULL_TARGETS := $(addprefix $(TARGETDIR)/, $(TARGETS))

#Default Make
all: $(FULL_TARGETS)

#Clean only Objects
clean:
@$(RM) -rf $(TARGETDIR)/*.so

# Compile
$(TARGETDIR)/%.so: %.cc %.h
$(CC) $(CFLAGS) $(INCLUDE) $< -o $@

6 changes: 6 additions & 0 deletions examples/omni/src/mover.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <iostream>
#include "mover.h"

using namespace enviro;

// Put your implementations here
47 changes: 47 additions & 0 deletions examples/omni/src/mover.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef __MOVER_AGENT__H
#define __MOVER_AGENT__H

#include "enviro.h"
#include <math.h>

using namespace enviro;

class MoverController : public Process, public AgentInterface {

public:
MoverController() : Process(), AgentInterface() {}

void init() {}
void start() {
i = 0;
t = 0;
}
void update() {
t += 1;
if ( t > 40 ) {
t = 0;
i = (i+1)%4;
}
omni_track_velocity(5*vx[i], 5*vy[i]);
}
void stop() {}

int t;
const vector<double> vx = { 1, 0, -1, 0 };
const vector<double> vy = { 0, 1, 0, -1 };
int i;

};

class Mover : public Agent {
public:
Mover(json spec, World& world) : Agent(spec, world) {
add_process(c);
}
private:
MoverController c;
};

DECLARE_INTERFACE(Mover)

#endif
Loading

0 comments on commit 8ab5a7c

Please sign in to comment.