Skip to content
Snippets Groups Projects
NJointHolonomicPlatformGlobalPositionController.cpp 5.86 KiB
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"
Christoph Pohl's avatar
Christoph Pohl committed
#include <cmath>
armar-user's avatar
armar-user committed
#include <SimoxUtility/math/convert/mat3f_to_rpy.h>
#include <SimoxUtility/math/convert/mat4f_to_rpy.h>
#include <SimoxUtility/math/periodic/periodic_clamp.h>
Christoph Pohl's avatar
Christoph Pohl committed

#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>
Christoph Pohl's avatar
Christoph Pohl committed
        registrationNJointHolonomicPlatformGlobalPositionController(
            "NJointHolonomicPlatformGlobalPositionController");

    NJointHolonomicPlatformGlobalPositionController::
        NJointHolonomicPlatformGlobalPositionController(
            RobotUnit*,
            const NJointHolonomicPlatformGlobalPositionControllerConfigPtr& cfg,
            const VirtualRobot::RobotPtr&) :
        pid(cfg->p, cfg->i, cfg->d, cfg->maxVelocity, cfg->maxAcceleration),
Christoph Pohl's avatar
Christoph Pohl committed
        opid(cfg->p_rot,
             cfg->i_rot,
             cfg->d_rot,
             cfg->maxRotationVelocity,
             cfg->maxRotationAcceleration,
             true)
Christoph Pohl's avatar
Christoph Pohl committed
        const SensorValueBase* sv =
            useSensorValue(GlobalRobotLocalizationSensorDevice::DeviceName());
armar-user's avatar
armar-user committed
        this->sv = sv->asA<GlobalRobotLocalizationSensorDevice::SensorValueType>();
Christoph Pohl's avatar
Christoph Pohl committed
        target = useControlTarget(cfg->platformName, ControlModes::HolonomicPlatformVelocity)
                     ->asA<ControlTargetHolonomicPlatformVelocity>();
        pid.threadSafe = false;
        opid.threadSafe = false;
Christoph Pohl's avatar
Christoph Pohl committed
    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();
Christoph Pohl's avatar
Christoph Pohl committed
        const Eigen::Vector2f global_P_robot = global_T_robot.block<2, 1>(0, 3);

        if (rtGetControlStruct().newTargetSet)
        {
            pid.reset();
            getWriterControlStruct().newTargetSet = false;
            writeControlStruct();
Christoph Pohl's avatar
Christoph Pohl committed



        // 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;

Christoph Pohl's avatar
Christoph Pohl committed
        if (not sv->isAvailable())
        {
            // 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;
Christoph Pohl's avatar
Christoph Pohl committed
        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());
Christoph Pohl's avatar
Christoph Pohl committed
    void
    NJointHolonomicPlatformGlobalPositionController::rtPreActivateController()
        target->velocityX = 0;
        target->velocityY = 0;
        target->velocityRotation = 0;
Christoph Pohl's avatar
Christoph Pohl committed
    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;
Christoph Pohl's avatar
Christoph Pohl committed
        getWriterControlStruct().targetOrientation =
            simox::math::periodic_clamp(yaw, -M_PIf, M_PIf);
        getWriterControlStruct().translationAccuracy = translationAccuracy;
        getWriterControlStruct().rotationAccuracy = rotationAccuracy;
Christoph Pohl's avatar
Christoph Pohl committed

        getWriterControlStruct().newTargetSet = true;
        writeControlStruct();
    }

} // namespace armarx