Skip to content

Commit ed48495

Browse files
Add diffusion dynamics task and related methods to MJScene class
1 parent 7faf271 commit ed48495

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

src/simulation/mujocoDynamics/_GeneralModuleFiles/MJScene.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <stdexcept>
3333
#include <vector>
3434
#include <cmath>
35+
#include <unordered_set>
3536

3637
MJScene::MJScene(std::string xml, const std::vector<std::string>& files)
3738
: spec(*this, xml, files)
@@ -59,13 +60,31 @@ void MJScene::AddFwdKinematicsToDynamicsTask(int32_t priority)
5960
this->AddModelToDynamicsTask(this->ownedSysModel.back().get(), priority);
6061
}
6162

62-
void MJScene::SelfInit() { this->dynamicsTask.SelfInitTaskList(); }
63+
void MJScene::AddModelToDiffusionDynamicsTask(SysModel* model, int32_t priority)
64+
{
65+
this->dynamicsDiffusionTask.AddNewObject(model, priority);
66+
}
67+
68+
void MJScene::AddFwdKinematicsToDiffusionDynamicsTask(int32_t priority)
69+
{
70+
this->ownedSysModel.emplace_back(std::make_unique<MJFwdKinematics>(*this));
71+
this->ownedSysModel.back()->ModelTag = "FwdKinematics" + std::to_string(this->ownedSysModel.size()-1);
72+
this->AddModelToDiffusionDynamicsTask(this->ownedSysModel.back().get(), priority);
73+
}
74+
75+
void MJScene::SelfInit()
76+
{
77+
this->dynamicsTask.SelfInitTaskList();
78+
this->dynamicsDiffusionTask.SelfInitTaskList();
79+
}
6380

6481
void MJScene::Reset(uint64_t CurrentSimNanos)
6582
{
6683
this->timeBefore = CurrentSimNanos * NANO2SEC;
6784
this->dynamicsTask.TaskName = "Dynamics:" + this->ModelTag;
6885
this->dynamicsTask.ResetTaskList(CurrentSimNanos);
86+
this->dynamicsDiffusionTask.TaskName = "DiffusionDynamics:" + this->ModelTag;
87+
this->dynamicsDiffusionTask.ResetTaskList(CurrentSimNanos);
6988
this->initializeDynamics();
7089
this->writeOutputStateMessages(CurrentSimNanos);
7190
}
@@ -95,16 +114,31 @@ void MJScene::initializeDynamics()
95114
}
96115

97116
// Register the states of the models in the dynamics task
98-
for (auto[_, sysModelPtr] : this->dynamicsTask.TaskModels)
117+
std::unordered_set<StatefulSysModel*> alreadyRegisteredModels;
118+
auto registerStatesOnSysModel = [this, &alreadyRegisteredModels](SysModel* sysModelPtr)
99119
{
100120
if (auto statefulSysModelPtr = dynamic_cast<StatefulSysModel*>(sysModelPtr))
101121
{
122+
// Don't registerStates in a model twice!
123+
if (alreadyRegisteredModels.count(statefulSysModelPtr) > 0) return;
124+
102125
statefulSysModelPtr->registerStates(DynParamRegisterer(
103126
this->dynManager,
104127
sysModelPtr->ModelTag.empty() ? std::string("model") : sysModelPtr->ModelTag
105128
+ "_" + std::to_string(sysModelPtr->moduleID) + "_"
106129
));
130+
131+
alreadyRegisteredModels.emplace(statefulSysModelPtr);
107132
}
133+
};
134+
135+
for (auto[_, sysModelPtr] : this->dynamicsTask.TaskModels)
136+
{
137+
registerStatesOnSysModel(sysModelPtr);
138+
}
139+
for (auto[_, sysModelPtr] : this->dynamicsDiffusionTask.TaskModels)
140+
{
141+
registerStatesOnSysModel(sysModelPtr);
108142
}
109143
}
110144

@@ -206,6 +240,12 @@ void MJScene::equationsOfMotion(double t, double timeStep)
206240
}
207241
}
208242

243+
void MJScene::equationsOfMotionDiffusion(double t, double timeStep)
244+
{
245+
auto nanos = static_cast<uint64_t>(t * SEC2NANO);
246+
this->dynamicsDiffusionTask.ExecuteTaskList(nanos);
247+
}
248+
209249
void MJScene::preIntegration(double callTime) { this->timeStep = callTime - this->timeBefore; }
210250

211251
void MJScene::postIntegration(double callTime)

src/simulation/mujocoDynamics/_GeneralModuleFiles/MJScene.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ class MJScene : public DynamicObject
290290
* task typically compute and apply forces and torques on the system
291291
* that depend on the simulation time or the state of the multi-body.
292292
*
293+
* Models in this task should contribute to computing ``f`` in:
294+
*
295+
* dx = f(t,x) dt
296+
*
297+
* where ``x`` represents the state of this dynamic object.
298+
*
293299
* @warning `SysModel` added to the dynamics task should be memoryless.
294300
* That is, any output message computed should depend strictly on
295301
* input messages and the current time/states. It should save values
@@ -303,6 +309,23 @@ class MJScene : public DynamicObject
303309
*/
304310
void AddModelToDynamicsTask(SysModel* model, int32_t priority = -1);
305311

312+
/** @brief Adds a model to the diffusion dynamics task.
313+
*
314+
* This task and function are only relevant when the dynamics of
315+
* the system are stochastic.
316+
*
317+
* Similar to ``AddModelToDynamicsTask``, except that models in this
318+
* task contribute to computing ``g`` in:
319+
*
320+
* dx = f(t,x)dt + g(t,x)dW
321+
*
322+
* where ``x`` is the state of the system, ``f`` represents the
323+
* drift term of the dynamics (classic time derivative), and
324+
* ``g`` is the diffusion term of the dynamics (which evaluates
325+
* the impact of the random 'noise' ``W`` on the dynamics).
326+
*/
327+
void AddModelToDiffusionDynamicsTask(SysModel* model, int32_t priority = -1);
328+
306329
/**
307330
* @brief Adds forward kinematics to the dynamics task.
308331
*
@@ -334,6 +357,17 @@ class MJScene : public DynamicObject
334357
*/
335358
void AddFwdKinematicsToDynamicsTask(int32_t priority);
336359

360+
/**
361+
* @brief Adds forward kinematics to the diffusion dynamics task.
362+
*
363+
* See ``AddModelToDiffusionDynamicsTask`` and ``AddFwdKinematicsToDynamicsTask``.
364+
*
365+
* By default, the diffusion dynamics task has no forward kinematics
366+
* model, so one must be added if the diffusion term depends on the
367+
* forward kinematics of the multibody.
368+
*/
369+
void AddFwdKinematicsToDiffusionDynamicsTask(int32_t priority);
370+
337371
/**
338372
* @brief Calls `SelfInit` on all system models in the dynamics task.
339373
*/
@@ -367,11 +401,30 @@ class MJScene : public DynamicObject
367401
* joints... These information is translated, through MuJoCo, into
368402
* first derivatives of the joint states and the mass of bodies.
369403
*
404+
* Computes ``f`` in:
405+
*
406+
* dx = f(t,x) dt
407+
*
408+
* where ``x`` represents the current state of the dynamics.
409+
*
370410
* @param t The current simulation time in seconds.
371411
* @param timeStep The integration time step.
372412
*/
373413
void equationsOfMotion(double t, double timeStep) override;
374414

415+
/**
416+
* @brief Computes the diffusion of the dynamics of the system.
417+
*
418+
* Only relevant for systems with stochastic dynamics.
419+
*
420+
* Computes ``g`` in:
421+
*
422+
* dx = f(t,x) dt + g(t,x)dW
423+
*
424+
* where ``x`` represents the current state of the dynamics.
425+
*/
426+
void equationsOfMotionDiffusion(double t, double timeStep) override;
427+
375428
/**
376429
* @brief Prepares the system before actual integration.
377430
*
@@ -558,6 +611,7 @@ class MJScene : public DynamicObject
558611
bool forwardKinematicsStale = true; ///< Flag indicating stale forward kinematics.
559612

560613
SysModelTask dynamicsTask; ///< Task managing models involved in the dynamics of this scene.
614+
SysModelTask dynamicsDiffusionTask; ///< Task managing models involved in the diffusion stochastic dynamics of this scene.
561615
std::vector<std::unique_ptr<SysModel>> ownedSysModel; ///< System models that should be cleared on this scene destruction.
562616

563617
MJQPosStateData* qposState; ///< Position state data.

0 commit comments

Comments
 (0)