Newer
Older
/*
* This file is part of ArmarX.
*
* Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
*
* ArmarX is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* ArmarX 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package ArmarX
* @author Markus Grotz (markus.grotz at kit dot edu)
* @date 2019
* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
* GNU General Public License
*/
#include "NJointHolonomicPlatformGlobalPositionController.h"
#include <SimoxUtility/math/convert/mat3f_to_rpy.h>
#include <SimoxUtility/math/convert/mat4f_to_rpy.h>
#include <SimoxUtility/math/periodic/periodic_clamp.h>
#include "ArmarXCore/core/logging/Logging.h"
#include "RobotAPI/components/units/RobotUnit/util/ControlThreadOutputBuffer.h"
#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
namespace armarx
{
NJointControllerRegistration<NJointHolonomicPlatformGlobalPositionController>
registrationNJointHolonomicPlatformGlobalPositionController(
"NJointHolonomicPlatformGlobalPositionController");
NJointHolonomicPlatformGlobalPositionController::
NJointHolonomicPlatformGlobalPositionController(
RobotUnit*,
const NJointHolonomicPlatformGlobalPositionControllerConfigPtr& cfg,
const VirtualRobot::RobotPtr&) :
pid(cfg->p, cfg->i, cfg->d, cfg->maxVelocity, cfg->maxAcceleration),
opid(cfg->p_rot,
cfg->i_rot,
cfg->d_rot,
cfg->maxRotationVelocity,
cfg->maxRotationAcceleration,
true)
const SensorValueBase* sv =
useSensorValue(GlobalRobotLocalizationSensorDevice::DeviceName());
this->sv = sv->asA<GlobalRobotLocalizationSensorDevice::SensorValueType>();
target = useControlTarget(cfg->platformName, ControlModes::HolonomicPlatformVelocity)
->asA<ControlTargetHolonomicPlatformVelocity>();
pid.threadSafe = false;
pid.preallocate(2);
opid.threadSafe = false;
void
NJointHolonomicPlatformGlobalPositionController::rtRun(
const IceUtil::Time& currentTime,
const IceUtil::Time& timeSinceLastIteration)
const auto global_T_robot = sv->global_T_root;
const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(global_T_robot);
const float global_orientation = rpy.z();
const Eigen::Vector2f global_P_robot = global_T_robot.block<2, 1>(0, 3);
if (rtGetControlStruct().newTargetSet)
{
pid.reset();
getWriterControlStruct().newTargetSet = false;
writeControlStruct();
isTargetSet = true;
// if ((sv->lastUpdate + IceUtil::Time::seconds(2)) < currentTime)
// {
// ARMARX_RT_LOGF_WARNING << deactivateSpam(0.5) << "Waiting for global pos";
// target->velocityX = 0;
// target->velocityY = 0;
// target->velocityRotation = 0;
// isAborted = true;
// return;
// }
if (not isTargetSet)
target->velocityX = 0;
target->velocityY = 0;
target->velocityRotation = 0;
{
// ARMARX_RT_LOGF_INFO << deactivateSpam(1) << "global pose not available";
target->velocityX = 0;
target->velocityY = 0;
target->velocityRotation = 0;
return;
}
const float measuredOrientation = global_orientation;
pid.update(
timeSinceLastIteration.toSecondsDouble(), global_P_robot, rtGetControlStruct().target);
opid.update(timeSinceLastIteration.toSecondsDouble(),
static_cast<double>(measuredOrientation),
rtGetControlStruct().targetOrientation);
const Eigen::Rotation2Df global_R_local(-measuredOrientation);
const Eigen::Vector2f velocities = global_R_local * pid.getControlValue();
target->velocityX = velocities.x();
target->velocityY = velocities.y();
target->velocityRotation = static_cast<float>(opid.getControlValue());
void
NJointHolonomicPlatformGlobalPositionController::rtPreActivateController()
target->velocityX = 0;
target->velocityY = 0;
target->velocityRotation = 0;
void
NJointHolonomicPlatformGlobalPositionController::setTarget(float x,
float y,
float yaw,
float translationAccuracy,
float rotationAccuracy)
{
// todo do we really need a recursive mutex?
std::lock_guard<std::recursive_mutex> lock(controlDataMutex);
getWriterControlStruct().target << x, y;
simox::math::periodic_clamp(yaw, -M_PIf, M_PIf);
getWriterControlStruct().translationAccuracy = translationAccuracy;
getWriterControlStruct().rotationAccuracy = rotationAccuracy;
getWriterControlStruct().newTargetSet = true;
writeControlStruct();
}
} // namespace armarx