diff --git a/Activation.h b/Activation.h index 7ff0b0b..546cb28 100644 --- a/Activation.h +++ b/Activation.h @@ -6,6 +6,7 @@ namespace Passer { namespace RoboidControl { +/// @brief Activation function for control class Activation { public: static float HeavisideStep(float inputValue, float bias = 0); // Range: {0,1} diff --git a/DifferentialDrive.cpp b/DifferentialDrive.cpp index f7ab168..bab2f3f 100644 --- a/DifferentialDrive.cpp +++ b/DifferentialDrive.cpp @@ -38,3 +38,14 @@ void DifferentialDrive::SetTwistSpeed(float forward, float yaw) { float rightSpeed = Float::Clamp(forward + yaw, -1, 1); SetTargetSpeeds(leftSpeed, rightSpeed); } + +void DifferentialDrive::SetTwistSpeed(Vector2 linear, float yaw) { + SetTwistSpeed(linear.y, yaw); +} + +void DifferentialDrive::SetTwistSpeed(Vector3 linear, + float yaw, + float pitch, + float roll) { + SetTwistSpeed(linear.z, yaw); +} diff --git a/DifferentialDrive.h b/DifferentialDrive.h index 1ad7bad..8eed5db 100644 --- a/DifferentialDrive.h +++ b/DifferentialDrive.h @@ -5,15 +5,57 @@ namespace Passer { namespace RoboidControl { +/// @brief A two-wheeled Propulsion method +/// +/// The wheels are put at either side of the roboid with the following behaviour +/// * When both wheels spin forward, the Roboid moves forward +/// * When both wheels spin backward, the Roboid moves backward +/// * When both wheels are spinning in opposite directions, the Roboid rotates +/// wihout moving forward or backward +/// * When just one wheel is spinning, the Roboid turnes while moving forward or +/// backward. class DifferentialDrive : public Propulsion { public: + /// @brief Default constructor DifferentialDrive(); + /// @brief Setup of the DifferentialDrive with the Placement of the motors + /// @param leftMotorPlacement Placement of the left Motor + /// @param rightMotorPlacement Placement of the right Motor + /// In this setup, the left motor Direction will be CounterClockWise when + /// driving forward, while the right motor will turn Clockwise. + /// @note When not using controlled motors, the placement of the motors is + /// irrelevant. DifferentialDrive(Placement leftMotorPlacement, Placement rightMotorPlacement); + + /// @brief Set the target speeds of the motors directly + /// @param leftSpeed The target speed of the left Motor + /// @param rightSpeed The target speed of the right Motor void SetTargetSpeeds(float leftSpeed, float rightSpeed); + /// @brief Controls the motors through forward and rotation speeds + /// @param forward The target forward speed of the Roboid + /// @param yaw The target rotation speed of the Roboid virtual void SetTwistSpeed(float forward, float yaw) override; - // virtual void SetTwistSpeed(float forward, float yaw, float pitch) override; + /// @brief Controls the motors through forward and rotation speeds + /// @param linear The target linear speed of the Roboid + /// @param yaw The target rotation speed of the Roboid + /// @note As a DifferentialDrive cannot move sideward, this function has the + /// same effect as using the void SetTwistSpeed(float forward, float yaw) + /// function. + virtual void SetTwistSpeed(Vector2 linear, float yaw = 0.0F); + /// @brief Controls the motors through forward and rotation speeds + /// @param linear The target linear speed + /// @param yaw The target rotation speed around the vertical axis + /// @param pitch Pitch is not supported and is ignored + /// @param roll Roll is not supported and is ignores + /// @note As a DifferentialDrive cannot move sideward or vertical, this + /// function has the same effect as using the void SetTwistSpeed(float + /// forward, float yaw) function. + virtual void SetTwistSpeed(Vector3 linear, + float yaw = 0.0F, + float pitch = 0.0F, + float roll = 0.0F); }; } // namespace RoboidControl diff --git a/DistanceSensor.cpp b/DistanceSensor.cpp index c1224a2..be6f62d 100644 --- a/DistanceSensor.cpp +++ b/DistanceSensor.cpp @@ -12,16 +12,7 @@ float DistanceSensor::GetDistance() { return distance; }; -void DistanceSensor::SetDistance(float distance) { - this->distance = distance; -}; // for simulation purposes - bool DistanceSensor::IsOn() { bool isOn = GetDistance() <= triggerDistance; return isOn; } - -bool DistanceSensor::isOff() { - bool isOff = GetDistance() > triggerDistance; - return isOff; -} diff --git a/DistanceSensor.h b/DistanceSensor.h index 6f6d16b..c46f2ad 100644 --- a/DistanceSensor.h +++ b/DistanceSensor.h @@ -8,21 +8,26 @@ namespace RoboidControl { /// @brief A Sensor which can measure the distance to the nearest object class DistanceSensor : public Sensor { public: + /// @brief Default constructor DistanceSensor(); + /// @brief Creates a DistanceSensor with the given trigger distance + /// @param triggerDistance The distance at which the sensors indicates that a + /// object is close by DistanceSensor(float triggerDistance); + /// @brief Determine the distance to the nearest object /// @return the measured distance in meters to the nearest object virtual float GetDistance(); - void SetDistance(float distance); /// @brief The distance at which ObjectNearby triggers float triggerDistance = 1; + /// @brief Indicate that an object is nearby + /// @return True when an object is nearby bool IsOn(); - bool isOff(); - protected: + /// @brief Distance to the closest object float distance = 0; }; diff --git a/Motor.cpp b/Motor.cpp index 3c23653..c2a2185 100644 --- a/Motor.cpp +++ b/Motor.cpp @@ -12,19 +12,3 @@ float Motor::GetSpeed() { void Motor::SetSpeed(float targetSpeed) { this->currentTargetSpeed = targetSpeed; } - -bool Motor::Drive(float distance) { - if (!this->driving) { - this->startTime = time(NULL); - this->targetDistance = distance >= 0 ? distance : -distance; - this->driving = true; - } - double duration = difftime(time(NULL), this->startTime); - if (duration >= this->targetDistance) { - this->driving = false; - return true; - } - - SetSpeed(distance < 0 ? -1 : 1); // max speed - return false; -} \ No newline at end of file diff --git a/Motor.h b/Motor.h index 5506678..737e7ff 100644 --- a/Motor.h +++ b/Motor.h @@ -27,13 +27,8 @@ class Motor : public Thing { /// forward) virtual float GetSpeed(); - bool Drive(float distance); - protected: float currentTargetSpeed = 0; - bool driving = false; - float targetDistance = 0; - time_t startTime = 0; }; } // namespace RoboidControl diff --git a/Perception.cpp b/Perception.cpp index 788e950..78f9971 100644 --- a/Perception.cpp +++ b/Perception.cpp @@ -10,24 +10,6 @@ Perception::Perception(Placement* sensors, unsigned int sensorCount) { this->sensorPlacements = (Placement*)sensors; } -void Perception::AddSensors(Placement* things, unsigned int thingCount) { - sensorCount = 0; - for (unsigned int thingIx = 0; thingIx < thingCount; thingIx++) { - Thing* thing = things[thingIx].thing; - if (thing->IsSensor()) - sensorCount++; - } - - sensorPlacements = new Placement[sensorCount]; - - unsigned int sensorIx = 0; - for (unsigned int thingIx = 0; thingIx < thingCount; thingIx++) { - Thing* thing = things[thingIx].thing; - if (thing->IsSensor()) - sensorPlacements[sensorIx++] = things[thingIx]; - } -} - unsigned int Perception::GetSensorCount() { return this->sensorCount; } @@ -154,64 +136,4 @@ bool Perception::SwitchOn(float fromAngle, float toAngle) { } } return false; -} - -unsigned int Perception::ToDepthMapIndex(float angle) { - unsigned int depthMapIx = - (unsigned int)(((angle - rangeMinimum) / (rangeMaximum - rangeMinimum)) * - (float)resolution); - return depthMapIx; -} - -float Perception::GetDistance(float angle) { - if (depthMap != nullptr) { - if (angle < rangeMinimum || angle > rangeMaximum) - return INFINITY; - unsigned int depthMapIx = ToDepthMapIndex(angle); - return depthMap[depthMapIx]; - } else { - for (unsigned int sensorIx = 0; sensorIx < this->sensorCount; sensorIx++) { - Placement placement = sensorPlacements[sensorIx]; - float placementAngle = placement.horizontalDirection; - if (placementAngle == angle) { - DistanceSensor* distanceSensor = (DistanceSensor*)placement.thing; - return distanceSensor->GetDistance(); - } - } - } - return INFINITY; -} - -void Perception::SetResolution(unsigned int resolution) { - this->resolution = resolution; - this->depthMap = new float[this->resolution]; -} - -void Perception::SetRange(float min, float max) { - this->rangeMinimum = min; - this->rangeMaximum = max; -} - -float* Perception::GetDepthMap() { - return this->depthMap; -} - -void Perception::SetDepthMap(float angle, float distance) { - if (angle < rangeMinimum || angle > rangeMaximum) - return; - - unsigned int depthMapIx = ToDepthMapIndex(angle); - depthMap[depthMapIx] = distance; -} - -Sensor* Perception::GetSensor(float angle) { - angle = Angle::Normalize(angle); - - for (unsigned int ix = 0; ix < this->sensorCount; ix++) { - Placement placement = this->sensorPlacements[ix]; - if (abs(placement.horizontalDirection - angle) < 0.01F) - return (Sensor*)placement.thing; - } - - return nullptr; } \ No newline at end of file diff --git a/Perception.h b/Perception.h index ae5ee0c..7e22154 100644 --- a/Perception.h +++ b/Perception.h @@ -6,9 +6,10 @@ namespace Passer { namespace RoboidControl { +/// @brief Module to which keeps track of objects around the roboid class Perception { public: - /// @brief Setup perception + /// @brief Default Constructor Perception(); /// @brief Template to make it possible to leave out ths sensorCount @@ -18,14 +19,31 @@ class Perception { inline Perception(Placement (&sensors)[sensorCount]) { Perception(sensors, sensorCount); } + /// @brief Create a perception setup with the given Sensors + /// @param sensors The Placement of Sensors on the Roboid + /// @param sensorCount The number of sensors in the placement array Perception(Placement* sensors, unsigned int sensorCount); - void AddSensors(Placement* sensors, unsigned int sensorCount); - + /// @brief Get the number of Sensors + /// @return The number of sensors, zero when no sensors are present unsigned int GetSensorCount(); - Sensor* GetSensor(unsigned int sensorId); + /// @brief Get a specific Sensor on the Roboid + /// @param sensorId The index of the Sensor + /// @return The requested Sensor or a nullptr when no Sensor with the given + /// index could be found + Sensor* GetSensor(unsigned int sensorIx); + /// @brief Get the placement of a specific Sensor + /// @param motorIx The index of the Sensor + /// @return Returns the Placement or a nullptr when no Placement with the + /// given index could be found + Placement* GetSensorPlacement(unsigned int sensorIx); - float DistanceForward(float angle = 90); + /// @brief Distance to the closest object on the front of the Roboid + /// @param direction The direction relative to the forward direction in which + /// the object should be present + /// @return The distance to the closest object within the given range, + /// INFINITY when no object is detected + float DistanceForward(float direction = 90); /// @brief Distance to the closest object on the left /// @return distance in meters, INFINITY when no object is detected. @@ -57,33 +75,39 @@ class Perception { /// @note When an object is beyond `angle` meters, it is not reported. float DistanceRight(float angle); + /// @brief Distance to the closest object above the Roboid + /// @return distance in meters, INFINITY when no object is detected float DistanceUp() { return DistanceUp(180); } + /// @brief Distance to the closest object above the Roboid within the give + /// range + /// @param angle The angle relative to the upward direction to indicate the + /// range + /// @return distance in meters, INFINITY when no object is detected float DistanceUp(float angle); + /// @brief Disatnce to the closest object under the Roboid + /// @return distance in meters, INFINITY when no object is detected float DistanceDown() { return DistanceDown(180); } + /// @brief Distance to the closest object under th4e Roboid within the given + /// range + /// @param angle The angle relative to the downward direciton to indicate the + /// range + /// @return distance in meters, INFINITY when no object is detected float DistanceDown(float angle); - float Distance(float leftAngle, float rightAngle); - float GetDistance(float angle); - + /// @brief Checks if an object is close within the give range in the + /// horizontal plane + /// @param fromAngle Start angle in the horizontal plane + /// @param toAngle End angle in the horizontal plane + /// @return True is an object is closeby + /// @note Whether an object is closeby depends on the Distance Sensor + /// @remark This function is likely to change in the near future bool SwitchOn(float fromAngle, float toAngle); - void SetResolution(unsigned int resolution); - void SetRange(float min, float max); - float* GetDepthMap(); - unsigned int ToDepthMapIndex(float angle); - void SetDepthMap(float angle, float distance); - - Sensor* GetSensor(float angle); - protected: - // SensorPlacement* sensors = nullptr; + /// @brief The Placement of the Sensors used for Perception Placement* sensorPlacements = nullptr; + /// @brief The number of Sensors used for Perception unsigned int sensorCount = 0; - - unsigned int resolution; - float rangeMinimum; - float rangeMaximum; - float* depthMap = nullptr; }; } // namespace RoboidControl diff --git a/Propulsion.cpp b/Propulsion.cpp index dada9fc..b1575e9 100644 --- a/Propulsion.cpp +++ b/Propulsion.cpp @@ -9,23 +9,6 @@ Propulsion::Propulsion() { this->motorCount = 0; } -void Propulsion::AddMotors(Placement* things, unsigned int thingCount) { - this->motorCount = 0; - for (unsigned int thingIx = 0; thingIx < thingCount; thingIx++) { - Thing* thing = things[thingIx].thing; - if (thing->IsMotor()) - motorCount++; - } - this->placement = new Placement[motorCount]; - - unsigned int motorIx = 0; - for (unsigned int thingIx = 0; thingIx < thingCount; thingIx++) { - Thing* thing = things[thingIx].thing; - if (thing->IsMotor()) - this->placement[motorIx++] = things[thingIx]; - } -} - unsigned int Propulsion::GetMotorCount() { return this->motorCount; } @@ -52,13 +35,7 @@ Placement* Propulsion::GetMotorPlacement(unsigned int motorId) { return nullptr; } -void Propulsion::Update(float currentTimeMs) { - this->lastUpdateTime = currentTimeMs; -} - -void Propulsion::SetMaxSpeed(float maxSpeed) { - this->maxSpeed = abs(maxSpeed); -} +void Propulsion::Update(float currentTimeMs) {} void Propulsion::SetTwistSpeed(float forward, float yaw) {} diff --git a/Propulsion.h b/Propulsion.h index 7d58263..20d0dc1 100644 --- a/Propulsion.h +++ b/Propulsion.h @@ -7,47 +7,65 @@ namespace Passer { namespace RoboidControl { +/// @brief The Propulsion module for a Roboid is used to move the Roboid in +/// space +/// +/// Usually, a specific implementation of the propulsion module is used for a +/// robot. This base class does not implement the functions to move the Roboid +/// around. class Propulsion { public: - /// @brief Setup sensing + /// @brief Default Constructor for Propulsion Propulsion(); + /// @brief Update the propulsion state of the Roboid + /// @param currentTimeMs The time in milliseconds when calling this void Update(float currentTimeMs); - void AddMotors(Placement* motors, unsigned int motorCount); - // void AddQuadcopter(Quadcopter* quadcopter); - // Quadcopter* GetQuadcopter(); - + /// @brief Get the number of motors in this roboid + /// @return The number of motors. Zero when no motors are present unsigned int GetMotorCount(); + /// @brief Get a specific motor + /// @param motorIx The index of the motor + /// @return Returns the motor or a nullptr when no motor with the given index + /// could be found Motor* GetMotor(unsigned int motorIx); + /// @brief Get the Placement of a specific Motor + /// @param motorIx The index of the Motor + /// @return Returns the Placement or a nullptr when no Placement with the give + /// index could be found Placement* GetMotorPlacement(unsigned int motorIx); - /// @brief Set the maximum linear speed. - /// @param maxSpeed The new maximum linear speed - /// For controlled motors, this is rpm. - /// For calibrated controlled motors, this is m/s - /// For uncontrolled motors this is a value between 0 and 1 where 1 is the - /// maximum speed of the motor - void SetMaxSpeed(float maxSpeed); - // Velocity control - virtual void SetTwistSpeed(float forward, float yaw = 0.0F); // 2D - virtual void SetTwistSpeed(Vector2 linear, float yaw = 0.0F); // 2D plus + + /// @brief Sets the forward and rotation speed of a (grounded) Roboid + /// @param forward The target forward speed + /// @param yaw The target rotation speed around the vertical axis + /// This function is typically used for Roboid which are driving on the + /// ground. + virtual void SetTwistSpeed(float forward, float yaw = 0.0F); + /// @brief Sets the forward, sideward and rotation speed of a (grounded) + /// Roboid + /// @param linear The target linear (forward, sideward) speed + /// @param yaw The target rotation speed around the vertical axis + /// This function is typically used for Roboid which are driving on the ground + /// which have to ability to move sideward + virtual void SetTwistSpeed(Vector2 linear, float yaw = 0.0F); + /// @brief Set the target 3D linear and 3D rotation speed of a (flying) Roboid + /// @param linear The target linear speed + /// @param yaw The target rotation speed around the vertical axis + /// @param pitch The target rotation speed around the sideward axis + /// @param roll The target rotation speed around hte forward axis virtual void SetTwistSpeed(Vector3 linear, float yaw = 0.0F, float pitch = 0.0F, - float roll = 0.0F); // 3D - - Placement* placement = nullptr; - unsigned int motorCount = 0; + float roll = 0.0F); protected: - float maxSpeed = 1; - - bool driving = false; - float targetDistance = 0; - time_t startTime; - float lastUpdateTime; + /// @brief The number of motors used for Propulsion + unsigned int motorCount = 0; + /// @brief The Placement of the motors used for Propulsion + Placement* placement = nullptr; }; } // namespace RoboidControl diff --git a/Roboid.h b/Roboid.h index 4859c5e..964b125 100644 --- a/Roboid.h +++ b/Roboid.h @@ -6,16 +6,25 @@ namespace Passer { namespace RoboidControl { +/// @brief A Roboid is used to control autonomous robots class Roboid { public: + /// @brief Default constructor for a Roboid Roboid(); - Roboid(Placement configuration[], unsigned int thingCount); + /// @brief Creates a Roboid with Perception and Propulsion abilities + /// @param perception The Perception implementation to use for this Roboid + /// @param propulsion The Propulsion implementation to use for this Roboid Roboid(Perception* perception, Propulsion* propulsion); - Perception* perception; - Propulsion* propulsion; - + /// @brief Update the state of the Roboid + /// @param currentTimeMs The time in milliseconds when calling this + /// function void Update(float currentTimeMs); + + /// @brief The Perception module of this Roboid + Perception* perception; + /// @brief The Propulsion module of this Roboid + Propulsion* propulsion; }; } // namespace RoboidControl } // namespace Passer diff --git a/Sensor.h b/Sensor.h index 4f6f87a..f88906b 100644 --- a/Sensor.h +++ b/Sensor.h @@ -8,6 +8,7 @@ namespace RoboidControl { /// @brief A sensor is a thing which can perform measurements in the environment class Sensor : public Thing { public: + /// @brief Default Constructor for a Sensor Sensor(); };