Program Listing for File unjam_integral_command.cpp
↰ Return to documentation for file (src/tap/control/setpoint/commands/unjam_integral_command.cpp
)
/*
* Copyright (c) 2022 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 "unjam_integral_command.hpp"
#include <cassert>
#include "tap/algorithms/math_user_utils.hpp"
using namespace tap::algorithms;
namespace tap::control::setpoint
{
UnjamIntegralCommand::UnjamIntegralCommand(
IntegrableSetpointSubsystem& integrableSetpointSubsystem,
const Config& config)
: integrableSetpointSubsystem(integrableSetpointSubsystem),
config(config)
{
assert(config.targetUnjamIntegralChange > 0);
assert(config.targetCycleCount > 0);
assert(config.maxWaitTime > 0);
// max wait time must be > min time it will take to reach the unjam displacement given the unjam
// velocity
assert(
1000.0f * (this->config.targetUnjamIntegralChange / this->config.unjamSetpoint) <
this->config.maxWaitTime);
addSubsystemRequirement(&integrableSetpointSubsystem);
unjamRotateTimeout.stop();
}
bool UnjamIntegralCommand::isReady() { return integrableSetpointSubsystem.isOnline(); }
void UnjamIntegralCommand::initialize()
{
unjamRotateTimeout.restart(config.maxWaitTime);
positionBeforeUnjam = integrableSetpointSubsystem.getCurrentValueIntegral();
forwardsCleared = false;
backwardsCleared = false;
backwardsCount = 0;
beginUnjamBackwards();
}
void UnjamIntegralCommand::execute()
{
float curPosition = integrableSetpointSubsystem.getCurrentValueIntegral();
switch (currUnjamState)
{
case UNJAM_BACKWARD:
if (curPosition <= positionBeforeUnjam - config.targetUnjamIntegralChange)
{
backwardsCleared = true;
beginUnjamForwards();
}
else if (unjamRotateTimeout.isExpired())
{
beginUnjamForwards();
}
break;
case UNJAM_FORWARD:
if (curPosition >= positionBeforeUnjam)
{
forwardsCleared = true;
beginUnjamBackwards();
}
else if (unjamRotateTimeout.isExpired())
{
beginUnjamBackwards();
}
break;
case JAM_CLEARED:
break;
}
// Forward and backward thresholds cleared, try to return to original setpoint.
if (currUnjamState != JAM_CLEARED && forwardsCleared && backwardsCleared)
{
currUnjamState = JAM_CLEARED;
}
}
void UnjamIntegralCommand::end(bool)
{
if (currUnjamState == JAM_CLEARED)
{
integrableSetpointSubsystem.clearJam();
}
integrableSetpointSubsystem.setSetpoint(0);
}
bool UnjamIntegralCommand::isFinished() const
{
return !integrableSetpointSubsystem.isOnline() || (currUnjamState == JAM_CLEARED) ||
(backwardsCount >= config.targetCycleCount + 1);
}
void UnjamIntegralCommand::beginUnjamForwards()
{
unjamRotateTimeout.restart(config.maxWaitTime);
integrableSetpointSubsystem.setSetpoint(config.unjamSetpoint);
currUnjamState = UNJAM_FORWARD;
}
void UnjamIntegralCommand::beginUnjamBackwards()
{
unjamRotateTimeout.restart(config.maxWaitTime);
integrableSetpointSubsystem.setSetpoint(-config.unjamSetpoint);
currUnjamState = UNJAM_BACKWARD;
backwardsCount += 1;
}
} // namespace tap::control::setpoint