ROBOOP, A Robotics Object Oriented Package in C++
dynamics_sim.cpp
Go to the documentation of this file.
1 /*
2 Copyright (C) 2002-2004 Etienne Lachance
3 
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
8 
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13 
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 Report problems and direct all questions to:
20 
21 email: etienne.lachance@polymtl.ca or richard.gourdeau@polymtl.ca
22 
23 -------------------------------------------------------------------------------
24 Revision_history:
25 
26 2005/06/10: Etienne Lachance
27  -The desired joint acceleration was missing in the computed torque method.
28 
29 2006/05/19: Richard Gourdeau
30  -Fix set_q, setq_p bug in xdot (reported by Philip Gruebele)
31 -------------------------------------------------------------------------------
32 */
33 
39 #include "dynamics_sim.h"
40 #include "robot.h"
41 
42 #ifdef use_namespace
43 namespace ROBOOP {
44  using namespace NEWMAT;
45 #endif
46 
48 
49 
54 Dynamics::Dynamics(Robot_basic *robot_): robot(robot_)
55 {
56  ndof = 1;
57  dof_fix = 1;
58  if(robot)
59  {
60  ndof = robot->get_dof();
61  dof_fix = ndof + robot->get_fix();
62  }
63 
64  q = ColumnVector(ndof);
65  q = 0;
66  qp = ColumnVector(ndof);
67  qp = 0;
68  qpp = ColumnVector(ndof);
69  qpp = 0;
70  qd = ColumnVector(ndof);
71  qd = 0.0;
72  qpd = ColumnVector(ndof);
73  qpd = 0;
74  qppd = ColumnVector(ndof);
75  qppd = 0;
76  tau = ColumnVector(ndof);
77  tau = 0.0;
78  pd = ColumnVector(3); pd = 0;
79  ppd = ColumnVector(3);
80  ppd = 0;
81  pppd = ColumnVector(3);
82  pppd = 0;
83  wd = ColumnVector(3);
84  wd = 0;
85  wpd = ColumnVector(3);
86  wpd = 0;
87  nsteps = 50;
88  to = 0;
89  tf = 0.1;
90  dt = ((tf-to)/nsteps)/4.0;
91  tf_cont = 1;
92 
93  first_pass_Kutta = true;
94  instance = this;
95 }
96 
102 {
103  return instance;
104 }
105 
113 {
114  ndof = 1;
115  dof_fix = 1;
116  robot = robot_;
117  if(robot)
118  {
119  ndof = robot->get_dof();
120  dof_fix = ndof + robot->get_fix();
121  }
122  q = ColumnVector(ndof);
123  q = 0;
124  qp = ColumnVector(ndof);
125  qp = 0;
126  qpp = ColumnVector(ndof);
127  qpp = 0;
128  qd = ColumnVector(ndof);
129  qd = 0.0;
130  qpd = ColumnVector(ndof);
131  qpd = 0;
132  qppd = ColumnVector(ndof);
133  qppd = 0;
134  tau = ColumnVector(ndof);
135  tau = 0.0;
136 
137  first_pass_Kutta = true;
138 }
139 
140 void Dynamics::set_time_frame(const int nsteps_)
142 {
143  nsteps = nsteps_;
144 }
145 
146 void Dynamics::set_final_time(const double tf)
148 {
149  tf_cont = tf;
150 }
151 
154 {
155  first_pass_Kutta = true;
156 }
157 
160 {
161  control = control_;
162  if( (ndof != control.get_dof()) && (control.type != NONE) )
163  {
164  control.type = NONE;
165  cerr << "Dynamics::set_controller: mismatch degree of freedom between robot and controller." << endl;
166  return -1;
167  }
168  return 0;
169 }
170 
171 short Dynamics::set_trajectory(const Trajectory_Select & path_select_)
173 {
174  path_select = path_select_;
175 
177  {
178  control.type = NONE;
179  path_select.type = NONE;
180  cerr << "Dynamics::set_trajectory: controller space and trajectory space are not compatible.\n"
181  << " Both should be in joint space or in cartesian space." << endl;
182  return -1;
183  }
184  return 0;
185 }
186 
198 {
199  ColumnVector qs(2*ndof);
200 
201  if(path_select.type == JOINT_SPACE)
202  {
203  if(path_select.path.p_pdot(0.0, qd, qpd))
204  cerr << "Dynamics::set_robot_on_first_point_of_spines: invalid joint space path." << endl;
205  else
206  {
207  tf_cont = path_select.path.get_final_time();
208  robot->set_q(qd);
209  qs.SubMatrix(1,ndof,1,1) = qd;
210  qs.SubMatrix(ndof+1,2*ndof,1,1) = 0;
211  qs.Release();
212  return qs;
213  }
214  }
215  else if(path_select.type == CARTESIAN_SPACE) // && quaternion active
216  {
217  if( (path_select.path.p_pdot_pddot(0.0, pd, ppd, pppd) == 0) &&
218  (path_select.path_quat.quat_w(0.0, quatd, wd) == 0) )
219  {
220  Matrix Tobj(4,4); Tobj = 0;
221  Tobj.SubMatrix(1,3,1,3) = quatd.R();
222  Tobj.SubMatrix(1,3,4,4) = pd;
223  Tobj(4,4) = 1;
224  bool converge;
225  robot->inv_kin(Tobj, 0, converge);
226 
227  if(converge)
228  {
229  tf_cont = path_select.path.get_final_time();
230  q = robot->get_q();
231  qs.SubMatrix(1,ndof,1,1) = q;
232  qs.SubMatrix(ndof+1,2*ndof,1,1) = 0;
233 
234  qs.Release();
235  return qs;
236  }
237  }
238  else
239  cerr << "Dynamics::set_robot_on_first_point_of_spines: invalid cartesian path." << endl;
240  }
241 
242  q = robot->get_q();
243  qs.SubMatrix(1,ndof,1,1) = q;
244  qs.SubMatrix(ndof+1,2*ndof,1,1) = 0;
245  qs.Release();
246  return qs;
247 }
248 
249 ReturnMatrix Dynamics::xdot(const Matrix & x)
257 {
258  q = x.SubMatrix(1,ndof,1,1); // joint position from state vecteur
259  qp = x.SubMatrix(ndof+1,2*ndof,1,1);// " " velocity " "
260  robot->set_q(q);
261  robot->set_qp(qp);
262 
263  if(robot)
264  {
265  switch (control.type)
266  {
267  case PD:
268  if(path_select.type == JOINT_SPACE)
269  {
271  {
272  xd = qp & qpp;
273  xd.Release();
274  return xd;
275  }
276  }
277  else if(path_select.type == CARTESIAN_SPACE)
278  cerr << "Dynamics::xdot: Cartesian path can not be used with CTM controller." << endl;
279 
280  tau = control.pd.torque_cmd(*robot, qd, qpd);
281 
282  break;
283 
284  case CTM:
285  if(path_select.type == JOINT_SPACE)
286  {
288  {
289  xd = qp & qpp;
290  xd.Release();
291  return xd;
292  }
293  }
294  else if(path_select.type == CARTESIAN_SPACE)
295  cerr << "Dynamics::xdot: Cartesian path can not be used with CTM controller." << endl;
296 
297  tau = control.ctm.torque_cmd(*robot, qd, qpd, qppd);
298 
299  break;
300 
301  case RRA:
302  if(path_select.type == CARTESIAN_SPACE)
303  {
306  {
307  xd = qp & qpp;
308  xd.Release();
309  return xd;
310  }
311  }
312  else if(path_select.type == JOINT_SPACE)
313  cerr << "Dynamics::xdot: Joint Space path can not be used with RRA controller." << endl;
314 
316  break;
317  default:
318  tau = 0;
319  }
320  qpp = robot->acceleration(q, qp, tau);
321  }
322 
323  plot();
324 
325  xd = qp & qpp; // state derivative
326 
327  xd.Release();
328  return xd;
329 }
330 
333 {
334  if(first_pass_Kutta)
335  {
336  h = (tf-to)/nsteps;
337  h2 = h/2.0;
338  time = to;
340  first_pass_Kutta = false;
341  return;
342  }
343 
344  k1 = xdot(x) * h;
345  time += h2;
346  k2 = xdot(x+k1*0.5)*h;
347  k3 = xdot(x+k2*0.5)*h;
348  time += h2;
349  k4 = xdot(x+k3)*h;
350  x = x + (k1*0.5+ k2 + k3 + k4*0.5)*(1.0/3.0);
351 }
352 
355 {
357  h = (tf_cont - to)/nsteps;
358  h2 = h/2.0;
359  time = to;
360 
361  for (int i = 1; i <= nsteps; i++) {
362  k1 = xdot(x) * h;
363  k2 = xdot(x+k1*0.5)*h;
364  k3 = xdot(x+k2*0.5)*h;
365  k4 = xdot(x+k3)*h;
366  x = x + (k1*0.5+ k2 + k3 + k4*0.5)*(1.0/3.0);
367  time += h;
368  }
369 }
370 
371 #ifdef use_namespace
372 }
373 #endif
374 
375 
376 
377 
378 
379 
380 
381 
382 
383 
384