Follower.cpp
Go to the documentation of this file.
1#include "Follower.h"
2
3#include <Eigen/Core>
4#include <Eigen/Geometry>
5
6#include <SimoxUtility/math/convert.h>
7#include <VirtualRobot/Robot.h>
8#include <VirtualRobot/RobotNodeSet.h>
9#include <VirtualRobot/VirtualRobot.h>
10
12
13#include <RobotAPI/interface/units/RobotUnit/TaskSpaceActiveImpedanceControl.h>
14
20#include <armarx/control/skills/skills/platform_follower_controller/aron/FollowerParams.aron.generated.h>
21
23{
24
27 {
28 ParamType defaultParams;
29 defaultParams.platformControlConfig.nodeSetNameLeft = "LeftArm";
30 defaultParams.platformControlConfig.nodeSetNameRight = "RightArm";
31 defaultParams.platformControlConfig.kPos = 12;
32 defaultParams.platformControlConfig.kAngle = 8;
33 defaultParams.platformControlConfig.dPos = 0;
34 defaultParams.platformControlConfig.dAngle = 0;
35
36 return ::armarx::skills::SkillDescription{.skillId = {.skillName = "Follower"},
37 .description =
38 "TODO: Description of skill Follower.",
39 .rootProfileDefaults = defaultParams.toAron(),
40 .timeout = ::armarx::Duration::Days(1),
41 .parametersType = ParamType::ToAronType()};
42 }
43
45 ::armarx::skills::SimpleSpecializedSkill<ParamType>(GetSkillDescription()),
46 // ::armarx::skills::mixin::RobotReadingSkillMixin(services.mns),
47 services_(services),
48 parameters_(parameters)
49 {
50 ARMARX_CHECK_NOT_NULL(services_.controlComponentPlugin);
51
52 // auto robotUnit = controlComponentPlugin->getRobotUnitPlugin().getRobotUnit();
53 // robotUnit->loadLibFromPackage("armarx_control", "armarx_control_njoint_mp_controller");
54 // robotUnit->loadLibFromPackage("armarx_control", "armarx_control_njoint_controller");
55 // robotUnit->loadLibFromPackage("eurobin_wp2_skills", "eurobin_wp2_skills_platform_follower_controller");
56 }
57
58 /*
59 bool
60 Follower::isAvailable(const SpecializedInitInput&) const
61 {
62 return true;
63 }
64 */
65
66 /*
67 ::armarx::skills::Skill::InitResult
68 Follower::init(const SpecializedInitInput&)
69 {
70 return InitResult{.status = ::armarx::skills::TerminatedSkillStatus::Succeeded};
71 }
72 */
73
74
76 Follower::main(const SpecializedMainInput& in)
77 {
78 // robotReader.connect();
79 VirtualRobot::RobotPtr robot = services_.robotReader.getRobotWaiting(parameters_.robotName);
82
83 VirtualRobot::RobotNodeSetPtr rnsRight = robot->getRobotNodeSet("RightArm"); // TODO
84 VirtualRobot::RobotNodeSetPtr rnsLeft = robot->getRobotNodeSet("LeftArm"); // TODO
85
86 std::map<std::string,
89 controllers;
90 for (const auto& rns : {rnsRight, rnsLeft})
91 {
92 /// create controllers with controller builder
93 auto builder =
96
97 builder.withNodeSet(rns->getName()).withNamePrefix(rns->getName());
98
99 /// load predefined config from file
100 {
101 if (in.parameters.jointConfigFileName.empty())
102 {
103 const std::string controllerClassName =
106 const armarx::PackagePath configPath(
107 "armarx_control",
108 "controller_config/NJointTaskspaceImpedanceController/"
109 "bimanual_transport_default.json");
110 ARMARX_IMPORTANT << "Using config `" << configPath.toSystemPath() << "`.";
111 ARMARX_CHECK(std::filesystem::exists(configPath.toSystemPath()))
112 << configPath.toSystemPath();
113
114 builder.withConfig(configPath.toSystemPath());
115 }
116 else
117 {
118 builder.withConfig(in.parameters.jointConfigFileName);
119 }
120
121 ARMARX_CHECK(builder.config().limbs.count("LeftArm") > 0);
122 ARMARX_CHECK(builder.config().limbs.count("RightArm") > 0);
123
124 // const auto& leftConfig = builder.config().limbs.at("LeftArm");
125 // const auto& rightConfig = builder.config().limbs.at("RightArm");
126
127 // /// to be removed
128 // ARMARX_INFO << VAROUT(armConfig.kpImpedance);
129 // ARMARX_INFO << VAROUT(armConfig.kdImpedance);
130 // ARMARX_INFO << VAROUT(armConfig.kpNullspaceTorque);
131 // ARMARX_INFO << VAROUT(armConfig.kdNullspaceTorque);
132 // ARMARX_INFO << VAROUT(armConfig.desiredPose);
133 // ARMARX_INFO << VAROUT(armConfig.desiredTwist);
134 // if (armConfig.desiredNullspaceJointAngles.has_value())
135 // {
136 // ARMARX_INFO << VAROUT(armConfig.desiredNullspaceJointAngles.value());
137 // }
138 // ARMARX_INFO << VAROUT(armConfig.torqueLimit);
139 // ARMARX_INFO << VAROUT(armConfig.qvelFilter);
140 }
141
142
143 ARMARX_INFO << "Setting desired pose for controller with nodeset " << rns->getName()
144 << ".";
145 auto& armConfig = builder.config().limbs.at(rns->getName());
146
147
148 // TODO add offset in global z-direction
149 armConfig.desiredPose = rns->getTCP()->getPoseInRootFrame();
150 ARMARX_IMPORTANT << VAROUT(armConfig.desiredPose);
151
153 ARMARX_INFO << "creating controller";
154
155 auto ctrlWrapper = builder.create();
156 const std::string controllerName = builder.getControllerName();
157
158 // The controller is scoped by default, which means that if the ControllerWrapper goes out of scope, it will deactivate
159 // and delete the NJointController. To prevent this, you can use the daemonize(true) method if needed.
160 ctrlWrapper->daemonize(false);
161
163 ARMARX_CHECK_NOT_NULL(ctrlWrapper);
164
165 controllers.emplace(rns->getName(), std::move(ctrlWrapper));
166 }
167
169
170 ARMARX_INFO << "Activating controller";
171 for (auto& c : controllers)
172 {
173 c.second->updateConfig();
174
175 if (not services_.controlComponentPlugin->getRobotUnitPlugin()
176 .getRobotUnit()
177 ->isSimulation())
178 {
179 c.second->activate();
180 }
181 }
182
183
184 // TODO sleep for in.getMinExecutionTime() usleep(10000);
185
186 // TODO Trigger speech output
187
188 // TOOD start platform following
189 const auto platformControlConfig = in.parameters.platformControlConfig;
190
191 // TODO stop platform unit -> trigger placing
192
193 constexpr auto ControllerType = ::armarx::control::njoint_controller::platform::
194 ControllerType::PlatformFollowerController;
195
196 auto platformControllerBuilder =
197 services_.controlComponentPlugin->createControllerBuilder<ControllerType>();
198 platformControllerBuilder.withNodeSet("Platform").withNamePrefix("Andre");
199
200
201 {
202 const std::string controllerClassName =
205 const armarx::PackagePath configPath(
206 "armarx_control", "controller_config/PlatformFollowerController/default.json");
207 ARMARX_IMPORTANT << "Using config `" << configPath.toSystemPath() << "`.";
208 ARMARX_CHECK(std::filesystem::exists(configPath.toSystemPath()));
209
210 platformControllerBuilder.withConfig(configPath.toSystemPath());
211 }
212 // TODO add support of using a diffeerent default parameters, for different robots.
213 // platformControllerBuilder.config().params.kPos = in.parameters.platformControlConfig.kPos;
214 // platformControllerBuilder.config().params.kAngle = in.parameters.platformControlConfig.kAngle;
215 // platformControllerBuilder.config().params.dPos = in.parameters.platformControlConfig.dPos;
216 // platformControllerBuilder.config().params.dAngle = in.parameters.platformControlConfig.dAngle;
217
218 // platformControllerBuilder.config().params.maxAngleVel = in.parameters.platformControlConfig.maxAngleVel;
219 // platformControllerBuilder.config().params.maxPosVel = in.parameters.platformControlConfig.maxPosVel;
220
221 // platformControllerBuilder.config().params.minAngleTolerance = in.parameters.platformControlConfig.minAngleTolerance;
222 // platformControllerBuilder.config().params.minPosTolerance = in.parameters.platformControlConfig.minPosTolerance;
223
224 auto platformCtrlWrapper = platformControllerBuilder.create();
225
226 ARMARX_INFO << "Activating platform controller.";
227 platformCtrlWrapper->activate();
228
229 while (not shouldSkillTerminate())
230 {
232 }
233
234 ARMARX_INFO << "Stop requested. Deactivating controllers.";
235 for (auto& c : controllers)
236 {
237 c.second->deactivate();
238 }
239 platformCtrlWrapper->deactivate();
240
241
242 return MainResult{
244 .data = nullptr,
245 };
246 }
247
248 /*
249 ::armarx::skills::Skill::ExitResult
250 Follower::exit(const SpecializedExitInput&)
251 {
252 return ExitResult{.status = ::armarx::skills::TerminatedSkillStatus::Succeeded};
253 }
254 */
255
256} // namespace armarx::control::skills::skills::platform_follower_controller
#define VAROUT(x)
constexpr T c
static void WaitFor(const Duration &duration)
Wait for a certain duration on the virtual clock.
Definition Clock.cpp:99
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
static Duration Days(std::int64_t days)
Constructs a duration in days.
Definition Duration.cpp:144
VirtualRobot::RobotPtr getRobotWaiting(const std::string &name, const armem::Time &timestamp=armem::Time::Invalid(), const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure)
In contrast to getRobot(), this function will retry to query the robot until it exists.
bool synchronizeRobot(VirtualRobot::Robot &robot, const armem::Time &timestamp) const
Synchronize both the platform pose and the joint values of a virtual robot, according to the robot st...
armarx::plugins::RobotUnitComponentPlugin & getRobotUnitPlugin()
Wrapper class for an NJointController proxy.
Follower(const Services &services, const Parameters &parameters)
Definition Follower.cpp:44
static DateTime Now()
Definition DateTime.cpp:51
armarx::aron::data::DictPtr parameters
Definition Skill.h:369
bool shouldSkillTerminate() const override
Returns whether the skill should terminate as soon as possible.
Definition Skill.cpp:469
virtual MainResult main()
Override this method with the actual implementation.
Definition Skill.cpp:542
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
const simox::meta::EnumNames< ControllerType > ControllerTypeNames
Definition type.h:170
This file offers overloads of toIce() and fromIce() functions for STL container types.
This file is part of ArmarX.
A result struct for th main method of a skill.
Definition Skill.h:62
#define ARMARX_TRACE
Definition trace.h:77