From 7cad32fa2f8ac3c64699c643f5229490e9e4a1af Mon Sep 17 00:00:00 2001 From: Alexis Duburcq Date: Mon, 13 May 2024 11:23:26 +0200 Subject: [PATCH] [gym/common] Enable specifying reference trajectories in pipeline config. --- core/src/io/json_writer.cc | 6 +- .../gym_jiminy/common/bases/pipeline.py | 17 +- .../gym_jiminy/common/bases/quantities.py | 19 +- .../gym_jiminy/common/utils/__init__.py | 7 +- .../gym_jiminy/common/utils/pipeline.py | 191 ++++++++++++++++-- python/gym_jiminy/common/setup.py | 4 +- .../unit_py/data/anymal_pipeline.toml | 5 +- .../unit_py/data/anymal_trajectory.hdf5 | Bin 0 -> 249246 bytes python/jiminy_py/src/jiminy_py/log.py | 4 +- .../include/jiminy/python/utilities.h | 30 +-- python/jiminy_pywrap/src/helpers.cc | 16 +- 11 files changed, 250 insertions(+), 49 deletions(-) create mode 100644 python/gym_jiminy/unit_py/data/anymal_trajectory.hdf5 diff --git a/core/src/io/json_writer.cc b/core/src/io/json_writer.cc index fce2f6fe9b..0e4fbc2edd 100644 --- a/core/src/io/json_writer.cc +++ b/core/src/io/json_writer.cc @@ -28,9 +28,11 @@ namespace jiminy std::unique_ptr writer(builder.newStreamWriter()); std::ostream output(&buffer); writer->write(input, &output); - device_->resize(static_cast(buffer.str().size())); - device_->write(buffer.str()); + // FIXME: Use `view` to get a string_view rather than a string copy when moving to C++20 + const std::string data = buffer.str(); + device_->resize(static_cast(data.size())); + device_->write(data); device_->close(); } diff --git a/python/gym_jiminy/common/gym_jiminy/common/bases/pipeline.py b/python/gym_jiminy/common/gym_jiminy/common/bases/pipeline.py index 81288e5cca..c1cc53caf2 100644 --- a/python/gym_jiminy/common/gym_jiminy/common/bases/pipeline.py +++ b/python/gym_jiminy/common/gym_jiminy/common/bases/pipeline.py @@ -19,9 +19,11 @@ Callable, cast) import numpy as np + import gymnasium as gym from gymnasium.core import RenderFrame from gymnasium.envs.registration import EnvSpec +from jiminy_py.dynamics import Trajectory from .interfaces import (DT_EPS, ObsT, @@ -319,7 +321,8 @@ class ComposedJiminyEnv( def __init__(self, env: InterfaceJiminyEnv[ObsT, ActT], *, - reward: AbstractReward) -> None: + reward: Optional[AbstractReward] = None, + trajectories: Optional[Dict[str, Trajectory]] = None) -> None: """ :param env: Environment to extend, eventually already wrapped. :param reward: Reward object deriving from `AbstractReward`. It will be @@ -329,6 +332,11 @@ def __init__(self, the provided environment. `None` for not considering any reward. Optional: `None` by default. + :param trajectories: Set of named trajectories as a dictionary whose + (key, value) pairs are respectively the name of + each trajectory and the trajectory itself. `None` + for not considering any trajectory. + Optional: `None` by default. """ # Make sure that the unwrapped environment matches the reward one assert reward is None or env.unwrapped is reward.env.unwrapped @@ -339,6 +347,11 @@ def __init__(self, # Initialize base class super().__init__(env) + # Add reference trajectories to all managed quantities if requested + if trajectories is not None: + for name, trajectory in trajectories.items(): + self.env.quantities.add_trajectory(name, trajectory) + # Bind observation and action of the base environment assert self.observation_space.contains(self.env.observation) assert self.action_space.contains(self.env.action) @@ -396,6 +409,8 @@ def compute_command(self, action: ActT, command: np.ndarray) -> None: self.env.compute_command(action, command) def compute_reward(self, terminated: bool, info: InfoType) -> float: + if self.reward is None: + return 0.0 return self.reward(terminated, info) diff --git a/python/gym_jiminy/common/gym_jiminy/common/bases/quantities.py b/python/gym_jiminy/common/gym_jiminy/common/bases/quantities.py index 1370410eb8..43bf5d738a 100644 --- a/python/gym_jiminy/common/gym_jiminy/common/bases/quantities.py +++ b/python/gym_jiminy/common/gym_jiminy/common/bases/quantities.py @@ -762,6 +762,12 @@ def discard(self, name: str) -> None: :param name: Name of the trajectory to discard. """ + # Un-select trajectory if it corresponds to the discarded one + if self._name == name: + self._trajectory = None + self._name = "" + + # Delete trajectory for global registry del self.registry[name] @sync @@ -799,12 +805,10 @@ def name(self) -> str: @InterfaceQuantity.cache.setter # type: ignore[attr-defined] def cache(self, cache: Optional[SharedCache[ValueT]]) -> None: # Get existing registry if any and making sure not already out-of-sync - registry: Optional[OrderedDict[str, Trajectory]] = None + owner: Optional[InterfaceQuantity] = None if cache is not None and cache.owners: - owner: InterfaceQuantity = next(iter(cache.owners)) + owner = next(iter(cache.owners)) assert isinstance(owner, DatasetTrajectoryQuantity) - registry = owner.registry - name, mode = owner._name, owner._mode if self._trajectory: raise RuntimeError( "Trajectory dataset not empty. Impossible to add a shared " @@ -814,9 +818,10 @@ def cache(self, cache: Optional[SharedCache[ValueT]]) -> None: InterfaceQuantity.cache.fset(self, cache) # type: ignore[attr-defined] # Catch-up synchronization - if registry is not None: - self.registry = registry - self.select(name, mode) + if owner: + self.registry = owner.registry + if owner._trajectory is not None: + self.select(owner._name, owner._mode) def refresh(self) -> State: """Compute state of selected trajectory at current simulation time. diff --git a/python/gym_jiminy/common/gym_jiminy/common/utils/__init__.py b/python/gym_jiminy/common/gym_jiminy/common/utils/__init__.py index f2b082a2c1..364ac290c4 100644 --- a/python/gym_jiminy/common/gym_jiminy/common/utils/__init__.py +++ b/python/gym_jiminy/common/gym_jiminy/common/utils/__init__.py @@ -41,7 +41,10 @@ get_fieldnames, register_variables, sample) -from .pipeline import build_pipeline, load_pipeline +from .pipeline import (save_trajectory_to_hdf5, + load_trajectory_to_hdf5, + build_pipeline, + load_pipeline) __all__ = [ @@ -86,6 +89,8 @@ 'is_nan', 'get_fieldnames', 'register_variables', + 'save_trajectory_to_hdf5', + 'load_trajectory_to_hdf5', 'build_pipeline', 'load_pipeline' ] diff --git a/python/gym_jiminy/common/gym_jiminy/common/utils/pipeline.py b/python/gym_jiminy/common/gym_jiminy/common/utils/pipeline.py index 09b83b3ff4..52d1fb51ea 100644 --- a/python/gym_jiminy/common/gym_jiminy/common/utils/pipeline.py +++ b/python/gym_jiminy/common/gym_jiminy/common/utils/pipeline.py @@ -10,13 +10,20 @@ import json import pathlib from pydoc import locate +from dataclasses import asdict from functools import partial from typing import ( - Dict, Any, Optional, Union, Type, Sequence, Callable, TypedDict) + Dict, Any, Optional, Union, Type, Sequence, Callable, TypedDict, Literal, + cast) +import h5py import toml +import numpy as np import gymnasium as gym +import jiminy_py.core as jiminy +from jiminy_py.dynamics import State, Trajectory + from ..bases import (InterfaceJiminyEnv, InterfaceBlock, BaseControllerBlock, @@ -53,6 +60,36 @@ class RewardConfig(TypedDict, total=False): """ +class TrajectoriesConfig(TypedDict, total=False): + """Store information required for adding a database of reference + trajectories to the environment. + + Specifically, it is a dictionary comprising a set of named trajectories as + a dictionary whose keys are the name of the trajectories and values are + either the trajectory itself or the path of a file storing its dump in HDF5 + format, the name of the selected trajectory, and its interpolation mode. + """ + + dataset: Dict[str, Union[str, Trajectory]] + """Set of named trajectories as a dictionary. + + .. note:: + Both `Trajectory` objects or path (absolute or relative) are supported. + """ + + name: str + """Name of the selected trajectory if any. + + This attribute can be omitted. + """ + + mode: Literal['raise', 'wrap', 'clip'] + """Interpolation mode of the selected trajectory if any. + + This attribute can be omitted. + """ + + class EnvConfig(TypedDict, total=False): """Store information required for instantiating a given base environment and compose it with some additional reward components and termination @@ -84,6 +121,12 @@ class EnvConfig(TypedDict, total=False): This attribute can be omitted. """ + trajectories: TrajectoriesConfig + """Reference trajectories configuration. + + This attribute can be omitted. + """ + class BlockConfig(TypedDict, total=False): """Store information required for instantiating a given observation or @@ -163,7 +206,9 @@ class LayerConfig(TypedDict, total=False): def build_pipeline(env_config: EnvConfig, - layers_config: Sequence[LayerConfig] + layers_config: Sequence[LayerConfig], + *, + root_path: Optional[Union[str, pathlib.Path]] = None ) -> Callable[..., InterfaceJiminyEnv]: """Wrap together an environment inheriting from `BaseJiminyEnv` with any number of layers, as a unified pipeline environment class inheriting from @@ -232,8 +277,9 @@ def build_reward(env: InterfaceJiminyEnv, # Define helper to build reward def build_composition(env_creator: Callable[..., InterfaceJiminyEnv], - reward_config: RewardConfig, - **env_kwargs: Any) -> BasePipelineWrapper: + reward_config: Optional[RewardConfig], + trajectories_config: Optional[TrajectoriesConfig], + **env_kwargs: Any) -> InterfaceJiminyEnv: """Helper adding reward on top of a base environment or a pipeline using `ComposedJiminyEnv` wrapper. @@ -241,6 +287,8 @@ def build_composition(env_creator: Callable[..., InterfaceJiminyEnv], input and returns an pipeline or base environment. :param reward_config: Configuration of the reward, as a dict of type `RewardConfig`. + :param trajectories: Set of named trajectories as a dictionary. See + `ComposedJiminyEnv` documentation for details. :param env_kwargs: Keyword arguments to forward to the constructor of the wrapped environment. Note that it will only overwrite the default value, so it will still be @@ -252,10 +300,29 @@ def build_composition(env_creator: Callable[..., InterfaceJiminyEnv], env = env_creator(**env_kwargs) # Instantiate the reward - reward = build_reward(env, reward_config) - - # Instantiate the wrapper - return ComposedJiminyEnv(env, reward=reward) + reward = None + if reward_config is not None: + reward = build_reward(env, reward_config) + + # Get trajectory dataset + trajectories: Dict[str, Trajectory] = {} + if trajectories_config is not None: + trajectories = cast( + Dict[str, Trajectory], trajectories_config["dataset"]) + + # Instantiate the composition wrapper if necessary + if reward or trajectories: + env = ComposedJiminyEnv( + env, reward=reward, trajectories=trajectories) + + # Select the reference trajectory if specified + if trajectories_config is not None: + name = trajectories_config.get("name") + if name is not None: + mode = trajectories_config.get("mode", "raise") + env.quantities.select_trajectory(name, mode) + + return env # Define helper to wrap a single layer def build_layer(env_creator: Callable[..., InterfaceJiminyEnv], @@ -329,13 +396,33 @@ def build_layer(env_creator: Callable[..., InterfaceJiminyEnv], pipeline_creator: Callable[..., InterfaceJiminyEnv] = partial( env_cls, **env_config.get("kwargs", {})) - # Compose base environment with an extra user-specified reward if any + # Parse reward configuration reward_config = env_config.get("reward") if reward_config is not None: sanitize_reward_config(reward_config) - pipeline_creator = partial(build_composition, - pipeline_creator, - reward_config) + + # Parse trajectory configuration + trajectories_config = env_config.get("trajectories") + if trajectories_config is not None: + trajectories = trajectories_config['dataset'] + assert isinstance(trajectories, dict) + for name, path_or_traj in trajectories.items(): + if isinstance(path_or_traj, Trajectory): + continue + path = pathlib.Path(path_or_traj) + if not path.is_absolute(): + if root_path is None: + raise RuntimeError( + "The argument 'root_path' must be provided when " + "specifying relative trajectory paths.") + path = pathlib.Path(root_path) / path + trajectories[name] = load_trajectory_to_hdf5(path) + + # Compose base environment with an extra user-specified reward + pipeline_creator = partial(build_composition, + pipeline_creator, + reward_config, + trajectories_config) # Generate pipeline recursively for layer_config in layers_config: @@ -397,15 +484,87 @@ def build_layer(env_creator: Callable[..., InterfaceJiminyEnv], return pipeline_creator -def load_pipeline(fullpath: str) -> Callable[..., InterfaceJiminyEnv]: +def load_pipeline(fullpath: Union[str, pathlib.Path] + ) -> Callable[..., InterfaceJiminyEnv]: """Load pipeline from JSON or TOML configuration file. :param: Fullpath of the configuration file. """ - file_ext = pathlib.Path(fullpath).suffix + fullpath = pathlib.Path(fullpath) + root_path, file_ext = fullpath.parent, fullpath.suffix with open(fullpath, 'r') as f: if file_ext == '.json': - return build_pipeline(**json.load(f)) + return build_pipeline(**json.load(f), root_path=root_path) if file_ext == '.toml': - return build_pipeline(**toml.load(f)) + return build_pipeline(**toml.load(f), root_path=root_path) raise ValueError("Only json and toml formats are supported.") + + +def save_trajectory_to_hdf5(trajectory: Trajectory, + fullpath: Union[str, pathlib.Path]) -> None: + """Export a trajectory object to HDF5 format. + + :param trajectory: Trajectory object to save. + :param fullpath: Fullpath of the generated HDF5 file. + """ + # Create HDF5 file + hdf_obj = h5py.File(fullpath, "w") + + # Dump each state attribute that are specified for all states at once + if trajectory.states: + state_dict = asdict(trajectory.states[0]) + state_fields = tuple( + key for key, value in state_dict.items() if value is not None) + for key in state_fields: + data = np.stack([ + getattr(state, key) for state in trajectory.states], axis=0) + hdf_obj.create_dataset(name=f"states/{key}", data=data) + + # Dump serialized robot + robot_data = jiminy.save_to_binary(trajectory.robot) + dataset = hdf_obj.create_dataset(name="robot", data=np.array(robot_data)) + + # Dump whether to use the theoretical model of the robot + dataset.attrs["use_theoretical_model"] = trajectory.use_theoretical_model + + # Close the HDF5 file + hdf_obj.close() + + +def load_trajectory_to_hdf5(fullpath: Union[str, pathlib.Path]) -> Trajectory: + """Import a trajectory object from file in HDF5 format. + + :param fullpath: Fullpath of the HDF5 file to import. + + :returns: Loaded trajectory object. + """ + # Open HDF5 file + hdf_obj = h5py.File(fullpath, "r") + + # Get all state attributes that are specified + states_dict = {} + if 'states' in hdf_obj.keys(): + for key, value in hdf_obj['states'].items(): + states_dict[key] = value[...] + + # Re-construct state sequence + states = [] + for args in zip(*states_dict.values()): + states.append(State(**dict(zip(states_dict.keys(), args)))) + + # Build trajectory from data. + # Null char '\0' must be added at the end to match original string length. + dataset = hdf_obj['robot'] + robot_data = dataset[()] + robot_data += b'\0' * ( + dataset.nbytes - len(robot_data)) # pylint: disable=no-member + robot = jiminy.load_from_binary(robot_data) + + # Load whether to use the theoretical model of the robot + use_theoretical_model = dataset.attrs["use_theoretical_model"] + + # Close the HDF5 file + hdf_obj.close() + + # Re-construct the whole trajectory + return Trajectory(states, robot, use_theoretical_model) diff --git a/python/gym_jiminy/common/setup.py b/python/gym_jiminy/common/setup.py index 0f1dce609a..0956bae005 100644 --- a/python/gym_jiminy/common/setup.py +++ b/python/gym_jiminy/common/setup.py @@ -49,8 +49,8 @@ package_data={"gym_jiminy.common": ["py.typed"]}, install_requires=[ f"jiminy-py~={jiminy_version}", - # Use to perform linear algebra computation - "numpy", + # Use internally for loading and dumping trajectories + "h5py", # Use internally to speedup computation of math methods # - 0.54: Adds 'np.clip' "numba>=0.54.0", diff --git a/python/gym_jiminy/unit_py/data/anymal_pipeline.toml b/python/gym_jiminy/unit_py/data/anymal_pipeline.toml index dcd8a1a50f..6f6255e32d 100644 --- a/python/gym_jiminy/unit_py/data/anymal_pipeline.toml +++ b/python/gym_jiminy/unit_py/data/anymal_pipeline.toml @@ -4,6 +4,10 @@ cls = "gym_jiminy.envs.ANYmalJiminyEnv" step_dt = 0.04 [env_config.reward] cls = "gym_jiminy.common.compositions.AdditiveMixtureReward" +[env_config.trajectories] +mode = "raise" +name = "reference" +dataset.reference = "./anymal_trajectory.hdf5" [env_config.reward.kwargs] name = "reward_total" weights = [0.6, 0.4] @@ -11,7 +15,6 @@ weights = [0.6, 0.4] cls = "gym_jiminy.common.compositions.OdometryVelocityReward" [env_config.reward.kwargs.components.kwargs] cutoff = 0.5 -target = [0.0, 0.0, 0.0] [[env_config.reward.kwargs.components]] cls = "gym_jiminy.common.compositions.SurviveReward" diff --git a/python/gym_jiminy/unit_py/data/anymal_trajectory.hdf5 b/python/gym_jiminy/unit_py/data/anymal_trajectory.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..c73512cac1c31e9d602351d3aff9b8a052d16afb GIT binary patch literal 249246 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 acm&#Q9!ES>lIgznc;X@pHgL6-8ukB_o2$V9 literal 0 HcmV?d00001 diff --git a/python/jiminy_py/src/jiminy_py/log.py b/python/jiminy_py/src/jiminy_py/log.py index 6732fb8f40..db808c5c59 100644 --- a/python/jiminy_py/src/jiminy_py/log.py +++ b/python/jiminy_py/src/jiminy_py/log.py @@ -169,8 +169,8 @@ def build_robot_from_log( # Get binary serialized robot data robot_data = log_constants[".".join(filter(None, (robot_name, "robot")))] - # Load robot - return jiminy.build_robot_from_binary( + # Load robot from binary data + return jiminy.load_from_binary( robot_data, mesh_path_dir, mesh_package_dirs) diff --git a/python/jiminy_pywrap/include/jiminy/python/utilities.h b/python/jiminy_pywrap/include/jiminy/python/utilities.h index bd367bb42d..f3bee2011e 100644 --- a/python/jiminy_pywrap/include/jiminy/python/utilities.h +++ b/python/jiminy_pywrap/include/jiminy/python/utilities.h @@ -19,14 +19,17 @@ #include -#define EXPECTED_PYTYPE_FOR_ARG_IS_ARRAY(type) \ - namespace boost::python::converter \ - { \ - template<> \ - struct expected_pytype_for_arg \ - { \ - static const PyTypeObject * get_pytype() { return &PyArray_Type; } \ - }; \ +#define EXPECTED_PYTYPE_FOR_ARG_IS_ARRAY(type) \ + namespace boost::python::converter \ + { \ + template<> \ + struct expected_pytype_for_arg \ + { \ + static const PyTypeObject * get_pytype() \ + { \ + return &PyArray_Type; \ + } \ + }; \ } EXPECTED_PYTYPE_FOR_ARG_IS_ARRAY(numpy::ndarray) @@ -217,6 +220,7 @@ namespace jiminy::python { stringStream << ":\n\n" << doc; } + // FIXME: Use `view` to get a string_view rather than a string copy when moving to C++20 return stringStream.str().substr( std::min(static_cast(stringStream.tellp()), size_t(1))); } @@ -235,7 +239,7 @@ namespace jiminy::python doc, std::pair{"fget", getMemberFuncPtr}, std::pair{"fset", setMemberFuncPtr}); } -// clang-format off + // clang-format off #define DEF_READONLY3(namePy, memberFuncPtr, doc) \ def_readonly(namePy, \ memberFuncPtr, \ @@ -1158,8 +1162,8 @@ namespace jiminy::python }; template - ConvertGeneratorFromPythonAndInvoke(R (*)(Args...)) - -> ConvertGeneratorFromPythonAndInvoke; + ConvertGeneratorFromPythonAndInvoke( + R (*)(Args...)) -> ConvertGeneratorFromPythonAndInvoke; template class ConvertGeneratorFromPythonAndInvoke @@ -1185,8 +1189,8 @@ namespace jiminy::python }; template - ConvertGeneratorFromPythonAndInvoke(R (T::*)(Args...)) - -> ConvertGeneratorFromPythonAndInvoke; + ConvertGeneratorFromPythonAndInvoke( + R (T::*)(Args...)) -> ConvertGeneratorFromPythonAndInvoke; // **************************** Automatic From Python converter **************************** // diff --git a/python/jiminy_pywrap/src/helpers.cc b/python/jiminy_pywrap/src/helpers.cc index 73256b94d6..1d919c89c2 100644 --- a/python/jiminy_pywrap/src/helpers.cc +++ b/python/jiminy_pywrap/src/helpers.cc @@ -68,6 +68,12 @@ namespace jiminy::python return bp::make_tuple(model, collisionModel); } + bp::object saveRobotToBinary(const std::shared_ptr & robot) + { + std::string data = saveToBinary(robot, true); + return bp::object(bp::handle<>(PyBytes_FromStringAndSize(data.c_str(), data.size()))); + } + std::shared_ptr buildRobotFromBinary(const std::string & data, const bp::object & meshPathDirPy, const bp::object & packageDirsPy) @@ -328,10 +334,12 @@ namespace jiminy::python bp::arg("build_visual_model") = false, bp::arg("load_visual_meshes") = false)); - bp::def("build_robot_from_binary", &buildRobotFromBinary, - (bp::arg("data"), - bp::arg("mesh_path_dir") = bp::object(), - bp::arg("mesh_package_dirs") = bp::list())); + bp::def("save_to_binary", &saveRobotToBinary, (bp::arg("robot"))); + + bp::def("load_from_binary", &buildRobotFromBinary, + (bp::arg("data"), + bp::arg("mesh_path_dir") = bp::object(), + bp::arg("mesh_package_dirs") = bp::list())); bp::def("get_joint_type", &getJointTypeFromIndex, (bp::arg("pinocchio_model"), "joint_index"));