RobotHeadMovement.cpp
Go to the documentation of this file.
1#include "RobotHeadMovement.h"
2
6
8{
9
10 void
12 const std::string& prefix)
13 {
14 defs->optional(
16 prefix + "checkHeadVelocity",
17 "If true, check whether the head is moving and discard updates in the meantime.");
18 defs->optional(maxJointVelocity,
19 prefix + "maxJointVelocity",
20 "If a head joint's velocity is higher, the head is considered moving.");
21 defs->optional(discardIntervalAfterMoveMS,
22 prefix + "discardIntervalAfterMoveMS",
23 "For how long new updates are ignored after moving the head.");
24 }
25
26 void
28 {
30 {
31 for (const std::string& jointName : jointNames)
32 {
33 std::string error = "";
34 try
35 {
36 DatafieldRefBasePtr datafield = kinematicUnitObserver->getDatafieldRefByName(
38 DatafieldRefPtr casted = DatafieldRefPtr::dynamicCast(datafield);
39 if (casted)
40 {
41 jointVelocitiesDatafields.push_back(casted);
42 }
43 }
44 catch (const InvalidDatafieldException& e)
45 {
46 error = e.what();
47 }
48 catch (const InvalidChannelException& e)
49 {
50 error = e.what();
51 }
52 if (error.size() > 0)
53 {
54 ARMARX_WARNING << "Could not get datafield for joint '" << jointName
55 << "' in channel '" << jointVelocitiesChannelName << "': \n "
56 << error;
57 }
58 }
59 }
60 else
61 {
62 ARMARX_INFO << "Cannot fetch joint velocity datafields because there is no kinematic "
63 "unit observer.";
64 }
65 }
66
67 bool
69 {
71 {
72 if (df)
73 {
74 float jointVelocity = df->getFloat();
75 // ARMARX_IMPORTANT << "Is " << df->datafieldName << " " << VAROUT(std::abs(jointVelocity)) << " > " << VAROUT(maxJointVelocity) << "?";
76 if (std::abs(jointVelocity) > maxJointVelocity)
77 {
78 return true;
79 }
80 }
81 }
82 return false;
83 }
84
85 void
86 RobotHeadMovement::movementStarts(long discardIntervalMs)
87 {
88 return movementStarts(Duration::MilliSeconds(discardIntervalMs));
89 }
90
91 void
93 {
94 discardUpdatesUntil = DateTime::Now() + discardInterval;
95 }
96
97 void
98 RobotHeadMovement::movementStops(long discardIntervalMs)
99 {
100 return movementStops(Duration::MilliSeconds(discardIntervalMs));
101 }
102
103 void
105 {
106 if (discardInterval.toMilliSeconds() < 0)
107 {
108 // Stop discarding.
110 }
111 else
112 {
113 // Basically the same as starting.
114 discardUpdatesUntil = DateTime::Now() + discardInterval;
115 }
116 }
117
118 objpose::SignalHeadMovementOutput
119 RobotHeadMovement::signalHeadMovement(const objpose::SignalHeadMovementInput& input)
120 {
121 objpose::SignalHeadMovementOutput output;
122 switch (input.action)
123 {
124 case objpose::HeadMovementAction::HeadMovementAction_Starting:
125 this->movementStarts(input.discardUpdatesIntervalMilliSeconds < 0
126 ? this->discardIntervalAfterMoveMS
127 : input.discardUpdatesIntervalMilliSeconds);
128 break;
129 case objpose::HeadMovementAction::HeadMovementAction_Stopping:
130 this->movementStops(input.discardUpdatesIntervalMilliSeconds);
131 break;
132 default:
133 ARMARX_UNEXPECTED_ENUM_VALUE(objpose::HeadMovementAction, input.action);
134 break;
135 }
136 output.discardUpdatesUntilMilliSeconds =
137 this->discardUpdatesUntil.toMilliSecondsSinceEpoch();
138 return output;
139 }
140
143 {
144 Discard discard;
146 {
147 if (isMoving())
148 {
150 // ARMARX_IMPORTANT << "Ignoring pose update because robot head is moving! until " << discardUpdatesUntil;
151 discard.all = true;
152 }
154 {
155 discard.all = true;
156 // ARMARX_IMPORTANT << "Ignoring pose update because robot head has moved until: " << discardUpdatesUntil;
157 }
158 else
159 {
161 }
162 }
163 return discard;
164 }
165
166 void
168 {
169 using namespace armarx::RemoteGui::Client;
170
172 {
173 float max = 10.0;
174 maxJointVelocity.setRange(0, max);
175 maxJointVelocity.setDecimals(3);
176 maxJointVelocity.setSteps(int(100 * max)); // = 0.01 steps
178 }
179 {
180 int max = 10 * 1000;
181 discardIntervalAfterMoveMS.setRange(0, max);
183 }
184
185 GridLayout grid;
186 int row = 0;
187 grid.add(Label("Check Head Motion"), {row, 0}).add(checkHeadVelocity, {row, 1});
188 row++;
189 grid.add(Label("Max Joint Velocity"), {row, 0}).add(maxJointVelocity, {row, 1});
190 row++;
191 grid.add(Label("Discard Interval after Move [ms]"), {row, 0})
192 .add(discardIntervalAfterMoveMS, {row, 1});
193 row++;
194
195 group.setLabel("Robot Head Movement");
196 group.addChild(grid);
197 }
198
199 void
206
207} // namespace armarx::armem::server::obj::instance
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
Definition Bitmap.cpp:801
#define ARMARX_UNEXPECTED_ENUM_VALUE(EnumType, value)
Throw an UnexpectedEnumValueException.
static DateTime Now()
Definition DateTime.cpp:51
static DateTime Invalid()
Definition DateTime.cpp:57
objpose::SignalHeadMovementOutput signalHeadMovement(const objpose::SignalHeadMovementInput &input)
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="head.")
std::int64_t toMilliSeconds() const
Returns the amount of milliseconds.
Definition Duration.cpp:60
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
armarx::core::time::Duration Duration
IceInternal::Handle< DatafieldRef > DatafieldRefPtr
Definition Observer.h:43
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})
Definition Widgets.cpp:438