RcsPySim
A robot control and simulation library
ActionModel.h
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (c) 2020, Fabio Muratore, Honda Research Institute Europe GmbH, and
3  Technical University of Darmstadt.
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are met:
8  1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  3. Neither the name of Fabio Muratore, Honda Research Institute Europe GmbH,
14  or Technical University of Darmstadt, nor the names of its contributors may
15  be used to endorse or promote products derived from this software without
16  specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL FABIO MURATORE, HONDA RESEARCH INSTITUTE EUROPE GMBH,
22  OR TECHNICAL UNIVERSITY OF DARMSTADT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30 
31 #ifndef _ACTIONMODEL_H_
32 #define _ACTIONMODEL_H_
33 
34 #include "../util/BoxSpaceProvider.h"
35 
36 #include <Rcs_MatNd.h>
37 #include <Rcs_graph.h>
38 #include <Rcs_typedef.h>
39 
40 namespace Rcs
41 {
42 
43 /*! Combination method for tasks a.k.a. movement primitives
44  * Determines how the contribution of each task is scaled with its activation.
45  */
47 {
49 };
50 
51 
52 /**
53  * The ActionModel component encapsulates the translation from the generic action passed from Python to actual joint
54  * space commands required by the physics simulation or the robot.
55  * Inherits from BoxSpaceProvider to provide a space for valid action values.
56  */
58 {
59 public:
60  /**
61  * Constructor
62  * @param graph graph being commanded
63  */
64  explicit ActionModel(RcsGraph* graph);
65 
66  virtual ~ActionModel();
67 
68  /**
69  * Create a deep copy of this action model.
70  * @return deep copy.
71  */
72  inline ActionModel* clone() const { return clone(graph); }
73 
74  /**
75  * Create a deep copy of this action model. The graph the action model operates on is replaced with newGraph.
76  * @param newGraph optionally, replace the graph used with newGraph.
77  * @return deep copy with new graph.
78  */
79  virtual ActionModel* clone(RcsGraph* newGraph) const = 0;
80 
81  /**
82  * Compute the joint commands from a specified action and the current state.
83  * @param[out] q_des desired joint positions
84  * @param[out] q_dot_des desired joint velocities
85  * @param[out] T_des desired joint torques
86  * @param[in] action input action values
87  * @param dt difference in time since the last call.
88  */
89  virtual void computeCommand(MatNd* q_des, MatNd* q_dot_des, MatNd* T_des, const MatNd* action, double dt) = 0;
90 
91  /**
92  * Called at the start of a rollout to reset any state modified by computeCommand().
93  * This allows to reuse the ActionModel for a new simulation rollout. The graph state will already be reset,
94  * so it can be used safely.
95  * It will be called before the first rollout too, so it can also be used to setup internals that depend on
96  * operations in subclass constructors.
97  */
98  virtual void reset();
99 
100  /**
101  * Obtain action values which would keep the system in the current state.
102  * For action variables which are velocities or accelerations, this should be 0.
103  * For action variables which are positions, this should be the current position.
104  * @param[out] action matrix to write the values into
105  */
106  virtual void getStableAction(MatNd* action) const = 0;
107 
108  /**
109  * Get the graph this action model operates on.
110  */
111  RcsGraph* getGraph() { return graph; }
112 
113  void setGraph(RcsGraph* newGraph) { graph = newGraph; }
114 
115  /*!
116  * If this ActionModel is a wrapper for another action model, return the wrapped action model.
117  * Otherwise, return NULL.
118  * @return wrapped action model or NULL if none.
119  */
120  virtual ActionModel* getWrappedActionModel() const;
121 
122  /*!
123  * Descend the wrapper chain to it's end.
124  * Returns this action model if unwrap() returns NULL.
125  * @return innermost action model
126  */
127  const ActionModel* unwrapAll() const;
128 
129  /*!
130  * Descend the wrapper chain to it's end.
131  * Returns this action model if unwrap() returns NULL.
132  * @return innermost action model
133  */
134  ActionModel* unwrapAll();
135 
136  /*!
137  * Find action model of a specific type in the wrapper chain.
138  * @tparam AM type of action model to locate
139  * @return typed action model or if not found.
140  */
141  template<typename AM>
142  const AM* unwrap() const
143  {
144  const ActionModel* curr = this;
145  // Loop through the chain
146  while (true) {
147  // Try to cast current action model
148  auto cast = dynamic_cast<AM*>(curr);
149  if (cast) {
150  return cast;
151  }
152 
153  // Obtain next wrapped action model
154  const ActionModel* wrapped = curr->getWrappedActionModel();
155  if (wrapped == NULL) {
156  // end of chain
157  return NULL;
158  }
159  // Descend
160  curr = wrapped;
161  }
162  }
163 
164  /*!
165  * Find action model of a specific type in the wrapper chain.
166  * @tparam AM type of action model to locate
167  * @return typed action model or if not found.
168  */
169  template<typename AM>
170  AM* unwrap()
171  {
172  ActionModel* curr = this;
173  // Loop through the chain
174  while (true) {
175  // Try to cast current action model
176  auto cast = dynamic_cast<AM*>(curr);
177  if (cast) {
178  return cast;
179  }
180 
181  // Obtain next wrapped action model
182  ActionModel* wrapped = curr->getWrappedActionModel();
183  if (wrapped == NULL) {
184  // End of chain
185  return NULL;
186  }
187  // Descend
188  curr = wrapped;
189  }
190  }
191 
192 protected:
193  // Graph this action model operates on
194  RcsGraph* graph;
195 };
196 
197 } /* namespace Rcs */
198 
199 #endif /* _ACTIONMODEL_H_ */
RcsGraph * getGraph()
Definition: ActionModel.h:111
virtual ActionModel * getWrappedActionModel() const
Definition: ActionModel.cpp:54
TaskCombinationMethod
Definition: ActionModel.h:46
void setGraph(RcsGraph *newGraph)
Definition: ActionModel.h:113
const AM * unwrap() const
Definition: ActionModel.h:142
ActionModel * clone() const
Definition: ActionModel.h:72
RcsGraph * graph
Definition: ActionModel.h:194