gusimplewhiteboard
MOTION_Interface.hpp
Go to the documentation of this file.
1
10#ifndef MOTION_Interface_DEFINED
11#define MOTION_Interface_DEFINED
12#define MOTION_Commands_DEFINED
13#define MOTION_Status_DEFINED
14
15#ifdef WHITEBOARD_POSTER_STRING_CONVERSION
16#include <cctype>
17#include <cstdlib>
18#endif // WHITEBOARD_POSTER_STRING_CONVERSION
19
20#include <string>
21#include <sstream>
22#include <vector>
23#include <map>
24#include <gu_util.h>
25
26#pragma clang diagnostic push
27#pragma clang diagnostic ignored "-Wpadded"
28
29#define MOTION_DIR "/data/motions/"
30#define MOTION_FILE_POSTFIX ".mot"
31#define JOINT_CHAIN_MAXSIZE 10
32#define CHAIN_IGNORED_MOTION_DURATION 100 //cycles
33#define TRANSITION_NAME(s, e) TRANSITION_NAME_FROM_STRING(stance_strings[s], stance_strings[e])
34#define TRANSITION_NAME_FROM_STRING(s, e) ((((std::string("transition_") += s) += "_") += e) += MOTION_FILE_POSTFIX)
35#define ACTION_NAME(a, s) ((((std::string("action_") += stance_strings[s]) += "_") += action_strings[a]) += MOTION_FILE_POSTFIX)
36#define STANCE_NAME(s) STANCE_NAME_FROM_STRING(stance_strings[s])
37#define STANCE_NAME_FROM_STRING(s) std::string("stance_").append(std::string(s).append(MOTION_FILE_POSTFIX))
38
39#define MAP_ACTION_ENTRY(a, s, c) v[a] = Action_Transition(a, s, c);
40
41#define MY_CHECK_ENUM(s,p,v) if (strstr((s), #v)) p = v
42
43
44namespace guWhiteboard
45{
46 namespace Motions
47 {
52 {
57 Motions
58 };
59
63 enum stance
64 {
73 };
74
78 enum action
79 {
91 };
92
96 static const char *stance_strings[NUM_OF_STANCES] =
97 {
98 "Standby_stance",
99 "Kneeling_stance",
100 "Standing_stance",
101 "GoalieSaveLeft_stance",
102 "GoalieSaveRight_stance",
103 "FallenForward_stance",
104 "FallenBack_stance",
105 };
106
110 static const char *action_strings[NUM_OF_ACTIONS] =
111 {
112 "Kneeling_wave",
113 "Kneeling_quickwave",
114 "Kneeling_flagwave", // Jeremy's Flag Wave
115 "Kneeling_raiseright", // Vlad's's Threat to Hit
116 "Kneeling_signal", // Vlad's's signal where to Hit
117 "Standing_leftkick",
118 "Standing_rightkick",
119 "Standing_leftpass",
120 "Standing_rightpass",
121 "Standing_wave"
122 };
123
128 {
131 int _cost;
132 std::string _name;
134 Stance_Transition(stance s, stance e, int cost) : _s(s), _e(e), _cost(cost), _name(TRANSITION_NAME(s, e)) { }
135 };
136
140 struct T{
145 static std::vector<Stance_Transition> create_transitions() //many paths to a stance will work (picks shortest by using the cost)
146 {
147 std::vector<Stance_Transition> v;
161
162 return v;
163 }
164 static const std::vector<Stance_Transition> _transitions;
165 };
166
171 {
174 int _cost;
175 std::string _name;
177 Action_Transition(action a = Kneeling_wave, stance s = Kneeling_stance, int cost = 1): _a(a), _s(s), _cost(cost), _name(ACTION_NAME(a, s)) { }
178 };
179
183 struct A{//CHANGE FROM MAP TO VECTOR AND USE THE ENUM INDEX TO GET THE ACTION_TRANSITION O(1)
188 static std::map<action, Action_Transition> create_actions() //each action may only have one stance
189 {
190 std::map<action, Action_Transition> v;
191 MAP_ACTION_ENTRY(Kneeling_wave, Kneeling_stance, 550) //cost should be time to perform the action
192 MAP_ACTION_ENTRY(Kneeling_quickwave, Kneeling_stance, 450) //cost should be time to perform the action
193 // Jeremy's Flag Wave Action.
202
203 return v;
204 }
205 static const std::map<action, Action_Transition> _actions;
206 };
207
208
216 {
217 private:
218 int _cost;
219 int _off;
220 bool _reached;
221 public:
223
227 Stance_Path(): _cost(0), _off(0), _reached(false) { }
228 int offset() { return _off; }
229 bool valid() { return _cost != -1 ? true : false; }
230 void invalidate() { _cost = -1; }
231 void reached() { _reached = true; }
232 int cost() { return _cost; }
233
239 void add_stance(stance s, int cost) { if(_off == (JOINT_CHAIN_MAXSIZE-1)) { invalidate(); } _stances[_off] = static_cast<u_int8_t>(s); _off++; _cost += cost; } //JOINT_CHAIN_MAXSIZE-1 leaves room for an action
246 void add_stance(stance s, int cost, int transition) { if(_off == (JOINT_CHAIN_MAXSIZE-1)) { invalidate(); } _stances[_off] = static_cast<u_int8_t>(transition+NUM_OF_STANCES+NUM_OF_ACTIONS); _off++; _stances[_off] = static_cast<u_int8_t>(s); _off++; _cost += cost; } //JOINT_CHAIN_MAXSIZE-1 leaves room for an action
251 {
252 std::stringstream ss;
253 ss << "Stance_Path: " << static_cast<int>(_off) << " ";
254 for(int i = 0; i < _off; i++)
255 {
256 if(_stances[i] < NUM_OF_STANCES)
257 ss << "-> " << static_cast<int>(_stances[i]) << " " << stance_strings[_stances[i]];
258 else
259 ss << " transition: " << static_cast<int>(_stances[i]) << " ";
260 }
261 fprintf(stderr, "%s\n", ss.str().c_str());
262 }
269 {
270 for(int i = 0; i < _off; i++)
271 {
272 if(_stances[i] == s)
273 return true;
274 }
275 return false;
276 }
277 };
278 }
279
296 {
297
299 BIT_PROPERTY(running)
300
301
302 PROPERTY(int8_t, expected_stance)
303
304
305 PROPERTY(int8_t, verified_stance)
306
307 public:
308
315 MOTION_Status(bool running, int8_t expected, int8_t verified)
316 {
317 _running = running;
318 _expected_stance = expected;
319 _verified_stance = verified;
320 }
321
326 bool isRunning() { return _running; }
327
332 Motions::stance expectedStance() { return static_cast<Motions::stance>(_expected_stance); }
333
338 Motions::stance verifiedStance() { return static_cast<Motions::stance>(_verified_stance); }
339
340#ifdef WHITEBOARD_POSTER_STRING_CONVERSION
345 MOTION_Status(const std::string &str) { from_string(str); }
346
351 void from_string(const std::string &str)
352 {
353 if(str.size() == 0)
354 return;
355 //NYI
356 }
357
362 std::string description()
363 {
364 std::stringstream ss;
365 ss << "Running: " << isRunning() << ", ";
366
367 ss << "Expected: ";
368 Motions::stance e = expectedStance();
370 ss << Motions::stance_strings[e];
371 else
372 ss << "unknown";
373 ss << ", ";
374
375 ss << "Verified (NYI): ";
376 Motions::stance v = verifiedStance();
378 ss << Motions::stance_strings[v];
379 else
380 ss << "unknown";
381
382 return ss.str();
383 }
384#endif // WHITEBOARD_POSTER_STRING_CONVERSION
385 };
386
416 {
418 ARRAY_PROPERTY(u_int8_t, stance_action, JOINT_CHAIN_MAXSIZE)
419
420 PROPERTY(int8_t, num_of_stance_actions)
421
422
423 BIT_PROPERTY(stance_action_mask)
424
425 BIT_PROPERTY(ignore_chain)
426
427 BIT_PROPERTY(ignore_chain_mask)
428
429
430 BIT_PROPERTY(head_stiffness)
431
432 BIT_PROPERTY(body_stiffness)
433
434 /* Control bits */
436 BIT_PROPERTY(head_stiffness_mask)
437
438 BIT_PROPERTY(body_stiffness_mask)
439
440 public:
441
448 MOTION_Commands(bool head_stiffness = false, bool body_stiffness = false, bool masks = false/*, Motions::stance stance = Motions::Kneeling_stance*/)
449 {
450 memset(this, 0, sizeof(*this));
451 _head_stiffness = head_stiffness;
452 _body_stiffness = body_stiffness;
453 _stance_action_mask = false;
454 _ignore_chain_mask = false;
455 _head_stiffness_mask = masks;
456 _body_stiffness_mask = masks;
457 //goto stance stance_action! NYI
458// _motion_player = motion_player;
459 }
460
461 private:
462
471 {
472 const std::vector<Motions::Stance_Transition> _transitions = Motions::T::create_transitions(); // move this out of here!
473
474 if(current == desired)
475 {
476 p.reached();
477 return p;
478 }
479
481 r.invalidate();
482
483 for (unsigned i = 0; i < _transitions.size(); i++)
484 {
485 if(_transitions[i]._s == current && !p.contains(_transitions.at(i)._e)) // I can use this transiton from my current stance
486 {
488 p2.add_stance(_transitions.at(i)._e, _transitions.at(i)._cost, int(i));
489
490 Motions::Stance_Path c = decide_stance(_transitions.at(i)._e, desired, p2);
491 if(!r.valid() || (c.cost() < r.cost() && c.valid()))
492 r = c;
493 }
494 }
495
496 return r;
497 }
498
499
500 public:
501
509 {
510 if(current == Motions::NUM_OF_STANCES || desired == Motions::NUM_OF_STANCES)
511 {
512 fprintf(stderr, "MOTION_Interface.h: \n"\
513 "\tGoToStance: \n"\
514 "\t\tGoToStance change aborted! \n"\
515 "\t\tThe passed variables 'current' and 'desired' must not be equal to Motions::NUM_OF_STANCES. \n"\
516 "\t\tYou may be trying to set them with expected_stance(). This only provides you with a reference to the last Stance that Motion got to. If this is the first Stance change then expected_stance() is set to Motions::NUM_OF_STANCES and you are getting this error.\n");
517 return -1;
518 }
520 p.add_stance(current, 1);
521 p = decide_stance(current, desired, p);
522 p.pretty_print();
523
524 memcpy(_stance_action, p._stances, sizeof(p._stances));
525 _num_of_stance_actions = static_cast<int8_t>(p.offset());
526 _stance_action_mask = true;
527
528 return p.cost();
529 }
530
538 {
539 std::map<Motions::action, Motions::Action_Transition> _actions = Motions::A::create_actions(); // move this out of here!
540 Motions::Action_Transition at = _actions[a];
541
543 p.add_stance(current, 1);
544
545 p = decide_stance(current, at._s, p); //I would use GoToStance however I need the path step offset
546 memcpy(_stance_action, p._stances, sizeof(p._stances));
547
548 _stance_action[p.offset()] = static_cast<uint8_t>(Motions::NUM_OF_STANCES) + static_cast<uint8_t>(a);
549
550 _num_of_stance_actions = static_cast<int8_t>(p.offset()+1);
551 _stance_action_mask = true;
552
553 return p.cost() + at._cost;
554 }
555
556#ifdef WHITEBOARD_POSTER_STRING_CONVERSION
561 MOTION_Commands(const std::string &str) { from_string(str); }
562
567 void from_string(const std::string &str)
568 {
569 set_ignore_chain_mask(false);
570
571 using namespace Motions;
572 const char *s = str.c_str();
573 bool want_head_stiffness = isdigit(*s);
574
575 if (want_head_stiffness)
576 {
577 set_head_stiffness_mask();
578 set_head_stiffness(unsigned(atoi(s)));
579 while (isdigit(*s)) s++;
580 }
581 else set_head_stiffness_mask(false);
582 if (*s == ',' && isdigit(*++s)) // check body stiffness?
583 {
584 set_body_stiffness_mask();
585 set_body_stiffness(unsigned(atoi(s)));
586 while (isdigit(*s)) s++;
587 }
588 else set_body_stiffness_mask(false);
589
590 if(*s != ',')
591 {
592 set_stance_action_mask(false);
593 return;
594 }
595 const char *ss = s;
596 ss++;
597 const char *p = strchr(ss, ',');
598 set_stance_action_mask(p != NULLPTR);
599 std::string str2(ss);
600 str2 = str2.substr(0, unsigned(p-ss+1));
601
602 stance s1;
603 MY_CHECK_ENUM(str2.c_str(), s1, Standby_stance);
604 else MY_CHECK_ENUM(str2.c_str(), s1, Kneeling_stance);
605 else MY_CHECK_ENUM(str2.c_str(), s1, Standing_stance);
606 else MY_CHECK_ENUM(str2.c_str(), s1, GoalieSaveLeft_stance);
607 else MY_CHECK_ENUM(str2.c_str(), s1, GoalieSaveRight_stance);
608 else MY_CHECK_ENUM(str2.c_str(), s1, FallenForward_stance);
609 else MY_CHECK_ENUM(str2.c_str(), s1, FallenBack_stance);
610 else s1 = NUM_OF_STANCES;
611
612 while (*(++s) != ',') ;
613
614 action a2;
617 else MY_CHECK_ENUM(s, a2, Kneeling_flagwave);
618 else MY_CHECK_ENUM(s, a2, Standing_leftkick);
620 else MY_CHECK_ENUM(s, a2, Standing_leftpass);
622 else MY_CHECK_ENUM(s, a2, Standing_wave);
623 else a2 = NUM_OF_ACTIONS;
624
625 if(a2 != NUM_OF_ACTIONS)
626 {
627 DoAction(s1, a2);
628 return;
629 }
630
631 stance s2;
633 else MY_CHECK_ENUM(s, s2, Kneeling_stance);
634 else MY_CHECK_ENUM(s, s2, Standing_stance);
638 else MY_CHECK_ENUM(s, s2, FallenBack_stance);
639 else s2 = NUM_OF_STANCES;
640
641 GoToStance(s1, s2);
642 }
643
644#pragma clang diagnostic ignored "-Wcovered-switch-default"
645#pragma clang diagnostic ignored "-Wunreachable-code"
646
651 std::string description() const
652 {
653 std::stringstream ss;
654 ss << head_stiffness() << "," << body_stiffness();
655 return ss.str();
656 }
657#endif // WHITEBOARD_POSTER_STRING_CONVERSION
658 };
659}
660
661#pragma clang diagnostic pop
662
663#endif //MOTION_Commands_DEFINED
#define MY_CHECK_ENUM(s, p, v)
#define MAP_ACTION_ENTRY(a, s, c)
#define TRANSITION_NAME(s, e)
#define ACTION_NAME(a, s)
#define JOINT_CHAIN_MAXSIZE
Motion Command class, this class is used to send commands to a motion module via the Whiteboard.
void from_string(const std::string &str)
Parser for recreating this class.
MOTION_Commands(const std::string &str)
String constructor.
long GoToStance(Motions::stance current, Motions::stance desired)
Transition from one 'Stance' to another.
long DoAction(Motions::stance current, Motions::action a)
Perform an 'Action'.
std::string description() const
Description method for pretty printing the values in this class.
Motion Status class, this class reports the status of the Motion engine via the Whiteboard.
Internal class for cost based graph search paths, in this case motion paths.
void add_stance(stance s, int cost)
Add the first stance to this path.
bool valid()
is this a valid motion transition
bool contains(stance s)
Check if the current stance path includes the passed in stance.
void invalidate()
set this path in invalid
void pretty_print()
pretty print of the stance path (mainly for debugging)
int cost()
getter for the path cost (aka time)
u_int8_t _stances[10]
the path taken
void reached()
did this path get to the desired stance
void add_stance(stance s, int cost, int transition)
Add the first stance to this path.
#define u_int8_t
motion_file_layout
This is the file format of the .mot files.
@ NAO_Version
V3 = 0, V4 = 1.
@ Units
RAD = 0 or DEG = 1.
@ Motions
The rest of the file is comma seperated joints and 10ms seperated lines.
@ Joints
Joint numbers, see SensorInfo.h 'jointNames' array.
action
enum values for all actions that can be done
@ Kneeling_signal
When kneeling, signal right arm - Vlad's where to hit.
@ Standing_leftkick
When standing, kick with the left foot.
@ Standing_wave
When standing, wave with one arm.
@ Standing_leftpass
When standing, kick sideways, moving the object in front of the robot left.
@ Standing_rightpass
When standing, kick sideways, moving the object in front of the robot right.
@ Kneeling_raiseright
When kneeling, raise right arm - Vlad's treat to hit.
@ Kneeling_wave
When kneeling, wave with one arm.
@ Kneeling_quickwave
When kneeling, wave quickly with one arm (originally for the RoboCup sound demo)
@ Standing_rightkick
When standing, kick with the right foot.
@ Kneeling_flagwave
When kneeling, wave as if holding a flag - Jeremy's Flag Wave.
@ NUM_OF_ACTIONS
Handy counter for the number of enums.
stance
enum values for all stances
@ Standing_stance
standing up, this is mirrored by the Nao walk engines 'Initialise' pose and means that a motion trans...
@ NUM_OF_STANCES
Handy counter for the number of enums.
@ FallenBack_stance
The robot has fallen backwards. There is no path to the fallen stances, these can only be gotten to b...
@ Standby_stance
Gorilla position, releases stiffness when done (implemented in the Nao motion module)
@ GoalieSaveLeft_stance
Half kneeling and leaning to the left.
@ Kneeling_stance
default kneeling stance - no stiffness by default (implemented in the Nao motion module)
@ GoalieSaveRight_stance
Half kneeling and leaning to the right.
@ FallenForward_stance
The robot has fallen face down. There is no path to the fallen stances, these can only be gotten to b...
/file APM_Interface.h
Simple struct to store the hardcoded motion 'Actions'.
static const std::map< action, Action_Transition > _actions
This stores all the actions that this API can use and what stance is required to use them.
static std::map< action, Action_Transition > create_actions()
These are the hardcoded Actions that can be used and the Stances required to use them.
Internal struct for representing a motion 'Action' such as Kicking.
Action_Transition(action a=Kneeling_wave, stance s=Kneeling_stance, int cost=1)
Constructor.
action _a
the action to be performed, somehow this is 'not really needed here', I can't remember why.
stance _s
the stance required to perform the action
std::string _name
the string name of the action
Internal struct for representing a transition from one from one 'Stance' to another.
Stance_Transition(stance s, stance e, int cost)
Constructor.
std::string _name
the string name of this transition
stance _s
the starting stance of this transition
stance _e
the ending stance of this transition
Simple struct to store the hardcoded motion transitions from one 'Stance' to another.
static std::vector< Stance_Transition > create_transitions()
These are the hardcoded transitions from one Stance to another.
static const std::vector< Stance_Transition > _transitions
the storage used for the hardcoded Stance transitions
@ NUM_OF_STANCES
Definition: wb_nao_state.h:27