From 9947325ef2f04bbc6eb76eed7e129f9432815230 Mon Sep 17 00:00:00 2001 From: Stefan Reither <stef.reither@web.de> Date: Tue, 5 Dec 2017 14:56:29 +0100 Subject: [PATCH] adds possibility to show trajectory only as a preview to TrajectoryControllerSubUnit --- .../NJointTrajectoryController.cpp | 52 +++++++++----- .../NJointTrajectoryController.h | 7 +- .../Units/TrajectoryControllerSubUnit.cpp | 70 ++++++++++++++++++- .../Units/TrajectoryControllerSubUnit.h | 5 ++ .../RobotUnit/NJointTrajectoryController.ice | 1 + 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp index a98c0beb3..020b91bd6 100644 --- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp @@ -9,22 +9,18 @@ namespace armarx NJointTrajectoryController::NJointTrajectoryController(NJointControllerDescriptionProviderInterfacePtr prov, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr& robot) { cfg = NJointTrajectoryControllerConfigPtr::dynamicCast(config); - // robot->getRobotNode("")->isLimitless(); ARMARX_CHECK_EXPRESSION_W_HINT(cfg, "Needed type: NJointTrajectoryControllerConfigPtr"); - // trajectory = TrajectoryPtr::dynamicCast(cfg->trajectory); for (size_t i = 0; i < cfg->jointNames.size(); i++) { auto jointName = cfg->jointNames.at(i); ControlTargetBase* ct = prov->getControlTarget(jointName, ControlModes::Velocity1DoF); const SensorValueBase* sv = prov->getSensorValue(jointName); - targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>()); - sensors.push_back(sv->asA<SensorValue1DoFActuatorPosition>()); - PIDs.push_back(PIDControllerPtr(new PIDController(cfg->PID_p, - cfg->PID_i, cfg->PID_d, - cfg->maxVelocity))); + targets.insert(std::make_pair(jointName, ct->asA<ControlTarget1DoFActuatorVelocity>())); + sensors.insert(std::make_pair(jointName, sv->asA<SensorValue1DoFActuatorPosition>())); + // targets[jointName] = ct->asA<ControlTarget1DoFActuatorVelocity>(); + // sensors[jointName] = sv->asA<SensorValue1DoFActuatorPosition>(); } - currentPos.resize(cfg->jointNames.size()); } std::string NJointTrajectoryController::getClassName(const Ice::Current&) const @@ -38,18 +34,27 @@ namespace armarx { TIMING_START(TrajectoryControl); TrajectoryController& contr = *rtGetControlStruct().trajectory; - int i = 0; - for (auto& sv : sensors) + + auto dimNames = contr.getTraj()->getDimensionNames(); + for (size_t i = 0; i < dimNames.size(); i++) { - currentPos(i) = sv->position; - i++; + const auto& jointName = dimNames.at(i); + currentPos(i) = (sensors.count(jointName) == 1) ? sensors[jointName]->position : 0.0f; } + auto newVelocities = contr.update(timeSinceLastIteration.toSecondsDouble() * direction, currentPos); bool finished = (contr.getCurrentTimestamp() >= contr.getTraj()->rbegin()->getTimestamp() && direction == 1.0) || (contr.getCurrentTimestamp() <= contr.getTraj()->begin()->getTimestamp() && direction == -1.0); - for (size_t i = 0; i < targets.size(); ++i) + if (!cfg->isPreview) { - targets.at(i)->velocity = finished ? 0.0f : newVelocities(i); + for (size_t i = 0; i < dimNames.size(); ++i) + { + const auto& jointName = dimNames.at(i); + if (targets.count(jointName) == 1) + { + targets[jointName]->velocity = finished ? 0.0f : newVelocities(i); + } + } } if (finished && looping) @@ -130,6 +135,7 @@ namespace armarx } trajEndTime = *trajectory->getTimestamps().rbegin() - *trajectory->getTimestamps().begin(); + currentPos.resize(trajectory->getDimensionNames().size()); LockGuardType guard {controlDataMutex}; getWriterControlStruct().trajectory.reset(new TrajectoryController(trajectory, cfg->PID_p, cfg->PID_i, cfg->PID_d, false)); @@ -162,6 +168,20 @@ namespace armarx return trajEndTime; } + TrajectoryPtr NJointTrajectoryController::getTrajectoryCopy() const + { + LockGuardType guard {controlDataMutex}; + TrajectoryControllerPtr contr = rtGetControlStruct().trajectory; + if (contr) + { + return TrajectoryPtr::dynamicCast(contr->getTraj()->clone()); + } + else + { + return new Trajectory(); + } + } + void NJointTrajectoryController::rtPreActivateController() { startTime = IceUtil::Time(); @@ -169,9 +189,9 @@ namespace armarx void NJointTrajectoryController::rtPostDeactivateController() { - for (size_t i = 0; i < targets.size(); ++i) + for (auto& target : targets) { - targets.at(i)->velocity = 0.0f; + target.second->velocity = 0.0f; } } diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h index aec0b8035..20090d066 100644 --- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h @@ -4,7 +4,6 @@ #include "NJointController.h" #include <VirtualRobot/Robot.h> #include <RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.h> -#include <RobotAPI/libraries/core/PIDController.h> #include <RobotAPI/libraries/core/TrajectoryController.h> #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h> #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h> @@ -41,12 +40,12 @@ namespace armarx double getCurrentTrajTime() const; void setLooping(bool looping); double getTrajEndTime() const; + TrajectoryPtr getTrajectoryCopy() const; private: // TrajectoryPtr trajectory; IceUtil::Time startTime; - std::vector<PIDControllerPtr> PIDs; - std::vector<ControlTarget1DoFActuatorVelocity*> targets; - std::vector<const SensorValue1DoFActuatorPosition*> sensors; + std::map<std::string, ControlTarget1DoFActuatorVelocity*> targets; + std::map<std::string, const SensorValue1DoFActuatorPosition*> sensors; Eigen::VectorXf currentPos; bool looping = false; float direction = 1.0; diff --git a/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.cpp b/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.cpp index 110aa4865..d62a7df31 100644 --- a/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.cpp +++ b/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.cpp @@ -35,11 +35,14 @@ void TrajectoryControllerSubUnit::onInitComponent() ki = getProperty<float>("Ki").getValue(); kd = getProperty<float>("Kd").getValue(); maxVelocity = getProperty<float>("absMaximumVelocity").getValue() / 180 * M_PI; // config expects value in rad/sec + + offeringTopic("DebugDrawerUpdates"); } void TrajectoryControllerSubUnit::onConnectComponent() { kinematicUnit = getProxy<KinematicUnitInterfacePrx>(kinematicUnitName); + debugDrawer = getTopic<armarx::DebugDrawerInterfacePrx>("DebugDrawerUpdates"); } bool TrajectoryControllerSubUnit::startTrajectoryPlayer(const Ice::Current& c) @@ -48,7 +51,19 @@ bool TrajectoryControllerSubUnit::startTrajectoryPlayer(const Ice::Current& c) assureTrajectoryController(); jointTrajController->setTrajectory(this->jointTraj, c); + jointTraj = jointTrajController->getTrajectoryCopy(); jointTrajController->activateController(); + + if (isPreview) + { + ARMARX_INFO << "robot file name : " << kinematicUnit->getRobotFilename(); + debugDrawer->setRobotVisu("Preview", "previewRobot", kinematicUnit->getRobotFilename(), boost::join(kinematicUnit->getArmarXPackages(), ","), armarx::CollisionModel); + debugDrawer->updateRobotColor("Preview", "previewRobot", DrawColor {0, 1, 0, 0.5}); + + previewTask = new PeriodicTask<TrajectoryControllerSubUnit>(this, &TrajectoryControllerSubUnit::previewRun, 20, false, "TrajectoryControllerSubUnitPreviewTask", false); + previewTask->start(); + } + return true; } @@ -72,6 +87,12 @@ bool TrajectoryControllerSubUnit::stopTrajectoryPlayer(const Ice::Current& c) { if (controllerExists()) { + if (isPreview) + { + previewTask->stop(); + debugDrawer->clearLayer("Preview"); + } + jointTrajController->deactivateController(); while (jointTrajController->isControllerActive()) {} jointTrajController->deleteController(); @@ -225,7 +246,18 @@ void TrajectoryControllerSubUnit::setEndTime(Ice::Double end, const Ice::Current void TrajectoryControllerSubUnit::setIsPreview(bool isPreview, const Ice::Current& c) { - ARMARX_WARNING << "NYI : TrajectoryControllerSubUnit::setIsPreview()"; + if (controllerExists() && jointTrajController->isControllerActive()) + { + ARMARX_WARNING << "TrajectoryController already running. Please reset it before setting wheter the controller is only for preview."; + return; + } + this->isPreview = isPreview; + + if (jointTraj) + { + jointTrajController = createTrajectoryController(usedJoints, false); + jointTrajController->setTrajectory(jointTraj, c); + } } bool TrajectoryControllerSubUnit::setJointsInUse(const std::string& jointName, bool isInUse, const Ice::Current& c) @@ -278,7 +310,7 @@ void TrajectoryControllerSubUnit::considerConstraints(bool consider, const Ice:: { if (controllerExists() && jointTrajController->isControllerActive()) { - ARMARX_WARNING << "TrajectoryController already running. Please reset it before setting joints in use."; + ARMARX_WARNING << "TrajectoryController already running. Please reset it before setting whether constraints should be considered."; return; } considerConstraintsForTrajectoryOptimization = consider; @@ -316,6 +348,13 @@ NJointTrajectoryControllerPtr TrajectoryControllerSubUnit::createTrajectoryContr config->maxVelocity = maxVelocity; config->jointNames = jointNames; config->considerConstraints = considerConstraintsForTrajectoryOptimization; + config->isPreview = isPreview; + + ARMARX_IMPORTANT << config->PID_p << "\n" + << config->PID_i << "\n" << config->PID_i << "\n" + << config->maxVelocity << "\n" << config->jointNames << "\n" + << config->considerConstraints << "\n" << config->isPreview << "\n"; + trajController = NJointTrajectoryControllerPtr::dynamicCast( robotUnit->createNJointController( "NJointTrajectoryController", controllerName, @@ -355,6 +394,33 @@ bool TrajectoryControllerSubUnit::controllerExists() return false; } +void TrajectoryControllerSubUnit::previewRun() +{ + if (controllerExists()) + { + if (jointTrajController->isControllerActive()) + { + ARMARX_DEBUG << "Preview ... "; + + std::vector<Ice::DoubleSeq > states = jointTraj->getAllStates(jointTrajController->getCurrentTrajTime(), 1); + NameValueMap targetPositionValues; + + auto dimNames = jointTraj->getDimensionNames(); + + for (size_t i = 0; i < dimNames.size(); i++) + { + const auto& jointName = dimNames.at(i); + if (std::find(usedJoints.begin(), usedJoints.end(), jointName) != usedJoints.end()) + { + targetPositionValues[jointName] = states[i][0]; + } + } + + debugDrawer->updateRobotConfig("Preview", "previewRobot", targetPositionValues); + } + } +} + void TrajectoryControllerSubUnit::setup(RobotUnit* rUnit) { ARMARX_CHECK_EXPRESSION(!robotUnit); diff --git a/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.h b/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.h index 7b3ba80aa..71195a63e 100644 --- a/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.h +++ b/source/RobotAPI/components/units/RobotUnit/Units/TrajectoryControllerSubUnit.h @@ -129,6 +129,7 @@ namespace armarx NJointTrajectoryControllerPtr createTrajectoryController(std::vector<std::string>& jointNames, bool deleteIfAlreadyExist); void assureTrajectoryController(); bool controllerExists(); + void previewRun(); RobotUnit* robotUnit = NULL; NJointTrajectoryControllerPtr jointTrajController; @@ -155,6 +156,10 @@ namespace armarx float maxVelocity; bool considerConstraintsForTrajectoryOptimization = false; + bool isPreview = false; + DebugDrawerInterfacePrx debugDrawer; + PeriodicTask<TrajectoryControllerSubUnit>::pointer_type previewTask; + Mutex dataMutex; }; } diff --git a/source/RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.ice b/source/RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.ice index 570f51f8a..e4e299be9 100644 --- a/source/RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.ice +++ b/source/RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.ice @@ -39,6 +39,7 @@ module armarx float PID_i = 0; float PID_d = 0; bool considerConstraints = true; + bool isPreview = false; }; interface NJointTrajectoryControllerInterface extends NJointControllerInterface -- GitLab