rollout accepts a list of models of length nroll
This commit is contained in:
@@ -16,6 +16,7 @@ Python bindings
|
|||||||
- Added ``bind`` method and removed id attribute from :ref:`mjSpec` objects. Using ids is error prone in scenarios of repeated attachment and
|
- Added ``bind`` method and removed id attribute from :ref:`mjSpec` objects. Using ids is error prone in scenarios of repeated attachment and
|
||||||
detachment. Python users are encouraged to use names for unique identification of model elements.
|
detachment. Python users are encouraged to use names for unique identification of model elements.
|
||||||
- Removed ``nroll`` argument from :ref:`rollout<PyRollout>` because its value can always be inferred.
|
- Removed ``nroll`` argument from :ref:`rollout<PyRollout>` because its value can always be inferred.
|
||||||
|
- :ref:`rollout<PyRollout>` can now accept lists of MjModel of length ``nroll``.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|||||||
@@ -700,6 +700,7 @@ states and sensor values. The basic usage form is
|
|||||||
|
|
||||||
state, sensordata = rollout.rollout(model, data, initial_state, control)
|
state, sensordata = rollout.rollout(model, data, initial_state, control)
|
||||||
|
|
||||||
|
``model`` is either a single instance of MjModel or a list of compatible MjModel of length ``nroll``.
|
||||||
``initial_state`` is an ``nroll x nstate`` array, with ``nroll`` initial states of size ``nstate``, where
|
``initial_state`` is an ``nroll x nstate`` array, with ``nroll`` initial states of size ``nstate``, where
|
||||||
``nstate = mj_stateSize(model, mjtState.mjSTATE_FULLPHYSICS)`` is the size of the
|
``nstate = mj_stateSize(model, mjtState.mjSTATE_FULLPHYSICS)`` is the size of the
|
||||||
:ref:`full physics state<geFullPhysics>`. ``control`` is a ``nroll x nstep x ncontrol`` array of controls. Controls are
|
:ref:`full physics state<geFullPhysics>`. ``control`` is a ``nroll x nstep x ncontrol`` array of controls. Controls are
|
||||||
|
|||||||
+29
-26
@@ -37,7 +37,7 @@ const auto rollout_doc = R"(
|
|||||||
Roll out open-loop trajectories from initial states, get resulting states and sensor values.
|
Roll out open-loop trajectories from initial states, get resulting states and sensor values.
|
||||||
|
|
||||||
input arguments (required):
|
input arguments (required):
|
||||||
model instance of MjModel
|
model list of MjModel instances of length nroll
|
||||||
data associated instance of MjData
|
data associated instance of MjData
|
||||||
nstep integer, number of steps to be taken for each trajectory
|
nstep integer, number of steps to be taken for each trajectory
|
||||||
control_spec specification of controls, ncontrol = mj_stateSize(m, control_spec)
|
control_spec specification of controls, ncontrol = mj_stateSize(m, control_spec)
|
||||||
@@ -54,18 +54,18 @@ Roll out open-loop trajectories from initial states, get resulting states and se
|
|||||||
// C-style rollout function, assumes all arguments are valid
|
// C-style rollout function, assumes all arguments are valid
|
||||||
// all input fields of d are initialised, contents at call time do not matter
|
// all input fields of d are initialised, contents at call time do not matter
|
||||||
// after returning, d will contain the last step of the last rollout
|
// after returning, d will contain the last step of the last rollout
|
||||||
void _unsafe_rollout(const mjModel* m, mjData* d, int nroll, int nstep, unsigned int control_spec,
|
void _unsafe_rollout(const mjModel** m, mjData* d, int nroll, int nstep, unsigned int control_spec,
|
||||||
const mjtNum* state0, const mjtNum* warmstart0, const mjtNum* control,
|
const mjtNum* state0, const mjtNum* warmstart0, const mjtNum* control,
|
||||||
mjtNum* state, mjtNum* sensordata) {
|
mjtNum* state, mjtNum* sensordata) {
|
||||||
// sizes
|
// sizes
|
||||||
int nstate = mj_stateSize(m, mjSTATE_FULLPHYSICS);
|
int nstate = mj_stateSize(m[0], mjSTATE_FULLPHYSICS);
|
||||||
int ncontrol = mj_stateSize(m, control_spec);
|
int ncontrol = mj_stateSize(m[0], control_spec);
|
||||||
int nv = m->nv, nbody = m->nbody, neq = m->neq;
|
int nv = m[0]->nv, nbody = m[0]->nbody, neq = m[0]->neq;
|
||||||
int nsensordata = m->nsensordata;
|
int nsensordata = m[0]->nsensordata;
|
||||||
|
|
||||||
// clear user inputs if unspecified
|
// clear user inputs if unspecified
|
||||||
if (!(control_spec & mjSTATE_CTRL)) {
|
if (!(control_spec & mjSTATE_CTRL)) {
|
||||||
mju_zero(d->ctrl, m->nu);
|
mju_zero(d->ctrl, m[0]->nu);
|
||||||
}
|
}
|
||||||
if (!(control_spec & mjSTATE_QFRC_APPLIED)) {
|
if (!(control_spec & mjSTATE_QFRC_APPLIED)) {
|
||||||
mju_zero(d->qfrc_applied, nv);
|
mju_zero(d->qfrc_applied, nv);
|
||||||
@@ -75,26 +75,26 @@ void _unsafe_rollout(const mjModel* m, mjData* d, int nroll, int nstep, unsigned
|
|||||||
}
|
}
|
||||||
if (!(control_spec & mjSTATE_MOCAP_POS)) {
|
if (!(control_spec & mjSTATE_MOCAP_POS)) {
|
||||||
for (int i = 0; i < nbody; i++) {
|
for (int i = 0; i < nbody; i++) {
|
||||||
int id = m->body_mocapid[i];
|
int id = m[0]->body_mocapid[i];
|
||||||
if (id >= 0) mju_copy3(d->mocap_pos+3*id, m->body_pos+3*i);
|
if (id >= 0) mju_copy3(d->mocap_pos+3*id, m[0]->body_pos+3*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(control_spec & mjSTATE_MOCAP_QUAT)) {
|
if (!(control_spec & mjSTATE_MOCAP_QUAT)) {
|
||||||
for (int i = 0; i < nbody; i++) {
|
for (int i = 0; i < nbody; i++) {
|
||||||
int id = m->body_mocapid[i];
|
int id = m[0]->body_mocapid[i];
|
||||||
if (id >= 0) mju_copy4(d->mocap_quat+4*id, m->body_quat+4*i);
|
if (id >= 0) mju_copy4(d->mocap_quat+4*id, m[0]->body_quat+4*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(control_spec & mjSTATE_EQ_ACTIVE)) {
|
if (!(control_spec & mjSTATE_EQ_ACTIVE)) {
|
||||||
for (int i = 0; i < neq; i++) {
|
for (int i = 0; i < neq; i++) {
|
||||||
d->eq_active[i] = m->eq_active0[i];
|
d->eq_active[i] = m[0]->eq_active0[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop over rollouts
|
// loop over rollouts
|
||||||
for (int r = 0; r < nroll; r++) {
|
for (int r = 0; r < nroll; r++) {
|
||||||
// set initial state
|
// set initial state
|
||||||
mj_setState(m, d, state0 + r*nstate, mjSTATE_FULLPHYSICS);
|
mj_setState(m[r], d, state0 + r*nstate, mjSTATE_FULLPHYSICS);
|
||||||
|
|
||||||
// set warmstart accelerations
|
// set warmstart accelerations
|
||||||
if (warmstart0) {
|
if (warmstart0) {
|
||||||
@@ -124,7 +124,7 @@ void _unsafe_rollout(const mjModel* m, mjData* d, int nroll, int nstep, unsigned
|
|||||||
for (; t < nstep; t++) {
|
for (; t < nstep; t++) {
|
||||||
int step = r*nstep + t;
|
int step = r*nstep + t;
|
||||||
if (state) {
|
if (state) {
|
||||||
mj_getState(m, d, state + step*nstate, mjSTATE_FULLPHYSICS);
|
mj_getState(m[r], d, state + step*nstate, mjSTATE_FULLPHYSICS);
|
||||||
}
|
}
|
||||||
if (sensordata) {
|
if (sensordata) {
|
||||||
mju_copy(sensordata + step*nsensordata, d->sensordata, nsensordata);
|
mju_copy(sensordata + step*nsensordata, d->sensordata, nsensordata);
|
||||||
@@ -137,15 +137,15 @@ void _unsafe_rollout(const mjModel* m, mjData* d, int nroll, int nstep, unsigned
|
|||||||
|
|
||||||
// controls
|
// controls
|
||||||
if (control) {
|
if (control) {
|
||||||
mj_setState(m, d, control + step*ncontrol, control_spec);
|
mj_setState(m[r], d, control + step*ncontrol, control_spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// step
|
// step
|
||||||
mj_step(m, d);
|
mj_step(m[r], d);
|
||||||
|
|
||||||
// copy out new state
|
// copy out new state
|
||||||
if (state) {
|
if (state) {
|
||||||
mj_getState(m, d, state + step*nstate, mjSTATE_FULLPHYSICS);
|
mj_getState(m[r], d, state + step*nstate, mjSTATE_FULLPHYSICS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy out sensor values
|
// copy out sensor values
|
||||||
@@ -188,7 +188,7 @@ PYBIND11_MODULE(_rollout, pymodule) {
|
|||||||
// get subsequent states and corresponding sensor values
|
// get subsequent states and corresponding sensor values
|
||||||
pymodule.def(
|
pymodule.def(
|
||||||
"rollout",
|
"rollout",
|
||||||
[](const MjModelWrapper& m, MjDataWrapper& d,
|
[](py::list m, MjDataWrapper& d,
|
||||||
int nstep, unsigned int control_spec,
|
int nstep, unsigned int control_spec,
|
||||||
const PyCArray state0,
|
const PyCArray state0,
|
||||||
std::optional<const PyCArray> warmstart0,
|
std::optional<const PyCArray> warmstart0,
|
||||||
@@ -196,7 +196,12 @@ PYBIND11_MODULE(_rollout, pymodule) {
|
|||||||
std::optional<const PyCArray> state,
|
std::optional<const PyCArray> state,
|
||||||
std::optional<const PyCArray> sensordata
|
std::optional<const PyCArray> sensordata
|
||||||
) {
|
) {
|
||||||
const raw::MjModel* model = m.get();
|
// get raw pointers
|
||||||
|
int nroll = state0.shape(0);
|
||||||
|
const raw::MjModel* model_ptrs[nroll];
|
||||||
|
for (int r = 0; r < nroll; r++) {
|
||||||
|
model_ptrs[r] = m[r].cast<const MjModelWrapper*>()->get();
|
||||||
|
}
|
||||||
raw::MjData* data = d.get();
|
raw::MjData* data = d.get();
|
||||||
|
|
||||||
// check that some steps need to be taken, return if not
|
// check that some steps need to be taken, return if not
|
||||||
@@ -205,19 +210,17 @@ PYBIND11_MODULE(_rollout, pymodule) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get sizes
|
// get sizes
|
||||||
int nstate = mj_stateSize(model, mjSTATE_FULLPHYSICS);
|
int nstate = mj_stateSize(model_ptrs[0], mjSTATE_FULLPHYSICS);
|
||||||
int ncontrol = mj_stateSize(model, control_spec);
|
int ncontrol = mj_stateSize(model_ptrs[0], control_spec);
|
||||||
int nroll = state0.shape(0);
|
|
||||||
|
|
||||||
// get raw pointers
|
|
||||||
mjtNum* state0_ptr = get_array_ptr(state0, "state0", nroll, 1, nstate);
|
mjtNum* state0_ptr = get_array_ptr(state0, "state0", nroll, 1, nstate);
|
||||||
mjtNum* warmstart0_ptr = get_array_ptr(warmstart0, "warmstart0", nroll,
|
mjtNum* warmstart0_ptr = get_array_ptr(warmstart0, "warmstart0", nroll,
|
||||||
1, model->nv);
|
1, model_ptrs[0]->nv);
|
||||||
mjtNum* control_ptr = get_array_ptr(control, "control", nroll,
|
mjtNum* control_ptr = get_array_ptr(control, "control", nroll,
|
||||||
nstep, ncontrol);
|
nstep, ncontrol);
|
||||||
mjtNum* state_ptr = get_array_ptr(state, "state", nroll, nstep, nstate);
|
mjtNum* state_ptr = get_array_ptr(state, "state", nroll, nstep, nstate);
|
||||||
mjtNum* sensordata_ptr = get_array_ptr(sensordata, "sensordata", nroll,
|
mjtNum* sensordata_ptr = get_array_ptr(sensordata, "sensordata", nroll,
|
||||||
nstep, model->nsensordata);
|
nstep, model_ptrs[0]->nsensordata);
|
||||||
|
|
||||||
// perform rollouts
|
// perform rollouts
|
||||||
{
|
{
|
||||||
@@ -226,7 +229,7 @@ PYBIND11_MODULE(_rollout, pymodule) {
|
|||||||
|
|
||||||
// call unsafe rollout function
|
// call unsafe rollout function
|
||||||
InterceptMjErrors(_unsafe_rollout)(
|
InterceptMjErrors(_unsafe_rollout)(
|
||||||
model, data, nroll, nstep, control_spec, state0_ptr,
|
model_ptrs, data, nroll, nstep, control_spec, state0_ptr,
|
||||||
warmstart0_ptr, control_ptr, state_ptr, sensordata_ptr);
|
warmstart0_ptr, control_ptr, state_ptr, sensordata_ptr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+34
-13
@@ -14,7 +14,7 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
"""Roll out open-loop trajectories from initial states, get subsequent states and sensor values."""
|
"""Roll out open-loop trajectories from initial states, get subsequent states and sensor values."""
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional, Union
|
||||||
|
|
||||||
import mujoco
|
import mujoco
|
||||||
from mujoco import _rollout
|
from mujoco import _rollout
|
||||||
@@ -22,7 +22,7 @@ import numpy as np
|
|||||||
from numpy import typing as npt
|
from numpy import typing as npt
|
||||||
|
|
||||||
|
|
||||||
def rollout(model: mujoco.MjModel,
|
def rollout(model: Union[mujoco.MjModel, list[mujoco.MjModel]],
|
||||||
data: mujoco.MjData,
|
data: mujoco.MjData,
|
||||||
initial_state: npt.ArrayLike,
|
initial_state: npt.ArrayLike,
|
||||||
control: Optional[npt.ArrayLike] = None,
|
control: Optional[npt.ArrayLike] = None,
|
||||||
@@ -41,7 +41,7 @@ def rollout(model: mujoco.MjModel,
|
|||||||
Allocates outputs if none are given.
|
Allocates outputs if none are given.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
model: An mjModel instance.
|
model: An mjModel or a list of MjModel with the same size signature.
|
||||||
data: An associated mjData instance.
|
data: An associated mjData instance.
|
||||||
initial_state: Array of initial states from which to roll out trajectories.
|
initial_state: Array of initial states from which to roll out trajectories.
|
||||||
([nroll or 1] x nstate)
|
([nroll or 1] x nstate)
|
||||||
@@ -90,6 +90,7 @@ def rollout(model: mujoco.MjModel,
|
|||||||
state=state,
|
state=state,
|
||||||
sensordata=sensordata)
|
sensordata=sensordata)
|
||||||
|
|
||||||
|
|
||||||
# check number of dimensions
|
# check number of dimensions
|
||||||
_check_number_of_dimensions(2,
|
_check_number_of_dimensions(2,
|
||||||
initial_state=initial_state,
|
initial_state=initial_state,
|
||||||
@@ -108,14 +109,6 @@ def rollout(model: mujoco.MjModel,
|
|||||||
state = _ensure_3d(state)
|
state = _ensure_3d(state)
|
||||||
sensordata = _ensure_3d(sensordata)
|
sensordata = _ensure_3d(sensordata)
|
||||||
|
|
||||||
# check trailing dimensions
|
|
||||||
nstate = mujoco.mj_stateSize(model, mujoco.mjtState.mjSTATE_FULLPHYSICS.value)
|
|
||||||
_check_trailing_dimension(nstate, initial_state=initial_state, state=state)
|
|
||||||
ncontrol = mujoco.mj_stateSize(model, control_spec)
|
|
||||||
_check_trailing_dimension(ncontrol, control=control)
|
|
||||||
_check_trailing_dimension(model.nv, initial_warmstart=initial_warmstart)
|
|
||||||
_check_trailing_dimension(model.nsensordata, sensordata=sensordata)
|
|
||||||
|
|
||||||
# infer nroll, check for incompatibilities
|
# infer nroll, check for incompatibilities
|
||||||
nroll = _infer_dimension(0, 1,
|
nroll = _infer_dimension(0, 1,
|
||||||
initial_state=initial_state,
|
initial_state=initial_state,
|
||||||
@@ -123,6 +116,14 @@ def rollout(model: mujoco.MjModel,
|
|||||||
control=control,
|
control=control,
|
||||||
state=state,
|
state=state,
|
||||||
sensordata=sensordata)
|
sensordata=sensordata)
|
||||||
|
if isinstance(model, list) and nroll == 1:
|
||||||
|
nroll = len(model)
|
||||||
|
|
||||||
|
if isinstance(model, list) and len(model) != nroll:
|
||||||
|
raise ValueError(f'nroll inferred as {nroll} '
|
||||||
|
f'but model is length {len(model)}')
|
||||||
|
elif not isinstance(model, list):
|
||||||
|
model = [model] # Use a length 1 list to simplify code below
|
||||||
|
|
||||||
# infer nstep, check for incompatibilities
|
# infer nstep, check for incompatibilities
|
||||||
nstep = _infer_dimension(1, nstep or 1,
|
nstep = _infer_dimension(1, nstep or 1,
|
||||||
@@ -130,7 +131,27 @@ def rollout(model: mujoco.MjModel,
|
|||||||
state=state,
|
state=state,
|
||||||
sensordata=sensordata)
|
sensordata=sensordata)
|
||||||
|
|
||||||
# tile input arrays if required (singleton expansion)
|
# get nstate/ncontrol/nv/nsensordata
|
||||||
|
# check that they are equal across models
|
||||||
|
nstate = mujoco.mj_stateSize(model[0], mujoco.mjtState.mjSTATE_FULLPHYSICS.value)
|
||||||
|
ncontrol = mujoco.mj_stateSize(model[0], control_spec)
|
||||||
|
nv = model[0].nv
|
||||||
|
nsensordata = model[0].nsensordata
|
||||||
|
for m in model[1:]:
|
||||||
|
if (nstate != mujoco.mj_stateSize(m, mujoco.mjtState.mjSTATE_FULLPHYSICS.value)
|
||||||
|
or ncontrol != mujoco.mj_stateSize(m, control_spec)
|
||||||
|
or nv != m.nv
|
||||||
|
or nsensordata != m.nsensordata):
|
||||||
|
raise ValueError('models are not compatible')
|
||||||
|
|
||||||
|
# check trailing dimensions
|
||||||
|
_check_trailing_dimension(nstate, initial_state=initial_state, state=state)
|
||||||
|
_check_trailing_dimension(ncontrol, control=control)
|
||||||
|
_check_trailing_dimension(nv, initial_warmstart=initial_warmstart)
|
||||||
|
_check_trailing_dimension(nsensordata, sensordata=sensordata)
|
||||||
|
|
||||||
|
# tile input arrays/lists if required (singleton expansion)
|
||||||
|
model = model*nroll if len(model) == 1 else model
|
||||||
initial_state = _tile_if_required(initial_state, nroll)
|
initial_state = _tile_if_required(initial_state, nroll)
|
||||||
initial_warmstart = _tile_if_required(initial_warmstart, nroll)
|
initial_warmstart = _tile_if_required(initial_warmstart, nroll)
|
||||||
control = _tile_if_required(control, nroll, nstep)
|
control = _tile_if_required(control, nroll, nstep)
|
||||||
@@ -139,7 +160,7 @@ def rollout(model: mujoco.MjModel,
|
|||||||
if state is None:
|
if state is None:
|
||||||
state = np.empty((nroll, nstep, nstate))
|
state = np.empty((nroll, nstep, nstate))
|
||||||
if sensordata is None:
|
if sensordata is None:
|
||||||
sensordata = np.empty((nroll, nstep, model.nsensordata))
|
sensordata = np.empty((nroll, nstep, nsensordata))
|
||||||
|
|
||||||
# call rollout
|
# call rollout
|
||||||
_rollout.rollout(model, data, nstep, control_spec, initial_state,
|
_rollout.rollout(model, data, nstep, control_spec, initial_state,
|
||||||
|
|||||||
@@ -334,6 +334,34 @@ class MuJoCoRolloutTest(parameterized.TestCase):
|
|||||||
np.testing.assert_array_equal(state, py_state)
|
np.testing.assert_array_equal(state, py_state)
|
||||||
np.testing.assert_array_equal(sensordata, py_sensordata)
|
np.testing.assert_array_equal(sensordata, py_sensordata)
|
||||||
|
|
||||||
|
@parameterized.parameters(ALL_MODELS.keys())
|
||||||
|
def test_multi_model(self, model_name):
|
||||||
|
nroll = 3 # number of initial states and models
|
||||||
|
nstep = 3 # number of timesteps
|
||||||
|
|
||||||
|
spec = mujoco.MjSpec.from_string(ALL_MODELS[model_name])
|
||||||
|
|
||||||
|
if len(spec.bodies) > 1:
|
||||||
|
model = []
|
||||||
|
for i in range(nroll):
|
||||||
|
body = spec.bodies[1]
|
||||||
|
assert body.name != 'world'
|
||||||
|
body.pos = body.pos + i
|
||||||
|
model.append(spec.compile())
|
||||||
|
else:
|
||||||
|
model = [spec.compile() for i in range(nroll)]
|
||||||
|
|
||||||
|
nstate = mujoco.mj_stateSize(model[0], mujoco.mjtState.mjSTATE_FULLPHYSICS)
|
||||||
|
data = mujoco.MjData(model[0])
|
||||||
|
|
||||||
|
initial_state = np.random.randn(nroll, nstate)
|
||||||
|
control = np.random.randn(nroll, nstep, model[0].nu)
|
||||||
|
state, sensordata = rollout.rollout(model, data, initial_state, control)
|
||||||
|
|
||||||
|
py_state, py_sensordata = py_rollout(model, data, initial_state, control)
|
||||||
|
np.testing.assert_array_equal(state, py_state)
|
||||||
|
np.testing.assert_array_equal(sensordata, py_sensordata)
|
||||||
|
|
||||||
@parameterized.parameters(ALL_MODELS.keys())
|
@parameterized.parameters(ALL_MODELS.keys())
|
||||||
def test_multi_rollout_fixed_ctrl_infer_from_output(self, model_name):
|
def test_multi_rollout_fixed_ctrl_infer_from_output(self, model_name):
|
||||||
model = mujoco.MjModel.from_xml_string(ALL_MODELS[model_name])
|
model = mujoco.MjModel.from_xml_string(ALL_MODELS[model_name])
|
||||||
@@ -430,8 +458,9 @@ class MuJoCoRolloutTest(parameterized.TestCase):
|
|||||||
def thread_initializer():
|
def thread_initializer():
|
||||||
thread_local.data = mujoco.MjData(model)
|
thread_local.data = mujoco.MjData(model)
|
||||||
|
|
||||||
|
model_list = [model]*nroll
|
||||||
def call_rollout(initial_state, control, state, sensordata):
|
def call_rollout(initial_state, control, state, sensordata):
|
||||||
rollout.rollout(model, thread_local.data, initial_state, control,
|
rollout.rollout(model_list, thread_local.data, initial_state, control,
|
||||||
skip_checks=True,
|
skip_checks=True,
|
||||||
nstep=nstep, state=state, sensordata=sensordata)
|
nstep=nstep, state=state, sensordata=sensordata)
|
||||||
|
|
||||||
@@ -677,13 +706,17 @@ def py_rollout(model, data, initial_state, control,
|
|||||||
control = ensure_3d(control)
|
control = ensure_3d(control)
|
||||||
nroll = initial_state.shape[0]
|
nroll = initial_state.shape[0]
|
||||||
nstep = control.shape[1]
|
nstep = control.shape[1]
|
||||||
nstate = mujoco.mj_stateSize(model, mujoco.mjtState.mjSTATE_FULLPHYSICS)
|
|
||||||
|
if isinstance(model, mujoco.MjModel):
|
||||||
|
model = [model]*nroll
|
||||||
|
|
||||||
|
nstate = mujoco.mj_stateSize(model[0], mujoco.mjtState.mjSTATE_FULLPHYSICS)
|
||||||
|
|
||||||
state = np.empty((nroll, nstep, nstate))
|
state = np.empty((nroll, nstep, nstate))
|
||||||
sensordata = np.empty((nroll, nstep, model.nsensordata))
|
sensordata = np.empty((nroll, nstep, model[0].nsensordata))
|
||||||
for r in range(nroll):
|
for r in range(nroll):
|
||||||
state_r, sensordata_r = one_rollout(
|
state_r, sensordata_r = one_rollout(
|
||||||
model, data, initial_state[r], control[r], control_spec
|
model[r], data, initial_state[r], control[r], control_spec
|
||||||
)
|
)
|
||||||
state[r] = state_r
|
state[r] = state_r
|
||||||
sensordata[r] = sensordata_r
|
sensordata[r] = sensordata_r
|
||||||
|
|||||||
Reference in New Issue
Block a user