Implement plugin mechanism for actuators and sensors.

PiperOrigin-RevId: 474874088
Change-Id: I65a8ffdf845f4fa0f8266c165883a747ab5812d8
This commit is contained in:
Saran Tunyasuvunakool
2022-09-16 12:20:56 -07:00
committed by Copybara-Service
parent f556d4d94f
commit 1e2a9a53bc
29 changed files with 2121 additions and 51 deletions
+8
View File
@@ -15,6 +15,8 @@
#ifndef MUJOCO_MJDATA_H_
#define MUJOCO_MJDATA_H_
#include <stdint.h>
#include <mujoco/mjtnum.h>
#include <mujoco/mjmodel.h>
@@ -124,6 +126,7 @@ struct mjData_ {
// constant sizes
int nstack; // number of mjtNums that can fit in stack
int nbuffer; // size of main buffer in bytes
int nplugin; // number of plugin instances
// stack pointer
int pstack; // first available mjtNum address in stack
@@ -164,6 +167,7 @@ struct mjData_ {
mjtNum* qvel; // velocity (nv x 1)
mjtNum* act; // actuator activation (na x 1)
mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1)
mjtNum* plugin_state; // plugin state (npluginstate x 1)
// control
mjtNum* ctrl; // control (nu x 1)
@@ -184,6 +188,10 @@ struct mjData_ {
// sensors
mjtNum* sensordata; // sensor data array (nsensordata x 1)
// plugins
int* plugin; // copy of m->plugin, required for deletion (nplugin x 1)
uintptr_t* plugin_data; // pointer to plugin-managed data structure (nplugin x 1)
//-------------------------------- POSITION dependent
// computed by mj_fwdPosition/mj_kinematics
+17 -1
View File
@@ -239,7 +239,8 @@ typedef enum mjtObj_ { // type of MujoCo object
mjOBJ_NUMERIC, // numeric
mjOBJ_TEXT, // text
mjOBJ_TUPLE, // tuple
mjOBJ_KEY // keyframe
mjOBJ_KEY, // keyframe
mjOBJ_PLUGIN // plugin instance
} mjtObj;
@@ -315,6 +316,9 @@ typedef enum mjtSensor_ { // type of sensor
// global sensors
mjSENS_CLOCK, // simulation time
// plugin-controlled sensors
mjSENS_PLUGIN, // plugin-controlled
// user-defined sensor
mjSENS_USER // sensor data provided by mjcb_sensor callback
} mjtSensor;
@@ -565,6 +569,8 @@ struct mjModel_ {
int ntupledata; // number of objects in all tuple fields
int nkey; // number of keyframes
int nmocap; // number of mocap bodies
int nplugin; // number of plugin instances
int npluginattr; // number of chars in all plugin config attributes
int nuser_body; // number of mjtNums in body_user
int nuser_jnt; // number of mjtNums in jnt_user
int nuser_geom; // number of mjtNums in geom_user
@@ -584,6 +590,7 @@ struct mjModel_ {
int nstack; // number of fields in mjData stack
int nuserdata; // number of extra fields in mjData
int nsensordata; // number of fields in sensor data vector
int npluginstate; // number of fields in the plugin state vector
int nbuffer; // number of bytes in buffer
@@ -856,6 +863,7 @@ struct mjModel_ {
mjtNum* actuator_length0; // actuator length in qpos0 (nu x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nu x 2)
mjtNum* actuator_user; // user data (nu x nuser_actuator)
int* actuator_plugin; // plugin instance id; -1: not a plugin actuator (nu x 1)
// sensors
int* sensor_type; // sensor type (mjtSensor) (nsensor x 1)
@@ -870,6 +878,13 @@ struct mjModel_ {
mjtNum* sensor_cutoff; // cutoff for real and positive; 0: ignore (nsensor x 1)
mjtNum* sensor_noise; // noise standard deviation (nsensor x 1)
mjtNum* sensor_user; // user data (nsensor x nuser_sensor)
int* sensor_plugin; // plugin instance id; -1: not a plugin sensor (nsensor x 1)
// plugin instances
int* plugin; // globally registered plugin slot number (nplugin x 1)
int* plugin_stateadr; // address in the plugin state array (nplugin x 1)
char* plugin_attr; // config attributes of plugin instances (npluginattr x 1)
int* plugin_attradr; // address to each instance's config attrib (nplugin x 1)
// custom numeric fields
int* numeric_adr; // address of field in numeric_data (nnumeric x 1)
@@ -919,6 +934,7 @@ struct mjModel_ {
int* name_textadr; // text name pointers (ntext x 1)
int* name_tupleadr; // tuple name pointers (ntuple x 1)
int* name_keyadr; // keyframe name pointers (nkey x 1)
int* name_pluginadr; // plugin instance name pointers (nplugin x 1)
char* names; // names of all objects, 0-terminated (nnames x 1)
};
typedef struct mjModel_ mjModel;
+61
View File
@@ -0,0 +1,61 @@
// Copyright 2022 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_INCLUDE_MJPLUGIN_H_
#define MUJOCO_INCLUDE_MJPLUGIN_H_
#include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h>
typedef enum mjtPluginTypeBit_ {
mjPLUGIN_ACTUATOR = 1<<0,
mjPLUGIN_SENSOR = 1<<1
} mjtPluginTypeBit;
struct mjpPlugin_ {
const char* name; // globally unique name identifying the plugin
int nattribute; // number of configuration attributes
const char* const* attributes; // name of configuration attributes
int type; // bitfield of mjtPluginTypeBits specifying the plugin type
int needstage; // an mjtStage enum value specifying the sensor computation stage
// number of mjtNums needed to store the state of a plugin instance (required)
int (*nstate)(const mjModel* m, int instance);
// dimension of the specified sensor's output (required only for sensor plugins)
int (*nsensordata)(const mjModel* m, int instance, int sensor_id);
// called when a new mjData is being created (required)
void (*init)(const mjModel* m, mjData* d, int instance);
// called when an mjData is being freed (optional)
void (*destroy)(mjData* d, int instance);
// called when an mjData is being copied (optional)
void (*copy)(mjData* dest, const mjModel* m, const mjData* src, int instance);
// called when an mjData is being reset (required)
void (*reset)(const mjModel* m, mjData* d, int instance);
// called when the plugin needs to update its outputs (required)
void (*compute)(const mjModel* m, mjData* d, int instance, int type);
// called when time integration occurs (optional)
void (*advance)(const mjModel* m, mjData* d, int instance);
};
typedef struct mjpPlugin_ mjpPlugin;
#endif // MUJOCO_INCLUDE_MJPLUGIN_H_
+13 -1
View File
@@ -102,6 +102,8 @@
X( ntupledata ) \
X( nkey ) \
X( nmocap ) \
X( nplugin ) \
X( npluginattr ) \
X( nuser_body ) \
X( nuser_jnt ) \
X( nuser_geom ) \
@@ -119,6 +121,7 @@
X( nstack ) \
X( nuserdata ) \
X( nsensordata ) \
X( npluginstate ) \
X( nbuffer )
@@ -138,7 +141,6 @@
int nu = m->nu; \
int nmocap = m->nmocap;
// macro for annotating that an array size in an X macro is a member of mjModel
// by default this macro does nothing, but users can redefine it as necessary
#define MJ_M(n) n
@@ -367,6 +369,7 @@
X( mjtNum, actuator_length0, nu, 1 ) \
X( mjtNum, actuator_lengthrange, nu, 2 ) \
X( mjtNum, actuator_user, nu, MJ_M(nuser_actuator) ) \
X( int, actuator_plugin, nu, 1 ) \
X( int, sensor_type, nsensor, 1 ) \
X( int, sensor_datatype, nsensor, 1 ) \
X( int, sensor_needstage, nsensor, 1 ) \
@@ -379,6 +382,11 @@
X( mjtNum, sensor_cutoff, nsensor, 1 ) \
X( mjtNum, sensor_noise, nsensor, 1 ) \
X( mjtNum, sensor_user, nsensor, MJ_M(nuser_sensor) ) \
X( int, sensor_plugin, nsensor, 1 ) \
X( int, plugin, nplugin, 1 ) \
X( int, plugin_stateadr, nplugin, 1 ) \
X( char, plugin_attr, npluginattr, 1 ) \
X( int, plugin_attradr, nplugin, 1 ) \
X( int, numeric_adr, nnumeric, 1 ) \
X( int, numeric_size, nnumeric, 1 ) \
X( mjtNum, numeric_data, nnumericdata, 1 ) \
@@ -418,6 +426,7 @@
X( int, name_textadr, ntext, 1 ) \
X( int, name_tupleadr, ntuple, 1 ) \
X( int, name_keyadr, nkey, 1 ) \
X( int, name_pluginadr, nplugin, 1 ) \
X( char, names, nnames, 1 )
@@ -435,6 +444,7 @@
X( mjtNum, qvel, nv, 1 ) \
X( mjtNum, act, na, 1 ) \
X( mjtNum, qacc_warmstart, nv, 1 ) \
X( mjtNum, plugin_state, npluginstate, 1 ) \
X( mjtNum, ctrl, nu, 1 ) \
X( mjtNum, qfrc_applied, nv, 1 ) \
X( mjtNum, xfrc_applied, nbody, 6 ) \
@@ -444,6 +454,8 @@
X( mjtNum, act_dot, na, 1 ) \
X( mjtNum, userdata, nuserdata, 1 ) \
X( mjtNum, sensordata, nsensordata, 1 ) \
X( int, plugin, nplugin, 1 ) \
X( uintptr_t, plugin_data, nplugin, 1 ) \
X( mjtNum, xpos, nbody, 3 ) \
X( mjtNum, xquat, nbody, 4 ) \
X( mjtNum, xmat, nbody, 9 ) \
+28
View File
@@ -34,6 +34,7 @@ extern "C" {
// type definitions
#include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h>
#include <mujoco/mjplugin.h>
#include <mujoco/mjrender.h>
#include <mujoco/mjtnum.h>
#include <mujoco/mjui.h>
@@ -453,6 +454,10 @@ MJAPI mjtNum mj_getTotalmass(const mjModel* m);
// Scale body masses and inertias to achieve specified total mass.
MJAPI void mj_setTotalmass(mjModel* m, mjtNum newmass);
// Return a config attribute value of a plugin instance;
// NULL: invalid plugin instance ID or attribute name
MJAPI const char* mj_getPluginConfig(const mjModel* m, int plugin_id, const char* attrib);
// Return version number: 1.0.2 is encoded as 102.
MJAPI int mj_version(void);
@@ -1135,6 +1140,29 @@ MJAPI void mjd_transitionFD(const mjModel* m, mjData* d, mjtNum eps, mjtByte cen
//---------------------- Plugins -------------------------------------------------------------------
// Set default plugin definition.
MJAPI void mjp_defaultPlugin(mjpPlugin* plugin);
// Globally register a plugin. This function is thread-safe.
// If an identical mjpPlugin is already registered, this function does nothing.
// If a non-identical mjpPlugin with the same name is already registered, an mju_error is raised.
// Two mjpPlugins are considered identical if all member function pointers and numbers are equal,
// and the name and attribute strings are all identical, however the char pointers to the strings
// need not be the same.
MJAPI int mjp_registerPlugin(const mjpPlugin* plugin);
// Return the number of globally registered plugins.
MJAPI int mjp_pluginCount();
// Look up a plugin by name. If slot is not NULL, also write its registered slot number into it.
MJAPI const mjpPlugin* mjp_getPlugin(const char* name, int* slot);
// Look up a plugin by the registered slot number that was returned by mjp_registerPlugin.
MJAPI const mjpPlugin* mjp_getPluginAtSlot(int slot);
#if defined(__cplusplus)
}
#endif