RcsPySim
A robot control and simulation library
DynamicalSystem.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 _DYNAMICALSYSTEM_H_
32 #define _DYNAMICALSYSTEM_H_
33 
34 #include "../util/nocopy.h"
35 
36 #include <Eigen/Core>
37 
38 #include <vector>
39 
40 namespace Rcs
41 {
42 
43 // Forward declaration
44 class PropertySource;
45 
46 /*! Base class of all Dynamical Systems (DS)
47  */
49 {
50 public:
51  DynamicalSystem() = default;
52 
53  virtual ~DynamicalSystem() = default;
54 
55  // not copy- or movable RCSPYSIM_NOCOPY_NOMOVE(DynamicalSystem)
56 
57  /**
58  * Create a deep copy of this DynamicalSystem.
59  * @return deep copy
60  */
61  virtual DynamicalSystem* clone() const = 0;
62 
63  // config based factory
64  static DynamicalSystem* create(PropertySource* properties, unsigned int innerTaskDim);
65 
66  /*! Advance the dynamical system one step in time.
67  * Compute the velocity x_dot with the desired velocity in state x.
68  * For acceleration-based systems, x_dot is prefilled with the current velocity.
69  * @param[in,out] x_dot current velocity, override with new desired velocity
70  * @param[in] x current state
71  * @param[in] dt time step size for integration
72  */
73  virtual void step(Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const = 0;
74 
75  /*! Get the goal state for this dynamical system.
76  * @return x_des desired state for the system to pursue
77  */
78  virtual Eigen::VectorXd getGoal() const = 0;
79 
80  /*! Set the goal state for this dynamical system.
81  * The goal state is the system's desired equilibrium state. In the presence of repellers, this
82  * Systems without an explicit goal state do not need to override this. By default, it does othing.
83  * @param[in] x_des desired state for the system to pursue
84  */
85  virtual void setGoal(const Eigen::VectorXd& x_des) = 0;
86 
87  /*!
88  * Compute the L2 norm between the current state and the goal state.
89  * @param[in] x_curr current system state
90  * @return euclidean distance to goal
91  */
92  virtual double goalDistance(const Eigen::VectorXd& x_curr) const;
93 
94  unsigned int getStateDim() const;
95 
96  /*! The desired task space velocity of the DS, which is equal to x_dot coming from step().
97  * The robot will most likely not execute the commaded x_dot (e.g. due to the IK or other active DS).
98  * We store the desired task space velocity of the DS for potential using it in AMDynamicalSystemActivation or debugging.
99  * */
100  Eigen::VectorXd x_dot_des;
101 };
102 
103 
104 /*! A second-order dynamical system generates desired acceleration values.
105  * The acceleration is integrated to output desired velocities.
106  */
108 {
109 public:
110  virtual void step(Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
111 
112  /*! Advance the dynamical system one step in time.
113  * Compute the acceleration x_ddot given the velocity x_dot and the state x, and the time step size dt.
114  * @param[out] x_ddot fill with desired acceleration, is not initialized
115  * @param[in] x_dot current velocity
116  * @param[in] x current state
117  * @param[in] dt time step size for integration
118  */
119  virtual void
120  step(Eigen::VectorXd& x_ddot, const Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const = 0;
121 };
122 
123 
124 /*!
125  * Constant Dynamical System
126  * When DSConst is used on a velocity Task, a second order system behavior arises.
127  */
128 class DSConst : public DynamicalSystem
129 {
130 public:
131  /**
132  * !Constructor
133  * @param[in] constVelocity desired constant velocity of the dynamical system \f$ \dot{x} = c \f$
134  */
135  DSConst(const Eigen::VectorXd& constVelocity);
136 
137  virtual DynamicalSystem* clone() const;
138 
139  void step(Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
140 
141  Eigen::VectorXd getGoal() const;
142 
143  void setGoal(const Eigen::VectorXd& x_des);
144 
145 protected:
146  Eigen::VectorXd constVelocity;
147 };
148 
149 
150 /*!
151  * Linear Dynamical System
152  */
153 class DSLinear : public DynamicalSystem
154 {
155 public:
156  /**
157  * !Constructor
158  * @param[in] errorDynamics dynamics matrix
159  * @param[in] equilibriumPoint attractor
160  */
161  DSLinear(const Eigen::MatrixXd& errorDynamics, const Eigen::VectorXd& equilibriumPoint);
162 
163  virtual DynamicalSystem* clone() const;
164 
165  void step(Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
166 
167  Eigen::VectorXd getGoal() const;
168 
169  void setGoal(const Eigen::VectorXd& x_des);
170 
171 protected:
172  Eigen::MatrixXd errorDynamics;
173  Eigen::VectorXd equilibriumPoint;
174 };
175 
176 
177 /*!
178  * Mass-Spring-Damper Dynamical System
179  */
181 {
182 public:
183  //! Properties for one spring component.
184  struct Spring
185  {
186  //! Zero position of the spring, force is applied to reach this state.
187  Eigen::VectorXd equilibriumPoint;
188  //! Stiffness of the spring
189  double stiffness;
190 
191  Spring(Eigen::VectorXd equilibriumPoint, double stiffness) :
192  equilibriumPoint(equilibriumPoint), stiffness(stiffness) {}
193  };
194 
195  /*! Constructor
196  * @param[in] attractor attractor spring pulling the mass to the goal poisiton (there is only one)
197  * @param[in] repellers repeller springs pushing the mass away from points in space
198  * @param[in] damping of the dynamical system (there is only on)
199  * @param[in] mass mass of the particle (default: unit mass 1kg)
200  */
202  const Spring& attractor, const std::vector<Spring>& repellers, const double damping,
203  const double mass = 1.0);
204 
205  virtual DynamicalSystem* clone() const;
206 
207  void step(Eigen::VectorXd& x_ddot, const Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
208 
209  Eigen::VectorXd getGoal() const;
210 
211  void setGoal(const Eigen::VectorXd& x_des); // set goal spring
212 
213 protected:
214  //! attractor spring pulling the mass to the goal poisiton (there is only one for every dynamical system)
216  //! repeller springs pushing the mass away from points in space (e.g. obstacles)
217  std::vector<Spring> repellerSprings;
218  //! daming of the dynamical system (there is only one for every dynamical system)
219  double damping;
220  //! mass of the particle
221  double mass;
222 };
223 
224 
225 /*!
226  * Clampled Nonlinear Mass-Spring-Damper Dynamical System
227  */
229 {
230 public:
231  /*! Constructor
232  * @param[in] attractor attractor spring pulling the mass to the goal poisiton (there is only one)
233  * @param[in] repellers repeller springs pushing the mass away from points in space
234  * @param[in] damping of the dynamical system (there is only on)
235  * @param[in] mass mass of the particle (default: unit mass 1kg)
236  */
238  const Spring& attractor, const std::vector<Spring>& repellers, const double damping,
239  const double mass = 1.0);
240 
241  virtual DynamicalSystem* clone() const;
242 
243  void step(Eigen::VectorXd& x_ddot, const Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
244 };
245 
246 
247 /*!
248  * A dynamical system that only affects a slice of the state x.
249  */
250 class DSSlice : public DynamicalSystem
251 {
252 private:
254  unsigned int offset;
255  unsigned int length;
256  Eigen::VectorXd goal;
257 public:
258  //! constructor
259  DSSlice(DynamicalSystem* wrapped, unsigned int offset, unsigned int length);
260 
261  ~DSSlice();
262 
263  // not copy- or movable - klocwork doesn't pick up the inherited ones. RCSPYSIM_NOCOPY_NOMOVE(DSSlice)
264 
265  virtual DynamicalSystem* clone() const;
266 
267  virtual void step(Eigen::VectorXd& x_dot, const Eigen::VectorXd& x, double dt) const;
268 
269  virtual void setGoal(const Eigen::VectorXd& x_des);
270 
271  virtual Eigen::VectorXd getGoal() const;
272 
273  virtual double goalDistance(const Eigen::VectorXd& x_cur) const;
274 
275  DynamicalSystem* getWrapped() const;
276 };
277 
278 } /* namespace Rcs */
279 
280 #endif /* _DYNAMICALSYSTEM_H_ */
unsigned int getStateDim() const
unsigned int length
Eigen::VectorXd goal
virtual DynamicalSystem * clone() const =0
std::vector< Spring > repellerSprings
repeller springs pushing the mass away from points in space (e.g. obstacles)
virtual void step(Eigen::VectorXd &x_dot, const Eigen::VectorXd &x, double dt) const =0
Eigen::VectorXd equilibriumPoint
Zero position of the spring, force is applied to reach this state.
Eigen::VectorXd x_dot_des
virtual ~DynamicalSystem()=default
Eigen::MatrixXd errorDynamics
Eigen::VectorXd constVelocity
static DynamicalSystem * create(PropertySource *properties, unsigned int innerTaskDim)
DynamicalSystem()=default
virtual void setGoal(const Eigen::VectorXd &x_des)=0
Spring attractorSpring
attractor spring pulling the mass to the goal poisiton (there is only one for every dynamical system)...
virtual Eigen::VectorXd getGoal() const =0
Spring(Eigen::VectorXd equilibriumPoint, double stiffness)
double stiffness
Stiffness of the spring.
DynamicalSystem * wrapped
Eigen::VectorXd equilibriumPoint
virtual double goalDistance(const Eigen::VectorXd &x_curr) const
unsigned int offset
double damping
daming of the dynamical system (there is only one for every dynamical system)
double mass
mass of the particle
Properties for one spring component.