okapi::AsyncMotionProfileController class

Base classes

template<typename Input, typename Output>
class AsyncPositionController

Constructors, destructors, conversion operators

AsyncMotionProfileController(const TimeUtil& itimeUtil, const PathfinderLimits& ilimits, const std::shared_ptr<ChassisModel>& imodel, const ChassisScales& iscales, const AbstractMotor::GearsetRatioPair& ipair, const std::shared_ptr<Logger>& ilogger = Logger::getDefaultLogger())
An Async Controller which generates and follows 2D motion profiles.
AsyncMotionProfileController(AsyncMotionProfileController&& other) deleted
~AsyncMotionProfileController() override

Public functions

auto operator=(AsyncMotionProfileController&& other) -> AsyncMotionProfileController& deleted
void generatePath(std::initializer_list<PathfinderPoint> iwaypoints, const std::string& ipathId)
Generates a path which intersects the given waypoints and saves it internally with a key of pathId.
void generatePath(std::initializer_list<PathfinderPoint> iwaypoints, const std::string& ipathId, const PathfinderLimits& ilimits)
Generates a path which intersects the given waypoints and saves it internally with a key of pathId.
auto removePath(const std::string& ipathId) -> bool
Removes a path and frees the memory it used.
auto getPaths() -> std::vector<std::string>
Gets the identifiers of all paths saved in this AsyncMotionProfileController.
void setTarget(std::string ipathId) override
Executes a path with the given ID.
void setTarget(std::string ipathId, bool ibackwards, bool imirrored = false)
Executes a path with the given ID.
void controllerSet(std::string ivalue) override
Writes the value of the controller output.
auto getTarget() -> std::string override
Gets the last set target, or the default target if none was set.
auto getProcessValue() const -> std::string override
This is overridden to return the current path.
void waitUntilSettled() override
Blocks the current task until the controller has settled.
void moveTo(std::initializer_list<PathfinderPoint> iwaypoints, bool ibackwards = false, bool imirrored = false)
Generates a new path from the position (typically the current position) to the target and blocks until the controller has settled.
void moveTo(std::initializer_list<PathfinderPoint> iwaypoints, const PathfinderLimits& ilimits, bool ibackwards = false, bool imirrored = false)
Generates a new path from the position (typically the current position) to the target and blocks until the controller has settled.
auto getError() const -> PathfinderPoint override
Returns the last error of the controller.
auto isSettled() -> bool override
Returns whether the controller has settled at the target.
void reset() override
Resets the controller so it can start from 0 again properly.
void flipDisable() override
Changes whether the controller is off or on.
void flipDisable(bool iisDisabled) override
Sets whether the controller is off or on.
auto isDisabled() const -> bool override
Returns whether the controller is currently disabled.
void tarePosition() override
This implementation does nothing because the API always requires the starting position to be specified.
void setMaxVelocity(std::int32_t imaxVelocity) override
This implementation does nothing because the maximum velocity is configured using PathfinderLimits elsewhere.
void startThread()
Starts the internal thread.
auto getThread() const -> CrossplatformThread*
void storePath(const std::string& idirectory, const std::string& ipathId)
Saves a generated path to a file.
void loadPath(const std::string& idirectory, const std::string& ipathId)
Loads a path from a directory on the SD card containing a path CSV file.
void forceRemovePath(const std::string& ipathId)
Attempts to remove a path without stopping execution.

Protected static functions

static void trampoline(void* context)
static auto makeFilePath(const std::string& directory, const std::string& filename) -> std::string
Joins and escapes a directory and file name.

Protected functions

void loop()
void executeSinglePath(const std::vector<squiggles::ProfilePoint>& path, std::unique_ptr<AbstractRate> rate) virtual
Follow the supplied path.
auto convertLinearToRotational(QSpeed linear) const -> QAngularSpeed
Converts linear chassis speed to rotational motor speed.
auto getPathErrorMessage(const std::vector<PathfinderPoint>& points, const std::string& ipathId, int length) -> std::string
void internalStorePath(std::ostream& file, const std::string& ipathId)
void internalLoadPath(std::istream& file, const std::string& ipathId)
void internalLoadPathfinderPath(std::istream& leftFile, std::istream& rightFile, const std::string& ipathId)

Protected static variables

static double DT constexpr

Protected variables

std::shared_ptr<Logger> logger
std::map<std::string, std::vector<squiggles::ProfilePoint>> paths
PathfinderLimits limits
std::shared_ptr<ChassisModel> model
ChassisScales scales
AbstractMotor::GearsetRatioPair pair
TimeUtil timeUtil
CrossplatformMutex currentPathMutex
std::string currentPath
std::atomic_bool isRunning
std::atomic_int direction
std::atomic_bool mirrored
std::atomic_bool disabled
std::atomic_bool dtorCalled
CrossplatformThread* task

Function documentation

okapi::AsyncMotionProfileController::AsyncMotionProfileController(const TimeUtil& itimeUtil, const PathfinderLimits& ilimits, const std::shared_ptr<ChassisModel>& imodel, const ChassisScales& iscales, const AbstractMotor::GearsetRatioPair& ipair, const std::shared_ptr<Logger>& ilogger = Logger::getDefaultLogger())

An Async Controller which generates and follows 2D motion profiles.

Parameters
itimeUtil The TimeUtil.
ilimits The default limits.
imodel The chassis model to control.
iscales The chassis dimensions.
ipair The gearset.
ilogger The logger this instance will log to.

Throws a std::invalid_argument exception if the gear ratio is zero.

void okapi::AsyncMotionProfileController::generatePath(std::initializer_list<PathfinderPoint> iwaypoints, const std::string& ipathId)

Generates a path which intersects the given waypoints and saves it internally with a key of pathId.

Parameters
iwaypoints The waypoints to hit on the path.
ipathId A unique identifier to save the path with.

Call executePath() with the same pathId to run it.

If the waypoints form a path which is impossible to achieve, an instance of std::runtime_error is thrown (and an error is logged) which describes the waypoints. If there are no waypoints, no path is generated.

void okapi::AsyncMotionProfileController::generatePath(std::initializer_list<PathfinderPoint> iwaypoints, const std::string& ipathId, const PathfinderLimits& ilimits)

Generates a path which intersects the given waypoints and saves it internally with a key of pathId.

Parameters
iwaypoints The waypoints to hit on the path.
ipathId A unique identifier to save the path with.
ilimits The limits to use for this path only.

Call executePath() with the same pathId to run it.

If the waypoints form a path which is impossible to achieve, an instance of std::runtime_error is thrown (and an error is logged) which describes the waypoints. If there are no waypoints, no path is generated.

NOTE: The waypoints are expected to be in the okapi::State::FRAME_TRANSFORMATION format where +x is forward, +y is right, and 0 theta is measured from the +x axis to the +y axis.

bool okapi::AsyncMotionProfileController::removePath(const std::string& ipathId)

Removes a path and frees the memory it used.

Parameters
ipathId A unique identifier for the path, previously passed to generatePath()
Returns True if the path no longer exists

This function returns true if the path was either deleted or didn't exist in the first place. It returns false if the path could not be removed because it is running.

std::vector<std::string> okapi::AsyncMotionProfileController::getPaths()

Gets the identifiers of all paths saved in this AsyncMotionProfileController.

Returns The identifiers of all paths

void okapi::AsyncMotionProfileController::setTarget(std::string ipathId) override

Executes a path with the given ID.

Parameters
ipathId A unique identifier for the path, previously passed to generatePath().

If there is no path matching the ID, the method will return. Any targets set while a path is being followed will be ignored.

void okapi::AsyncMotionProfileController::setTarget(std::string ipathId, bool ibackwards, bool imirrored = false)

Executes a path with the given ID.

Parameters
ipathId A unique identifier for the path, previously passed to generatePath().
ibackwards Whether to follow the profile backwards.
imirrored Whether to follow the profile mirrored.

If there is no path matching the ID, the method will return. Any targets set while a path is being followed will be ignored.

void okapi::AsyncMotionProfileController::controllerSet(std::string ivalue) override

Writes the value of the controller output.

This method might be automatically called in another thread by the controller. This just calls setTarget().

std::string okapi::AsyncMotionProfileController::getTarget() override

Gets the last set target, or the default target if none was set.

Returns the last target

std::string okapi::AsyncMotionProfileController::getProcessValue() const override

This is overridden to return the current path.

Returns The most recent value of the process variable.

void okapi::AsyncMotionProfileController::waitUntilSettled() override

Blocks the current task until the controller has settled.

This controller is settled when it has finished following a path. If no path is being followed, it is settled.

void okapi::AsyncMotionProfileController::moveTo(std::initializer_list<PathfinderPoint> iwaypoints, bool ibackwards = false, bool imirrored = false)

Generates a new path from the position (typically the current position) to the target and blocks until the controller has settled.

Parameters
iwaypoints The waypoints to hit on the path.
ibackwards Whether to follow the profile backwards.
imirrored Whether to follow the profile mirrored.

Does not save the path which was generated.

void okapi::AsyncMotionProfileController::moveTo(std::initializer_list<PathfinderPoint> iwaypoints, const PathfinderLimits& ilimits, bool ibackwards = false, bool imirrored = false)

Generates a new path from the position (typically the current position) to the target and blocks until the controller has settled.

Parameters
iwaypoints The waypoints to hit on the path.
ilimits The limits to use for this path only.
ibackwards Whether to follow the profile backwards.
imirrored Whether to follow the profile mirrored.

Does not save the path which was generated.

PathfinderPoint okapi::AsyncMotionProfileController::getError() const override

Returns the last error of the controller.

Returns the last error

Does not update when disabled. This implementation always returns zero since the robot is assumed to perfectly follow the path. Subclasses can override this to be more accurate using odometry information.

bool okapi::AsyncMotionProfileController::isSettled() override

Returns whether the controller has settled at the target.

Returns whether the controller is settled

Determining what settling means is implementation-dependent.

If the controller is disabled, this method must return true.

void okapi::AsyncMotionProfileController::reset() override

Resets the controller so it can start from 0 again properly.

Keeps configuration from before. This implementation also stops movement.

void okapi::AsyncMotionProfileController::flipDisable() override

Changes whether the controller is off or on.

Turning the controller on after it was off will NOT cause the controller to move to its last set target.

void okapi::AsyncMotionProfileController::flipDisable(bool iisDisabled) override

Sets whether the controller is off or on.

Parameters
iisDisabled whether the controller is disabled

Turning the controller on after it was off will NOT cause the controller to move to its last set target, unless it was reset in that time.

bool okapi::AsyncMotionProfileController::isDisabled() const override

Returns whether the controller is currently disabled.

Returns whether the controller is currently disabled

void okapi::AsyncMotionProfileController::setMaxVelocity(std::int32_t imaxVelocity) override

This implementation does nothing because the maximum velocity is configured using PathfinderLimits elsewhere.

Parameters
imaxVelocity Ignored.

void okapi::AsyncMotionProfileController::startThread()

Starts the internal thread.

This should not be called by normal users. This method is called by the AsyncMotionProfileControllerBuilder when making a new instance of this class.

CrossplatformThread* okapi::AsyncMotionProfileController::getThread() const

Returns The underlying thread handle.

void okapi::AsyncMotionProfileController::storePath(const std::string& idirectory, const std::string& ipathId)

Saves a generated path to a file.

Parameters
idirectory The directory to store the path file in
ipathId The path ID of the generated path

Paths are stored as <ipathId>.csv. An SD card must be inserted into the brain and the directory must exist. idirectory can be prefixed with /usd/, but it this is not required.

void okapi::AsyncMotionProfileController::loadPath(const std::string& idirectory, const std::string& ipathId)

Loads a path from a directory on the SD card containing a path CSV file.

Parameters
idirectory The directory that the path files are stored in
ipathId The path ID that the paths are stored under (and will be loaded into)

/usd/ is automatically prepended to idirectory if it is not specified.

void okapi::AsyncMotionProfileController::forceRemovePath(const std::string& ipathId)

Attempts to remove a path without stopping execution.

Parameters
ipathId The path ID that will be removed

If that fails, disables the controller and removes the path.

static std::string okapi::AsyncMotionProfileController::makeFilePath(const std::string& directory, const std::string& filename) protected

Joins and escapes a directory and file name.

Parameters
directory The directory path, separated by forward slashes (/) and with or without a trailing slash
filename The file name in the directory
Returns the fully qualified and legal path name

void okapi::AsyncMotionProfileController::executeSinglePath(const std::vector<squiggles::ProfilePoint>& path, std::unique_ptr<AbstractRate> rate) virtual protected

Follow the supplied path.

Must follow the disabled lifecycle.

QAngularSpeed okapi::AsyncMotionProfileController::convertLinearToRotational(QSpeed linear) const protected

Converts linear chassis speed to rotational motor speed.

Parameters
linear chassis frame speed
Returns motor frame speed