#include <Robots/LoBot/io/LoRobot.H>
Public Member Functions | |
Sensors (const Sensors &) | |
long long | time_stamp () const |
Accessors for the different sensor values. | |
float | speed () const |
float | heading () const |
int | motor_pwm () const |
int | servo_pwm () const |
float | rpm () const |
bool | bump_left () const |
bool | bump_right () const |
bool | bump_both () const |
bool | bump_front () const |
bool | bump_rear_left () const |
bool | bump_rear_right () const |
bool | bump_rear_both () const |
bool | bump_rear () const |
bool | bump () const |
bool | wheel_drop_left () const |
bool | wheel_drop_right () const |
bool | wheel_drop_caster () const |
bool | wheel_drop_all () const |
bool | wheel_drop () const |
bool | wall () const |
bool | virtual_wall () const |
int | wall_signal () const |
bool | wall (int threshold) const |
bool | cliff_left () const |
bool | cliff_right () const |
bool | cliff_front_left () const |
bool | cliff_front_right () const |
bool | cliff_all () const |
bool | cliff () const |
int | cliff_signal_left () const |
int | cliff_signal_right () const |
int | cliff_signal_front_left () const |
int | cliff_signal_front_right () const |
bool | cliff (int threshold) const |
int | infrared () const |
int | distance () const |
int | angle () const |
bool | spin () const |
int | battery_charge () const |
int | requested_speed () const |
int | requested_radius () const |
Friends | |
class | Robot |
Client modules interact with the physical robot platform via an instance of this (the Robot) class, which provides a common API for controlling the robot's motors and for reading its current sensor values.
The robot's sensors are encapsulated using the Sensors inner class defined below. So as to maintain a common interface for all different robot platforms, this inner class needs to include fields for all the different sensors across all platforms. Sensors not relevant to the platform currently in use will be zeroed out. Clients should check the current platform before using those fields.
For example, if the Roomba platform is being used, then the PWM and RPM sensor fields will not be relevant. Similarly, if the hacked R/C car is being used, then the cliff and wheel drop sensors will not make any sense.
Thus, clients should determine which robot platform is being used before reading and using the sensor values stored in this class. This can be done by looking up the "platform" setting in the "robot" section of the lobot config file. Alternatively, we can write separate behaviours for different platforms and configure lobot to start the right set of behaviours depending on the robot platform being used.
DEVNOTE: This inner class is a do-it-all interface and represents a design choke point. Every time lobot is extended to support another robot platform, this beast here will have to be hacked to include yet more fields to hold the sensor values for the new platform.
Another way to implement this functionality might have been to implement a SensorBase class here and have every class derived from lobot::Robot provide its own Sensor class/struct containing only the relevant sensor fields. But because each robot platform can be quite different from every other, the SensorBase class defined here would be practically useless as a uniting interface and clients would have to use dynamic casts and/or RTTI to get the right type depending on the robot platform in use.
The approach outlined above does not seem to be any more palatable than having this do-it-all class here. In fact, from clients' perspectives, this do-it-all interface may actually be nicer than having to know different types and cast as required.
One other possibility is to not really have a statically typed class at all. Instead, we could use a "sensors database" that maps sensor names to values with both keys and values being strings (like the lobot configuration database). The Sensors API implemented here would then simply be map look-ups with return values being converted from strings to ints, floats, chars, whatever using a bunch of template functions (again, much as is done in the lobot configuration database).
This way, clients would get a uniform interface to any robot's sensors. And the sensors interface defined here would simply be a key-value database that wouldn't need to be hacked each time the system is extended to support a new robot platform. Furthermore, each lobot::Robot derived class will have the ability/freedom to define any kind of sensor type without having to worry about conforming to some predetermined set of sensor types that can exist.
Unfortunately, at this time (circa mid-Jan 2010), the "right" way to do it as described above will take more time than is available. Moreover, since development focus has now shifted to the Roomba (with the hacked R/C car platform being abandoned due to far too many hardware instabilities), the do-it-all approach is deemed an acceptable compromise. Eventually, when we get around to seriously adding support in this robot control framework for different platforms, the key-value database approach would be the way to go.
Definition at line 170 of file LoRobot.H.
lobot::Robot::Sensors::Sensors | ( | const Sensors & | S | ) |
long long lobot::Robot::Sensors::time_stamp | ( | ) | const [inline] |