4#include "../../utilities/Utilities.hpp"
9const unsigned long kStopAttemptInterval = 100;
10const uint8_t kMaxStopAttempts = 3;
19 , mOdometerLeft(odometer)
20 , mOdometerRight(odometer)
30 , mOdometerLeft(odometerLeft)
31 , mOdometerRight(odometerRight)
44 if (!areOdometersAttached())
53 if (areOdometersDirectional() && mCruiseControlEnabled)
62 auto newSpeedAtOppositeDirection = mTargetSpeed * speed < 0;
63 auto changeOfDirectionWhileCruiseControl = mCruiseControlEnabled && newSpeedAtOppositeDirection;
68 auto carShouldStop = carWantsToStop && !carIsAlreadyStopped;
69 if (changeOfDirectionWhileCruiseControl || carShouldStop)
78 if (!mCruiseControlEnabled)
85void DistanceCar::brake()
89 auto currentSpeed = mCruiseControlEnabled ? mPreviousControlledSpeed : mTargetSpeed;
95 for (
auto attempt = 0; attempt < kMaxStopAttempts; attempt++)
99 auto distanceTravelled =
getDistance() - initialDistance;
100 if (distanceTravelled == 0)
107 mPreviousControlledSpeed = 0;
108 mIntegratedError = 0;
114 if (!areOdometersAttached() || !mCruiseControlEnabled)
120 if (currentTime < mPreviousUpdate + mFrequency)
124 mPreviousUpdate = currentTime;
138 if (!areOdometersDirectional() && mTargetSpeed < 0)
140 actualSpeed = -actualSpeed;
142 auto controlledSpeed = controlMotorSpeed(mPreviousControlledSpeed, mTargetSpeed, actualSpeed);
146 if (!areOdometersDirectional() && (controlledSpeed * actualSpeed < 0))
159 mPreviousControlledSpeed = controlledSpeed;
162float DistanceCar::controlMotorSpeed(
float previousSpeed,
float targetSpeed,
float currentSpeed)
164 float error = targetSpeed - currentSpeed;
165 mIntegratedError += error;
166 float correction = (mProportional * error) + (mIntegral * mIntegratedError)
167 + (mDerivative * (error - mPreviousError));
168 mPreviousError = error;
177 return areOdometersAttached() ? (mOdometerLeft.
getSpeed() + mOdometerRight.
getSpeed()) / 2
183 mCruiseControlEnabled =
false;
189 unsigned long frequency)
191 mCruiseControlEnabled =
true;
192 mProportional = proportional;
193 mIntegral = integral;
194 mDerivative = derivative;
195 mFrequency = frequency;
198bool DistanceCar::areOdometersAttached()
const
203bool DistanceCar::areOdometersDirectional()
const
210 if (mCruiseControlEnabled)
Interface to generalize all classes that can provide a way to control a Car.
long getDistance()
Gets the car's travelled distance.
void overrideMotorSpeed(int firstMotorSpeed, int secondMotorSpeed) override
Sets the motor speed individually as a percentage of the motors` total power unless cruise control is...
virtual void update()
Adjusts the cruise control speed.
void disableCruiseControl()
Disable cruise control.
void setSpeed(float speed) override
Sets the car's speed in meters per second if cruise control is enabled otherwise as a percentage of t...
float getSpeed()
Gets the car's current speed in meters per second.
void enableCruiseControl(float proportional=smartcarlib::constants::car::kDefaultProportional, float integral=smartcarlib::constants::car::kDefaultIntegral, float derivative=smartcarlib::constants::car::kDefaultDerivative, unsigned long frequency=smartcarlib::constants::car::kDefaultPidFrequency)
Enables the car to move with a stable speed using the odometers.
DistanceCar(Runtime &runtime, Control &control, Odometer &odometer)
Constructs a car equipped with a distance sensor.
An interface to programmatically represent all odometers.
virtual bool providesDirection() const =0
Return whether the sensor is capable of inferring the direction of movement.
virtual long getDistance()=0
Returns the travelled distance in centimeters where sign can indicate direction if there is hardware ...
virtual float getSpeed()=0
Returns the current speed in meters/sec where sign can indicate direction if there is hardware suppor...
virtual bool isAttached() const =0
Returns whether the sensor has been properly attached.
An interface to serve as a wrapper for the native runtime environment, greatly inspired by the Arduin...
virtual void delayMillis(unsigned long milliseconds)=0
Block the execution for the specified number of milliseconds, equivalent of delay in Arduino.
virtual unsigned long currentTimeMillis()=0
Gets the amount of milliseconds since the microcontroller started running, equivalent of millis in Ar...
A class to programmatically represent a very basic vehicle with two motors.
void setSpeed(float speed) override
Sets the car's driving speed as a percentage of the motors total speed where the sign indicates direc...
void overrideMotorSpeed(int firstMotorSpeed, int secondMotorSpeed) override
Set the motor speed individually as a percentage of the motors` total power.
const auto kBreakSpeedScale
const int kOdometersNotAttachedError
const int kIdleControlSpeed
const int kMinControlSpeed
const int kMaxControlSpeed
constexpr bool areAlmostEqual(float a, float b)
Compares two floating point numbers.
constexpr AnyNumber getConstrain(AnyNumber number, AnyNumber min, AnyNumber max)
Limit the number between a range.