Implement plugin mechanism for actuators and sensors.
PiperOrigin-RevId: 474874088 Change-Id: I65a8ffdf845f4fa0f8266c165883a747ab5812d8
This commit is contained in:
committed by
Copybara-Service
parent
f556d4d94f
commit
1e2a9a53bc
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_
|
||||
@@ -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 ) \
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user