Program Listing for File move_command.cpp
↰ Return to documentation for file (src/tap/control/setpoint/commands/move_command.cpp
)
/*
* Copyright (c) 2020-2021 Advanced Robotics at the University of Washington <robomstr@uw.edu>
*
* This file is part of Taproot.
*
* Taproot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Taproot 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 Taproot. If not, see <https://www.gnu.org/licenses/>.
*/
#include "move_command.hpp"
#include "tap/algorithms/math_user_utils.hpp"
#include "tap/architecture/clock.hpp"
namespace tap
{
namespace control
{
namespace setpoint
{
MoveCommand::MoveCommand(
SetpointSubsystem* setpointSubsystem,
float targetDisplacement,
uint32_t moveTime,
uint32_t pauseAfterMoveTime,
bool setToTargetOnEnd,
float setpointTolerance)
: setpointSubsystem(setpointSubsystem),
targetDisplacement(targetDisplacement),
rampToTargetValue(0.0f),
moveTime(moveTime),
pauseAfterMoveTime(pauseAfterMoveTime),
setpointTolerance(setpointTolerance),
previousMoveTime(0),
setToTargetOnEnd(setToTargetOnEnd)
{
this->addSubsystemRequirement(setpointSubsystem);
}
void MoveCommand::initialize()
{
// set the ramp start and target values
float currentSetpoint = setpointSubsystem->getSetpoint();
float targetValue = currentSetpoint + targetDisplacement;
rampToTargetValue.setTarget(targetValue);
rampToTargetValue.setValue(currentSetpoint);
previousMoveTime = tap::arch::clock::getTimeMilliseconds();
// Stop timeout, doesn't start until target reached
minMoveTimeout.stop();
}
void MoveCommand::execute()
{
// Don't move setpoint if the subsystem is jammed or offline
if (setpointSubsystem->isJammed() || !setpointSubsystem->isOnline())
{
previousMoveTime = tap::arch::clock::getTimeMilliseconds();
return;
}
// update the subsystem setpoint ramp
uint32_t currTime = tap::arch::clock::getTimeMilliseconds();
rampToTargetValue.update(
(currTime - previousMoveTime) * targetDisplacement / static_cast<float>(moveTime));
previousMoveTime = currTime;
setpointSubsystem->setSetpoint(rampToTargetValue.getValue());
if (minMoveTimeout.isStopped() &&
fabsf(setpointSubsystem->getCurrentValue() - rampToTargetValue.getTarget()) <=
setpointTolerance)
{
minMoveTimeout.restart(pauseAfterMoveTime);
}
}
void MoveCommand::end(bool interrupted)
{
// if the subsystem is not interrupted, then it exited normally
// (i.e. reached the desired value) and is not jammed. If it is
// jammed we thus want to set the subsystem value to the current value,
// so the motor does not attempt to keep rotating forward (and possible stalling)
if (interrupted || setpointSubsystem->isJammed() || !setpointSubsystem->isOnline() ||
!setToTargetOnEnd)
{
setpointSubsystem->setSetpoint(setpointSubsystem->getCurrentValue());
}
else
{
setpointSubsystem->setSetpoint(rampToTargetValue.getTarget());
}
}
bool MoveCommand::isFinished() const
{
// The subsystem is jammed or offline or it is within the setpoint tolerance, the ramp is
// finished, and the minimum rotate time is expired.
return setpointSubsystem->isJammed() || !setpointSubsystem->isOnline() ||
(algorithms::compareFloatClose(
setpointSubsystem->getCurrentValue(),
rampToTargetValue.getTarget(),
setpointTolerance) &&
rampToTargetValue.isTargetReached() && minMoveTimeout.isExpired());
}
} // namespace setpoint
} // namespace control
} // namespace tap