Open psychemedia opened 4 years ago
Original ev3dev
sensor docs can be found here.
Sensors are defined here in part in js/ev3dev2/sensor/lego.py
.
We can make a start on a touch sensor as follows:
class TouchSensor:
_DRIVER_NAME = 'lego-ev3-touch'
MODE_TOUCH = 'TOUCH'
def __init__(self, address=None):
self.sensor = ev3dev2_glue.TouchSensor(address)
@property
def pressed(self):
return int(self.sensor.dist()) / 10.0
This calls on a sensor defined in js/ev3dev2_glue.js
:
mod.TouchSensor = Sk.misceval.buildClass(mod, function($gbl, $loc) {
var self = this;
// We probably need to consider a new model for the attachment / config of sensors?
// Also make an assumption that sensor attaches to a bumper along
// front of robot.
$loc.__init__ = new Sk.builtin.func(function(self, address) {
if (address.v == 'in1') {
self.side = 'front'
} else {
throw new Sk.builtin.TypeError('No touch sensor connected to ' + String(address.v));
}
});
$loc.value = new Sk.builtin.func(function(self) {
if (self.side == 'front') {
return sim.robotStates.touchSensorFront;
}
return false;
});
}, 'TouchSensor', []);
That sensor returns values regarding the sensor state set in js/EV3devSim.js
:
In this.loadRobot = function (robotSpecs)
, define the location. For now, let's set x
to a single point, though it may also be useful to define a bumper that extends along the front/rear edge by passing [x0, x1]
. The y
sensor location allows us to projected the sensor outside of the edge.
touchSensorFront: {
x: 0,
y: 0,
angle: 0
}
Initialise values in self.robotStates = {
:
touchSensorFront: false;
Call the sensor in this.reset = function ()
and at the end of this.animate = function ()
:
self.getTouchSensorValues();
(As an optimisation, would it make sense to provide a base sin/cos calculation in this.animate
and set it as state on self.robotState
? This should perhaps be after the drawAll
(or could it also be set in drawAll()
?)
We then need to define the sensor interaction with the simulator: but what interaction do we want?
At the moment there is no physics that impedes the progress of the robot, although the ultrasonic sensor does identify how far away the closest wall / obstacle is, if not in what direction. (See also this related issue: https://github.com/innovationOUtside/nbev3devsim/issues/28)
The easiest touch sensor would be a point sensor, which is activated if the touch sensor is inside an obstacle locus. Alternatively, we may want to define a bumper eg along some or all of the front or rear edge.
The following calculation is based on the ultrasonic calculation for the zero angled ray:
// Define a nominal field range for the touch sensor
const TOUCH_RANGE = 1;
this.getTouchSensorsValues = function () {
if (typeof self.robotSpecs.touchSensorFront != 'undefined') {
var x = self.robotSpecs.touchSensorFront.x;
var y = self.robotSpecs.touchSensorFront.y;
self.robotStates.touchSensorFront = self.getTouchValue(x, y);
}
}
this.getTouchValue = function (x0, y0) {
var touched = false;
//Calculate whether touched or not...
var dists = [];
var primaryAngle = self.robotStates.angle +self.robotSpecs.touchSensorFront.angle / 180 * Math.PI;
var cos = Math.cos(self.robotStates.angle - Math.PI / 2);
var sin = Math.sin(self.robotStates.angle - Math.PI / 2);
var x = cos * x0 - sin * y0 + self.robotStates.x;
var y = sin * x0 + cos * y0 + self.robotStates.y;
var lineEnd = [
x + TOUCH_RANGE * Math.cos(primaryAngle + a),
y + TOUCH_RANGE * Math.sin(primaryAngle + a)
];
let ray = [[x, y], lineEnd];
if (self.wallsPresent) {
for (let wall of WALLS) {
let intercept = self.calcIntercept(ray, wall);
if (intercept != null) {
return true;
}
}
}
if (self.obstaclesPresent) {
for (let obstacle of self.obstacles) {
for (let wall of self.obstacleToLines(obstacle)) {
let intercept = self.calcIntercept(ray, wall);
if (intercept != null) {
return true;
}
}
}
}
return false;
}
A simpler way to handle the touch sensor might be to use the obstacle layer as a visual layer and then detect we have bumped into an obstacle when we can see it? The walls could be drawn on the obstacle layer or simply identified if the touch sensor is outside the rectangular bounding box described by the walls.
There is no touch sensor implemented in the simulator.
This would require: