Program Listing for File power_limiter.cpp
↰ Return to documentation for file (src/tap/control/chassis/power_limiter.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 "power_limiter.hpp"
#include "tap/algorithms/math_user_utils.hpp"
#include "tap/drivers.hpp"
using namespace tap::algorithms;
using namespace tap::motor;
using std::max;
namespace tap::control::chassis
{
PowerLimiter::PowerLimiter(
const tap::Drivers *drivers,
tap::communication::sensors::current::CurrentSensorInterface *currentSensor,
float startingEnergyBuffer,
float energyBufferLimitThreshold,
float energyBufferCritThreshold)
: drivers(drivers),
currentSensor(currentSensor),
startingEnergyBuffer(startingEnergyBuffer),
energyBufferLimitThreshold(energyBufferLimitThreshold),
energyBufferCritThreshold(energyBufferCritThreshold),
energyBuffer(startingEnergyBuffer),
consumedPower(0.0f),
prevTime(0),
prevRobotDataReceivedTimestamp(0)
{
}
float PowerLimiter::getPowerLimitRatio()
{
if (!drivers->refSerial.getRefSerialReceivingData())
{
return 1.0f;
}
updatePowerAndEnergyBuffer();
if (energyBuffer < energyBufferLimitThreshold)
{
// If we have eaten through the majority of our energy buffer, do harsher limiting
// Cap the penalty at energyBufferCritThreshold / energyBufferLimitThreshold.
return limitVal(
static_cast<float>(energyBuffer - energyBufferCritThreshold) /
energyBufferLimitThreshold,
0.0f,
1.0f);
}
else
{
return 1.0f;
}
}
void PowerLimiter::updatePowerAndEnergyBuffer()
{
const auto &robotData = drivers->refSerial.getRobotData();
const auto &chassisData = robotData.chassis;
const float current = currentSensor->getCurrentMa();
const float newChassisPower = chassisData.volt * current / 1'000'000.0f;
// Manually compute energy buffer using consumedPower read from current sensor.
// See rules manual for reasoning behind the energy buffer calculation.
const float dt = tap::arch::clock::getTimeMilliseconds() - prevTime;
prevTime = tap::arch::clock::getTimeMilliseconds();
energyBuffer -= (consumedPower - chassisData.powerConsumptionLimit) * dt / 1000.0f;
if (robotData.robotDataReceivedTimestamp != prevRobotDataReceivedTimestamp)
{
energyBuffer = chassisData.powerBuffer;
prevRobotDataReceivedTimestamp = robotData.robotDataReceivedTimestamp;
}
consumedPower = newChassisPower;
}
} // namespace tap::control::chassis