/usr/include/enki/interactions/IRSensor.h is in libenki-dev 1:1.6.0-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | /*
Enki - a fast 2D robot simulator
Copyright (C) 1999-2016 Stephane Magnenat <stephane at magnenat dot net>
Copyright (C) 2004-2005 Markus Waibel <markus dot waibel at epfl dot ch>
Copyright (c) 2004-2005 Antoine Beyeler <abeyeler at ab-ware dot com>
Copyright (C) 2005-2006 Laboratory of Intelligent Systems, EPFL, Lausanne
Copyright (C) 2006-2008 Laboratory of Robotics Systems, EPFL, Lausanne
See AUTHORS for details
This program is free software; the authors of any publication
arising from research using this software are asked to add the
following reference:
Enki - a fast 2D robot simulator
http://home.gna.org/enki
Stephane Magnenat <stephane at magnenat dot net>,
Markus Waibel <markus dot waibel at epfl dot ch>
Laboratory of Intelligent Systems, EPFL, Lausanne.
You can redistribute this program and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ENKI_IRSENSOR_H
#define __ENKI_IRSENSOR_H
#include <enki/PhysicalEngine.h>
#include <enki/Interaction.h>
#include <valarray>
#undef min
/*! \file IRSensor.h
\brief Header of the generic infrared sensor
*/
namespace Enki
{
//! A generic infrared sensor
/*! \ingroup interaction
This sensor is based on a inverse square response function and three casted rays.
During objectStep() and wallsStep() it casts the three rays,
separated by an angle of 15 degrees. Distances are in cm. For negative distance values, i.e. a sensor inside an object, wall, etc., the value of the sensor response function at distance 0 will be used. If a ray fails to touch the object, the distance returned will be HUGE_VAL; the sensor response function will return a 0 sensor response for this case.
Upon finalize(), it computes finalValue and finalDist.
It does so first using the following equation for each ray:
m * (c - x0*x0)
value = F(x) = ----------------
x*x - 2*x0*x + c
where x is the distance to the obstacle.
It then combines the three rays with this equation:
finalValue = F(d_center) + F(d_left) + F(d_right) - 2*F(d_center*alpha)
where d_R is the distance of ray R, and alpha is 1/cos(15 degrees).
Finally, it computes the final distance using:
finalDist = F-1(finalValue)
where:
m
F-1(v) = x0 + sqrt( (x0*x0-c) * ( 1 - --- ) )
v
TODO
SensorResponseFunctors translate the distances stored in the rayValues[] into actual sensor activations. An appropriate noise model (if realistic modelling is desired) should be included in the sensor response function.
*/
class IRSensor : public LocalInteraction
{
protected:
//! Absolute position in the world, updated on init()
Vector absPos;
//! Absolute orientation in the world, updated on init()
double absOrientation;
//! Relative position on the robot
const Vector pos;
//! Height above ground, the sensor will not see any object of smaller height
const double height;
//! Relative orientation on the robot
const double orientation;
//! Actual detection range
const double range;
//! Aperture angle
const double aperture;
//! 1/cos(aperture)
const double alpha;
//! Number of rays used, each ray has an aperture of aperture/rayCount to the next one. Rays are assembled from right to left (i.e. counterclockwise)
const unsigned rayCount;
//! Maximum possible response value, might be inside the robot if x0<0, first parameter of response function
const double m;
//! Position of the maximum of response (might be negative, inside the robot), second parametere of response function
const double x0;
//! Third parameter of response function
const double c;
//! Standard deviation of Gaussian noise in the response space
const double noiseSd;
//! Radius for the smallest circle enclosing all rays
double smartRadius;
//! Current position of the center of the smartRadius, i.e. center of the smallest circle enclosing all rays in relative (robot) coordinates
Point smartPos;
//! Current position of the center of the smartRadius in absolute (world) coordinates, updated on init()
Vector absSmartPos;
//! Temporary ray values containing the lowest distance found up to now
std::vector<double> rayDists;
//! Temporary ray values containing the response value of the closest object found up to now
std::vector<double> rayValues;
//! The angle for each ray relative to the sensor orientation in relative (robot) coordinates
std::vector<double> rayAngles;
//! The angle for each ray relative to the sensor orientation in absolute (world) coordinates
std::vector<double> absRayAngles;
//! Final sensor value
double finalValue;
//! Final computed distance
double finalDist;
public:
//! Constructor
/*!
\param owner robot which embeds this sensor
\param pos relative position (x,y) on the robot
\param height height above ground, the sensor will not see any object of smaller height
\param orientation relative orientation on the robot
\param range detection range, objects over this range will not be seen
\param m maximum possible response value, might be inside the robot if x0<0, first parameter of response function
\param x0 position of the maximum of response (might be negative, inside the robot), second parametere of response function
\param c third parameter of response function
\param noiseSd standard deviation of Gaussian noise in the response space
*/
IRSensor(Robot *owner, Vector pos, double height, double orientation, double range, double m, double x0, double c, double noiseSd = 0.);
//! Reset distance values
void init(double dt, World* w);
//! Check for all potential intersections using smartRadius of sensor and calculate and find closest distance for each ray.
void objectStep(double dt, World *w, PhysicalObject *po);
//! Separated from objectStep because it is much simpler.
void wallsStep(double dt, World* w);
//! Applies the SensorResponseFunction to each ray and combines all rays using weights defined in the rayCombinationKernel.
void finalize(double dt, World* w);
//! Return the final sensor value
double getValue(void) const { return finalValue; }
//! Return the distance through the inverse response of the final sensor value
double getDist(void) const { return finalDist; }
//! Return the value of a ray
double getRayValue(unsigned i) const { return rayValues.at(i); }
//! Return the distance of a ray
double getRayDist(unsigned i) const { return rayDists.at(i); }
//! Return the absolute position of the IR sensor, updated at each time step on init()
Point getAbsolutePosition(void) const { return absPos; }
//! Return the absolute orientation of the IR sensor, updated at each time step on init()
double getAbsoluteOrientation(void) const { return absOrientation; }
//! Return the number of rays
unsigned getRayCount(void) const { return rayCount; }
//! Return the aperture of the sensor
double getAperture(void) const { return aperture; }
//! Return the range of the sensor
double getRange(void) const { return range; }
//! Return the radius for the smallest circle enclosing all rays
double getSmartRadius(void) const { return smartRadius; }
//! Return current position of the center of the smartRadius, i.e. center of the smallest circle enclosing all rays in relative (robot) coordinates
Point getAbsSmartPos(void) const { return absSmartPos; }
protected:
//! If dist is smaller than current ray distance, update distance and response value
void updateRay(size_t i, double dist);
//! Return the response for a given distance
double responseFunction(double x) const;
//! Return the inverse response for a given distance
double inverseResponseFunction(double v) const;
//! Returns distance to PhysicalObject po for angle rayAngle.
//! Note: The polygon MUST be convex and have vertices oriented counterclockwise (ccw). This code does not check for and verify these conditions. Returns distance to shortest intersection point or HUGE_VAL if there is no intersection
double distanceToPolygon(double rayAngle, const Polygon &p) const;
};
}
#endif
|