Blender V4.3
Scene.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Ruben Smits
2 *
3 * SPDX-License-Identifier: LGPL-2.1-or-later */
4
9#include "Scene.hpp"
10#include "ControlledObject.hpp"
12#include <cstdio>
13
14namespace iTaSC {
15
17 private:
18 Scene *m_scene;
19 Range m_qrange;
20
21 public:
22 SceneLock(Scene *scene) : m_scene(scene), m_qrange(0, 0)
23 {
24 }
25 virtual ~SceneLock()
26 {
27 }
28
29 void setRange(Range &range)
30 {
31 m_qrange = range;
32 }
33 // lock a joint, no need to update output
34 virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
35 {
36 q_nr += m_qrange.start;
37 project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
38 }
39 // lock a joint and update output in view of reiteration
40 virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double *qdot)
41 {
42 q_nr += m_qrange.start;
43 project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
44 // update the output vector so that the movement of this joint will be
45 // taken into account and we can put the joint back in its initial position
46 // which means that the jacobian doesn't need to be changed
47 for (unsigned int i = 0; i < ndof; ++i, ++q_nr) {
48 m_scene->m_ydot -= m_scene->m_A.col(q_nr) * qdot[i];
49 }
50 }
51};
52
54 : m_A(),
55 m_B(),
56 m_Atemp(),
57 m_Wq(),
58 m_Jf(),
59 m_Jq(),
60 m_Ju(),
61 m_Cf(),
62 m_Cq(),
63 m_Jf_inv(),
64 m_Vf(),
65 m_Uf(),
66 m_Wy(),
67 m_ydot(),
68 m_qdot(),
69 m_xdot(),
70 m_Sf(),
71 m_tempf(),
72 m_ncTotal(0),
73 m_nqTotal(0),
74 m_nuTotal(0),
75 m_nsets(0),
76 m_solver(NULL),
77 m_cache(NULL)
78{
79 m_minstep = 0.01;
80 m_maxstep = 0.06;
81}
82
84{
85 ConstraintMap::iterator constraint_it;
86 while ((constraint_it = constraints.begin()) != constraints.end()) {
87 delete constraint_it->second;
88 constraints.erase(constraint_it);
89 }
90 ObjectMap::iterator object_it;
91 while ((object_it = objects.begin()) != objects.end()) {
92 delete object_it->second;
93 objects.erase(object_it);
94 }
95}
96
97bool Scene::setParam(SceneParam paramId, double value)
98{
99 switch (paramId) {
100 case MIN_TIMESTEP:
101 m_minstep = value;
102 break;
103 case MAX_TIMESTEP:
104 m_maxstep = value;
105 break;
106 default:
107 return false;
108 }
109 return true;
110}
111
112bool Scene::addObject(const std::string &name,
113 Object *object,
114 UncontrolledObject *base,
115 const std::string &baseFrame)
116{
117 // finalize the object before adding
118 if (!object->finalize())
119 return false;
120 // Check if Object is controlled or uncontrolled.
121 if (object->getType() == Object::Controlled) {
122 int baseFrameIndex = base->addEndEffector(baseFrame);
123 if (baseFrameIndex < 0)
124 return false;
125 std::pair<ObjectMap::iterator, bool> result;
126 if (base->getNrOfCoordinates() == 0) {
127 // base is fixed object, no coordinate range
128 result = objects.insert(ObjectMap::value_type(
129 name,
130 new Object_struct(object,
131 base,
132 baseFrameIndex,
133 Range(m_nqTotal, object->getNrOfCoordinates()),
134 Range(m_ncTotal, ((ControlledObject *)object)->getNrOfConstraints()),
135 Range(0, 0))));
136 }
137 else {
138 // base is a moving object, must be in list already
139 ObjectMap::iterator base_it;
140 for (base_it = objects.begin(); base_it != objects.end(); base_it++) {
141 if (base_it->second->object == base)
142 break;
143 }
144 if (base_it == objects.end())
145 return false;
146 result = objects.insert(ObjectMap::value_type(
147 name,
148 new Object_struct(object,
149 base,
150 baseFrameIndex,
151 Range(m_nqTotal, object->getNrOfCoordinates()),
152 Range(m_ncTotal, ((ControlledObject *)object)->getNrOfConstraints()),
153 base_it->second->coordinaterange)));
154 }
155 if (!result.second) {
156 return false;
157 }
158 m_nqTotal += object->getNrOfCoordinates();
159 m_ncTotal += ((ControlledObject *)object)->getNrOfConstraints();
160 return true;
161 }
162 if (object->getType() == Object::UnControlled) {
163 if ((WorldObject *)base != &Object::world)
164 return false;
165 std::pair<ObjectMap::iterator, bool> result = objects.insert(
166 ObjectMap::value_type(name,
167 new Object_struct(object,
168 base,
169 0,
170 Range(0, 0),
171 Range(0, 0),
172 Range(m_nuTotal, object->getNrOfCoordinates()))));
173 if (!result.second)
174 return false;
175 m_nuTotal += object->getNrOfCoordinates();
176 return true;
177 }
178 return false;
179}
180
181bool Scene::addConstraintSet(const std::string &name,
182 ConstraintSet *task,
183 const std::string &object1,
184 const std::string &object2,
185 const std::string &ee1,
186 const std::string &ee2)
187{
188 // Check if objects exist:
189 ObjectMap::iterator object1_it = objects.find(object1);
190 ObjectMap::iterator object2_it = objects.find(object2);
191 if (object1_it == objects.end() || object2_it == objects.end())
192 return false;
193 int ee1_index = object1_it->second->object->addEndEffector(ee1);
194 int ee2_index = object2_it->second->object->addEndEffector(ee2);
195 if (ee1_index < 0 || ee2_index < 0)
196 return false;
197 std::pair<ConstraintMap::iterator, bool> result = constraints.insert(ConstraintMap::value_type(
198 name,
199 new ConstraintSet_struct(task,
200 object1_it,
201 ee1_index,
202 object2_it,
203 ee2_index,
204 Range(m_ncTotal, task->getNrOfConstraints()),
205 Range(6 * m_nsets, 6))));
206 if (!result.second)
207 return false;
208 m_ncTotal += task->getNrOfConstraints();
209 m_nsets += 1;
210 return true;
211}
212
213bool Scene::addSolver(Solver *_solver)
214{
215 if (m_solver == NULL) {
216 m_solver = _solver;
217 return true;
218 }
219 else
220 return false;
221}
222
223bool Scene::addCache(Cache *_cache)
224{
225 if (m_cache == NULL) {
226 m_cache = _cache;
227 return true;
228 }
229 else
230 return false;
231}
232
233bool Scene::initialize()
234{
235
236 // prepare all matrices:
237 if (m_ncTotal == 0 || m_nqTotal == 0 || m_nsets == 0)
238 return false;
239
240 m_A = e_zero_matrix(m_ncTotal, m_nqTotal);
241 if (m_nuTotal > 0) {
242 m_B = e_zero_matrix(m_ncTotal, m_nuTotal);
243 m_xdot = e_zero_vector(m_nuTotal);
244 m_Ju = e_zero_matrix(6 * m_nsets, m_nuTotal);
245 }
246 m_Atemp = e_zero_matrix(m_ncTotal, 6 * m_nsets);
247 m_ydot = e_zero_vector(m_ncTotal);
248 m_qdot = e_zero_vector(m_nqTotal);
249 m_Wq = e_zero_matrix(m_nqTotal, m_nqTotal);
250 m_Wy = e_zero_vector(m_ncTotal);
251 m_Jq = e_zero_matrix(6 * m_nsets, m_nqTotal);
252 m_Jf = e_zero_matrix(6 * m_nsets, 6 * m_nsets);
253 m_Jf_inv = m_Jf;
254 m_Cf = e_zero_matrix(m_ncTotal, m_Jf.rows());
255 m_Cq = e_zero_matrix(m_ncTotal, m_nqTotal);
256
257 bool result = true;
258 // finalize all objects
259 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
260 Object_struct *os = it->second;
261
262 os->object->initCache(m_cache);
263 if (os->constraintrange.count > 0)
264 project(m_Cq,
265 os->constraintrange,
266 os->jointrange) = (((ControlledObject *)(os->object))->getCq());
267 }
268
269 m_ytask.resize(m_ncTotal);
270 bool toggle = true;
271 int count = 0;
272 // Initialize all ConstraintSets:
273 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
274 // Calculate the external pose:
275 ConstraintSet_struct *cs = it->second;
276 Frame external_pose;
277 getConstraintPose(cs->task, cs, external_pose);
278 result &= cs->task->initialise(external_pose);
279 cs->task->initCache(m_cache);
280 for (int i = 0; i < cs->constraintrange.count; i++, count++) {
281 m_ytask[count] = toggle;
282 }
283 toggle = !toggle;
284 project(m_Cf, cs->constraintrange, cs->featurerange) = cs->task->getCf();
285 }
286
287 if (m_solver != NULL)
288 m_solver->init(m_nqTotal, m_ncTotal, m_ytask);
289 else
290 return false;
291
292 return result;
293}
294
295bool Scene::getConstraintPose(ConstraintSet *constraint, void *_param, KDL::Frame &_pose)
296{
297 // function called from constraint when they need to get the external pose
298 ConstraintSet_struct *cs = (ConstraintSet_struct *)_param;
299 // verification, the pointer MUST match
300 assert(constraint == cs->task);
301 Object_struct *ob1 = cs->object1->second;
302 Object_struct *ob2 = cs->object2->second;
303 // Calculate the external pose:
304 _pose =
305 (ob1->base->getPose(ob1->baseFrameIndex) * ob1->object->getPose(cs->ee1index)).Inverse() *
306 (ob2->base->getPose(ob2->baseFrameIndex) * ob2->object->getPose(cs->ee2index));
307 return true;
308}
309
310bool Scene::update(double timestamp,
311 double timestep,
312 unsigned int numsubstep,
313 bool reiterate,
314 bool cache,
315 bool interpolate)
316{
317 // we must have valid timestep and timestamp
318 if (timestamp < KDL::epsilon || timestep < 0.0)
319 return false;
320 Timestamp ts;
321 ts.realTimestamp = timestamp;
322 // initially we start with the full timestep to allow velocity estimation over the full interval
323 ts.realTimestep = timestep;
325 ts.substep = 0;
326 // for reiteration don't load cache
327 // reiteration=additional iteration with same timestamp if application finds the convergence not
328 // good enough
329 ts.reiterate = (reiterate) ? 1 : 0;
330 ts.interpolate = (interpolate) ? 1 : 0;
331 ts.cache = (cache) ? 1 : 0;
332 ts.update = 1;
333 ts.numstep = (numsubstep & 0xFF);
334 bool autosubstep = (numsubstep == 0) ? true : false;
335 if (numsubstep < 1)
336 numsubstep = 1;
337 double timesubstep = timestep / numsubstep;
338 double timeleft = timestep;
339
340 if (timeleft == 0.0) {
341 // this special case correspond to a request to cache data
342 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
343 it->second->object->pushCache(ts);
344 }
345 // Update the Constraints
346 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
347 it->second->task->pushCache(ts);
348 }
349 return true;
350 }
351
352 // double maxqdot; // UNUSED
353 e_scalar nlcoef;
354 SceneLock lockCallback(this);
355 Frame external_pose;
356 bool locked;
357
358 // initially we keep timestep unchanged so that update function compute the velocity over
359 while (numsubstep > 0) {
360 // get objects
361 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
362 Object_struct *os = it->second;
363 if (os->object->getType() == Object::Controlled) {
364 ((ControlledObject *)(os->object))->updateControlOutput(ts);
365 if (os->constraintrange.count > 0) {
366 project(m_ydot,
367 os->constraintrange) = ((ControlledObject *)(os->object))->getControlOutput();
368 project(m_Wy, os->constraintrange) = ((ControlledObject *)(os->object))->getWy();
369 // project(m_Cq,os->constraintrange,os->jointrange) =
370 // (((ControlledObject*)(os->object))->getCq());
371 }
372 if (os->jointrange.count > 0) {
373 project(
374 m_Wq, os->jointrange, os->jointrange) = ((ControlledObject *)(os->object))->getWq();
375 }
376 }
377 if (os->object->getType() == Object::UnControlled &&
378 ((UncontrolledObject *)os->object)->getNrOfCoordinates() != 0) {
379 ((UncontrolledObject *)(os->object))->updateCoordinates(ts);
380 if (!ts.substep) {
381 // velocity of uncontrolled object remains constant during substepping
382 project(m_xdot, os->coordinaterange) = ((UncontrolledObject *)(os->object))->getXudot();
383 }
384 }
385 }
386
387 // get new Constraints values
388 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
389 ConstraintSet_struct *cs = it->second;
390 Object_struct *ob1 = cs->object1->second;
391 Object_struct *ob2 = cs->object2->second;
392
393 if (ob1->base->updated() || ob1->object->updated() || ob2->base->updated() ||
394 ob2->object->updated()) {
395 // the object from which the constraint depends have changed position
396 // recompute the constraint pose
397 getConstraintPose(cs->task, cs, external_pose);
398 cs->task->initialise(external_pose);
399 }
400 cs->task->updateControlOutput(ts);
401 project(m_ydot, cs->constraintrange) = cs->task->getControlOutput();
402 if (!ts.substep || cs->task->substep()) {
403 project(m_Wy, cs->constraintrange) = (cs->task)->getWy();
404 // project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
405 }
406
407 project(m_Jf, cs->featurerange, cs->featurerange) = cs->task->getJf();
408 // std::cout << "Jf = " << Jf << std::endl;
409 // Transform the reference frame of this jacobian to the world reference frame
410 Eigen::Block<e_matrix> Jf_part = project(m_Jf, cs->featurerange, cs->featurerange);
411 changeBase(Jf_part,
412 ob1->base->getPose(ob1->baseFrameIndex) * ob1->object->getPose(cs->ee1index));
413 // std::cout << "Jf_w = " << Jf << std::endl;
414
415 // calculate the inverse of Jf
417 project(m_Jf, cs->featurerange, cs->featurerange), m_Uf, m_Sf, m_Vf, m_tempf);
418 for (unsigned int i = 0; i < 6; ++i)
419 if (m_Sf(i) < KDL::epsilon)
420 m_Uf.col(i).setConstant(0.0);
421 else
422 m_Uf.col(i) *= (1 / m_Sf(i));
423 project(m_Jf_inv, cs->featurerange, cs->featurerange).noalias() = m_Vf * m_Uf.transpose();
424
425 // Get the robotjacobian associated with this constraintset
426 // Each jacobian is expressed in robot base frame => convert to world reference
427 // and negate second robot because it is taken reversed when closing the loop:
428 if (ob1->object->getType() == Object::Controlled) {
429 project(m_Jq,
430 cs->featurerange,
431 ob1->jointrange) = (((ControlledObject *)(ob1->object))->getJq(cs->ee1index));
432 // Transform the reference frame of this jacobian to the world reference frame:
433 Eigen::Block<e_matrix> Jq_part = project(m_Jq, cs->featurerange, ob1->jointrange);
434 changeBase(Jq_part, ob1->base->getPose(ob1->baseFrameIndex));
435 // if the base of this object is moving, get the Ju part
436 if (ob1->base->getNrOfCoordinates() != 0) {
437 // Ju is already computed for world reference frame
438 project(m_Ju, cs->featurerange, ob1->coordinaterange) = ob1->base->getJu(
439 ob1->baseFrameIndex);
440 }
441 }
442 else if (ob1->object->getType() == Object::UnControlled &&
443 ((UncontrolledObject *)ob1->object)->getNrOfCoordinates() != 0) {
444 // object1 is uncontrolled moving object
445 project(m_Ju,
446 cs->featurerange,
447 ob1->coordinaterange) = ((UncontrolledObject *)ob1->object)->getJu(cs->ee1index);
448 }
449 if (ob2->object->getType() == Object::Controlled) {
450 // Get the robotjacobian associated with this constraintset
451 // process a special case where object2 and object1 are equal but using different end
452 // effector
453 if (ob1->object == ob2->object) {
454 // we must create a temporary matrix
455 e_matrix JqTemp(((ControlledObject *)(ob2->object))->getJq(cs->ee2index));
456 // Transform the reference frame of this jacobian to the world reference frame:
457 changeBase(JqTemp, ob2->base->getPose(ob2->baseFrameIndex));
458 // subtract in place
459 project(m_Jq, cs->featurerange, ob2->jointrange) -= JqTemp;
460 }
461 else {
462 project(m_Jq, cs->featurerange, ob2->jointrange) = -(
463 ((ControlledObject *)(ob2->object))->getJq(cs->ee2index));
464 // Transform the reference frame of this jacobian to the world reference frame:
465 Eigen::Block<e_matrix> Jq_part = project(m_Jq, cs->featurerange, ob2->jointrange);
466 changeBase(Jq_part, ob2->base->getPose(ob2->baseFrameIndex));
467 }
468 if (ob2->base->getNrOfCoordinates() != 0) {
469 // if base is the same as first object or first object base,
470 // that portion of m_Ju has been set already => subtract inplace
471 if (ob2->base == ob1->base || ob2->base == ob1->object) {
472 project(m_Ju, cs->featurerange, ob2->coordinaterange) -= ob2->base->getJu(
473 ob2->baseFrameIndex);
474 }
475 else {
476 project(m_Ju, cs->featurerange, ob2->coordinaterange) = -ob2->base->getJu(
477 ob2->baseFrameIndex);
478 }
479 }
480 }
481 else if (ob2->object->getType() == Object::UnControlled &&
482 ((UncontrolledObject *)ob2->object)->getNrOfCoordinates() != 0) {
483 if (ob2->object == ob1->base || ob2->object == ob1->object) {
484 project(m_Ju, cs->featurerange, ob2->coordinaterange) -=
485 ((UncontrolledObject *)ob2->object)->getJu(cs->ee2index);
486 }
487 else {
488 project(m_Ju, cs->featurerange, ob2->coordinaterange) =
489 -((UncontrolledObject *)ob2->object)->getJu(cs->ee2index);
490 }
491 }
492 }
493
494 // Calculate A
495 m_Atemp.noalias() = m_Cf * m_Jf_inv;
496 m_A.noalias() = m_Cq - (m_Atemp * m_Jq);
497 if (m_nuTotal > 0) {
498 m_B.noalias() = m_Atemp * m_Ju;
499 m_ydot.noalias() += m_B * m_xdot;
500 }
501
502 // Call the solver with A, Wq, Wy, ydot to solver qdot:
503 if (!m_solver->solve(m_A, m_Wy, m_ydot, m_Wq, m_qdot, nlcoef))
504 // this should never happen
505 return false;
506 // send result to the objects
507 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
508 Object_struct *os = it->second;
509 if (os->object->getType() == Object::Controlled)
510 ((ControlledObject *)(os->object))->setJointVelocity(project(m_qdot, os->jointrange));
511 }
512 // compute the constraint velocity
513 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
514 ConstraintSet_struct *cs = it->second;
515 Object_struct *ob1 = cs->object1->second;
516 Object_struct *ob2 = cs->object2->second;
517 // Calculate the twist of the world reference frame due to the robots (Jq*qdot+Ju*chiudot):
518 e_vector6 external_vel = e_zero_vector(6);
519 if (ob1->jointrange.count > 0)
520 external_vel.noalias() += (project(m_Jq, cs->featurerange, ob1->jointrange) *
521 project(m_qdot, ob1->jointrange));
522 if (ob2->jointrange.count > 0)
523 external_vel.noalias() += (project(m_Jq, cs->featurerange, ob2->jointrange) *
524 project(m_qdot, ob2->jointrange));
525 if (ob1->coordinaterange.count > 0)
526 external_vel.noalias() += (project(m_Ju, cs->featurerange, ob1->coordinaterange) *
527 project(m_xdot, ob1->coordinaterange));
528 if (ob2->coordinaterange.count > 0)
529 external_vel.noalias() += (project(m_Ju, cs->featurerange, ob2->coordinaterange) *
530 project(m_xdot, ob2->coordinaterange));
531 // the twist caused by the constraint must be opposite because of the closed loop
532 // estimate the velocity of the joints using the inverse jacobian
533 e_vector6 estimated_chidot = project(m_Jf_inv, cs->featurerange, cs->featurerange) *
534 (-external_vel);
535 cs->task->setJointVelocity(estimated_chidot);
536 }
537
538 if (autosubstep) {
539 // automatic computing of substep based on maximum joint change
540 // and joint limit gain variation
541 // We will pass the joint velocity to each object and they will recommend a maximum timestep
542 timesubstep = timeleft;
543 // get armature max joint velocity to estimate the maximum duration of integration
544 // maxqdot = m_qdot.cwise().abs().maxCoeff(); // UNUSED
545 double maxsubstep = nlcoef * m_maxstep;
546 if (maxsubstep < m_minstep)
547 maxsubstep = m_minstep;
548 if (timesubstep > maxsubstep)
549 timesubstep = maxsubstep;
550 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
551 Object_struct *os = it->second;
552 if (os->object->getType() == Object::Controlled)
553 ((ControlledObject *)(os->object))->getMaxTimestep(timesubstep);
554 }
555 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
556 ConstraintSet_struct *cs = it->second;
557 cs->task->getMaxTimestep(timesubstep);
558 }
559 // use substep that are even dividers of timestep for more regularity
560 maxsubstep = 2.0 * floor(timestep / 2.0 / timesubstep - 0.66666);
561 timesubstep = (maxsubstep < 0.0) ? timestep : timestep / (2.0 + maxsubstep);
562 if (timesubstep >= timeleft - (m_minstep / 2.0)) {
563 timesubstep = timeleft;
564 numsubstep = 1;
565 timeleft = 0.;
566 }
567 else {
568 numsubstep = 2;
569 timeleft -= timesubstep;
570 }
571 }
572 if (numsubstep > 1) {
573 ts.substep = 1;
574 }
575 else {
576 // set substep to false for last iteration so that controlled output
577 // can be updated in updateKinematics() and model_update)() before next call to
578 // Secne::update()
579 ts.substep = 0;
580 }
581 // change timestep so that integration is done correctly
582 ts.realTimestep = timesubstep;
583
584 do {
585 ObjectMap::iterator it;
586 Object_struct *os;
587 locked = false;
588 for (it = objects.begin(); it != objects.end(); ++it) {
589 os = it->second;
590 if (os->object->getType() == Object::Controlled) {
591 lockCallback.setRange(os->jointrange);
592 if (((ControlledObject *)os->object)->updateJoint(ts, lockCallback)) {
593 // this means one of the joint was locked and we must rerun
594 // the solver to update the remaining joints
595 locked = true;
596 break;
597 }
598 }
599 }
600 if (locked) {
601 // Some rows of m_Wq have been cleared so that the corresponding joint will not move
602 if (!m_solver->solve(m_A, m_Wy, m_ydot, m_Wq, m_qdot, nlcoef))
603 // this should never happen
604 return false;
605
606 // send result to the objects
607 for (it = objects.begin(); it != objects.end(); ++it) {
608 os = it->second;
609 if (os->object->getType() == Object::Controlled)
610 ((ControlledObject *)(os->object))->setJointVelocity(project(m_qdot, os->jointrange));
611 }
612 }
613 } while (locked);
614
615 // Update the Objects
616 for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
617 it->second->object->updateKinematics(ts);
618 // mark this object not updated since the constraint will be updated anyway
619 // this flag is only useful to detect external updates
620 it->second->object->updated(false);
621 }
622 // Update the Constraints
623 for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
624 ConstraintSet_struct *cs = it->second;
625 // Calculate the external pose:
626 getConstraintPose(cs->task, cs, external_pose);
627 cs->task->modelUpdate(external_pose, ts);
628 // update the constraint output and cache
629 cs->task->updateKinematics(ts);
630 }
631 numsubstep--;
632 }
633 return true;
634}
635
636} // namespace iTaSC
represents a frame transformation in 3D space (rotation + translation)
Definition frames.hpp:526
virtual const e_matrix6 & getJf() const
virtual double getMaxTimestep(double &timestep)
virtual bool initialise(KDL::Frame &init_pose)
virtual void initCache(Cache *_cache)=0
void substep(bool _substep)
virtual void modelUpdate(KDL::Frame &_external_pose, const Timestamp &timestamp)
virtual void updateKinematics(const Timestamp &timestamp)=0
virtual void setJointVelocity(const e_vector chidot_in)
virtual void updateControlOutput(const Timestamp &timestamp)=0
virtual const e_matrix & getCf() const
virtual const e_vector & getControlOutput() const
bool updated()
Definition Object.hpp:47
virtual int addEndEffector(const std::string &)
Definition Object.hpp:36
virtual void initCache(Cache *)=0
virtual void updateKinematics(const Timestamp &)=0
virtual const ObjectType getType()
Definition Object.hpp:42
virtual const KDL::Frame & getPose(const unsigned int end_effector=0)
Definition Object.hpp:38
SceneLock(Scene *scene)
Definition Scene.cpp:22
virtual ~SceneLock()
Definition Scene.cpp:25
virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double *qdot)
Definition Scene.cpp:40
void setRange(Range &range)
Definition Scene.cpp:29
virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
Definition Scene.cpp:34
virtual bool init(unsigned int nq, unsigned int nc, const std::vector< bool > &gc)=0
virtual bool solve(const e_matrix &A, const e_vector &Wy, const e_vector &ydot, const e_matrix &Wq, e_vector &qdot, e_scalar &nlcoef)=0
virtual const e_matrix & getJu(unsigned int frameIndex) const
virtual const unsigned int getNrOfCoordinates()
#define NULL
#define e_vector6
#define e_scalar
#define e_zero_vector
#define e_zero_matrix
#define e_matrix
IndexRange range
int count
ccl_device_inline float2 floor(const float2 a)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
Definition utility.cpp:22
int svd_eigen_HH(const Eigen::MatrixBase< MatrixA > &A, Eigen::MatrixBase< MatrixUV > &U, Eigen::MatrixBase< VectorS > &S, Eigen::MatrixBase< MatrixUV > &V, Eigen::MatrixBase< VectorS > &tmp, int maxiter=150)
void setCacheTimestamp(Timestamp &timestamp)
Definition Cache.hpp:52
static int changeBase(Eigen::MatrixBase< Derived > &J, const Frame &T)
Eigen::Block< MatrixType > project(MatrixType &m, Range r)
Scene(const SceneParams &params, Device *device)
Definition scene.cpp:38
bool update(Progress &progress)
Definition scene.cpp:574
~Scene()
Definition scene.cpp:79
unsigned int interpolate
Definition Cache.hpp:45
double realTimestep
Definition Cache.hpp:38
unsigned int cache
Definition Cache.hpp:43
double realTimestamp
Definition Cache.hpp:37
unsigned int reiterate
Definition Cache.hpp:42
unsigned int substep
Definition Cache.hpp:41
unsigned int numstep
Definition Cache.hpp:40
unsigned int update
Definition Cache.hpp:44