Add mjmActuator and mjmSensor.
PiperOrigin-RevId: 605600704 Change-Id: I0a2f5eb9d894c068ca9ee08940c752066021b6ec
This commit is contained in:
committed by
Copybara-Service
parent
e3cbad280c
commit
6fa139a693
@@ -123,6 +123,25 @@ void* mjm_addFrame(mjmBody* bodyspec, void* parentframe) {
|
||||
|
||||
|
||||
|
||||
// add actuator to model
|
||||
mjmActuator* mjm_addActuator(void* model, void* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCActuator* actuator = modelC->AddActuator(def);
|
||||
return &actuator->spec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// add sensor to model
|
||||
mjmSensor* mjm_addSensor(void* model) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCSensor* sensor = modelC->AddSensor();
|
||||
return &sensor->spec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add plugin to model.
|
||||
mjElement mjm_addPlugin(void* model) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
|
||||
@@ -211,6 +211,59 @@ typedef struct _mjmLight {
|
||||
} mjmLight;
|
||||
|
||||
|
||||
typedef struct _mjmActuator {
|
||||
mjElement element; // compiler only, do not modify
|
||||
mjString name; // name
|
||||
mjString classname; // class name
|
||||
mjString info; // message appended to errors
|
||||
int group; // group for visualization
|
||||
int ctrllimited; // are control limits defined: 0 false, 1 true, 2 auto
|
||||
int forcelimited; // are force limits defined: 0 false, 1 true, 2 auto
|
||||
int actlimited; // are activation limits defined: 0 false, 1 true, 2 auto
|
||||
int actdim; // dimension of associated activations
|
||||
int plugin_actdim; // actuator state size for plugins
|
||||
mjtDyn dyntype; // dynamics type
|
||||
mjtTrn trntype; // transmission type
|
||||
mjtGain gaintype; // gain type
|
||||
mjtBias biastype; // bias type
|
||||
double dynprm[mjNDYN]; // dynamics parameters
|
||||
double gainprm[mjNGAIN]; // gain parameters
|
||||
double biasprm[mjNGAIN]; // bias parameters
|
||||
mjtByte actearly; // apply activations to qfrc instantly
|
||||
double ctrlrange[2]; // control range
|
||||
double forcerange[2]; // force range
|
||||
double actrange[2]; // activation range
|
||||
double lengthrange[2]; // length range
|
||||
double gear[6]; // length and transmitted force scaling
|
||||
double cranklength; // crank length, for slider-crank only
|
||||
mjDouble userdata; // user data
|
||||
mjString target; // transmission target name
|
||||
mjString slidersite; // site defining cylinder, for slider-crank only
|
||||
mjString refsite; // reference site, for site transmission only
|
||||
mjmPlugin plugin; // actuator plugin
|
||||
} mjmActuator;
|
||||
|
||||
|
||||
typedef struct _mjmSensor {
|
||||
mjElement element; // compiler only, do not modify
|
||||
mjString name; // name
|
||||
mjString classname; // class name
|
||||
mjString info; // message appended to errors
|
||||
mjtSensor type; // type of sensor
|
||||
mjtDataType datatype; // data type for sensor measurement
|
||||
mjtStage needstage; // compute stage needed to simulate sensor
|
||||
mjtObj objtype; // type of sensorized object
|
||||
mjString objname; // name of sensorized object
|
||||
mjtObj reftype; // type of referenced object
|
||||
mjString refname; // name of referenced object
|
||||
int dim; // number of scalar outputs
|
||||
double cutoff; // cutoff for real and positive datatypes
|
||||
double noise; // noise stdev
|
||||
mjDouble userdata; // user data
|
||||
mjmPlugin plugin; // sensor plugin
|
||||
} mjmSensor;
|
||||
|
||||
|
||||
//---------------------------------- Public API ----------------------------------------------------
|
||||
|
||||
// Create model.
|
||||
@@ -246,6 +299,12 @@ MJAPI mjmLight* mjm_addLight(mjmBody* body, void* defspec);
|
||||
// Add frame to body.
|
||||
MJAPI void* mjm_addFrame(mjmBody* body, void* parentframe);
|
||||
|
||||
// Add actuator to model.
|
||||
MJAPI mjmActuator* mjm_addActuator(void* model, void* defspec);
|
||||
|
||||
// Add sensor to model.
|
||||
MJAPI mjmSensor* mjm_addSensor(void* model);
|
||||
|
||||
// Add plugin to model.
|
||||
MJAPI mjElement mjm_addPlugin(void* model);
|
||||
|
||||
@@ -306,6 +365,12 @@ MJAPI void mjm_defaultCamera(mjmCamera& camera);
|
||||
// Default light attributes.
|
||||
MJAPI void mjm_defaultLight(mjmLight& light);
|
||||
|
||||
// Default actuator attributes.
|
||||
MJAPI void mjm_defaultActuator(mjmActuator& actuator);
|
||||
|
||||
// Default sensor attributes.
|
||||
MJAPI void mjm_defaultSensor(mjmSensor& sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -81,6 +81,8 @@ void mjm_defaultGeom(mjmGeom& geom) {
|
||||
geom.fluid_coefs[2] = 1.5; // angular drag coefficient
|
||||
geom.fluid_coefs[3] = 1.0; // kutta lift coefficient
|
||||
geom.fluid_coefs[4] = 1.0; // magnus lift coefficient
|
||||
geom.plugin.active = false;
|
||||
geom.plugin.instance = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,3 +133,44 @@ void mjm_defaultLight(mjmLight& light) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// default actuator attributes
|
||||
void mjm_defaultActuator(mjmActuator& actuator) {
|
||||
memset(&actuator, 0, sizeof(mjmActuator));
|
||||
actuator.group = 0;
|
||||
actuator.ctrllimited = 2;
|
||||
actuator.forcelimited = 2;
|
||||
actuator.actlimited = 2;
|
||||
actuator.actdim = -1;
|
||||
actuator.plugin_actdim = 0;
|
||||
actuator.trntype = mjTRN_UNDEFINED;
|
||||
actuator.dyntype = mjDYN_NONE;
|
||||
actuator.gaintype = mjGAIN_FIXED;
|
||||
actuator.biastype = mjBIAS_NONE;
|
||||
actuator.actearly = 0;
|
||||
actuator.gear[0] = 1;
|
||||
actuator.dynprm[0] = 1;
|
||||
actuator.gainprm[0] = 1;
|
||||
actuator.cranklength = 0;
|
||||
actuator.plugin.active = false;
|
||||
actuator.plugin.instance = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// default sensor attributes
|
||||
void mjm_defaultSensor(mjmSensor& sensor) {
|
||||
memset(&sensor, 0, sizeof(mjmSensor));
|
||||
sensor.type = mjSENS_TOUCH;
|
||||
sensor.datatype = mjDATATYPE_REAL;
|
||||
sensor.needstage = mjSTAGE_ACC;
|
||||
sensor.objtype = mjOBJ_UNKNOWN;
|
||||
sensor.reftype = mjOBJ_UNKNOWN;
|
||||
sensor.cutoff = 0;
|
||||
sensor.noise = 0;
|
||||
sensor.dim = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2298,7 +2298,7 @@ void mjCModel::CopyObjects(mjModel* m) {
|
||||
copyvec(m->actuator_forcerange + 2*i, pac->forcerange, 2);
|
||||
copyvec(m->actuator_actrange + 2*i, pac->actrange, 2);
|
||||
copyvec(m->actuator_lengthrange + 2*i, pac->lengthrange, 2);
|
||||
copyvec(m->actuator_user+nuser_actuator*i, pac->userdata.data(), nuser_actuator);
|
||||
copyvec(m->actuator_user+nuser_actuator*i, pac->get_userdata().data(), nuser_actuator);
|
||||
}
|
||||
|
||||
// sensors
|
||||
@@ -2318,7 +2318,7 @@ void mjCModel::CopyObjects(mjModel* m) {
|
||||
m->sensor_dim[i] = psen->dim;
|
||||
m->sensor_cutoff[i] = (mjtNum)psen->cutoff;
|
||||
m->sensor_noise[i] = (mjtNum)psen->noise;
|
||||
copyvec(m->sensor_user+nuser_sensor*i, psen->userdata.data(), nuser_sensor);
|
||||
copyvec(m->sensor_user+nuser_sensor*i, psen->get_userdata().data(), nuser_sensor);
|
||||
|
||||
// calculate address and advance
|
||||
m->sensor_adr[i] = adr;
|
||||
@@ -2920,13 +2920,13 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
if (nuser_actuator == -1) {
|
||||
nuser_actuator = 0;
|
||||
for (int i=0; i<actuators.size(); i++) {
|
||||
nuser_actuator = mjMAX(nuser_actuator, actuators[i]->userdata.size());
|
||||
nuser_actuator = mjMAX(nuser_actuator, actuators[i]->spec_userdata_.size());
|
||||
}
|
||||
}
|
||||
if (nuser_sensor == -1) {
|
||||
nuser_sensor = 0;
|
||||
for (int i=0; i<sensors.size(); i++) {
|
||||
nuser_sensor = mjMAX(nuser_sensor, sensors[i]->userdata.size());
|
||||
nuser_sensor = mjMAX(nuser_sensor, sensors[i]->spec_userdata_.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3500,7 +3500,7 @@ bool mjCModel::CopyBack(const mjModel* m) {
|
||||
pa->cranklength = (double)m->actuator_cranklength[i];
|
||||
|
||||
if (nuser_actuator) {
|
||||
copyvec(pa->userdata.data(), m->actuator_user + nuser_actuator*i, nuser_actuator);
|
||||
copyvec(pa->userdata_.data(), m->actuator_user + nuser_actuator*i, nuser_actuator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3510,7 +3510,7 @@ bool mjCModel::CopyBack(const mjModel* m) {
|
||||
sensors[i]->noise = (double)m->sensor_noise[i];
|
||||
|
||||
if (nuser_sensor) {
|
||||
copyvec(sensors[i]->userdata.data(), m->sensor_user + nuser_sensor*i, nuser_sensor);
|
||||
copyvec(sensors[i]->userdata_.data(), m->sensor_user + nuser_sensor*i, nuser_sensor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+109
-69
@@ -475,7 +475,7 @@ void mjCDef::Compile(const mjCModel* model) {
|
||||
site.userdata_.resize(model->nuser_site);
|
||||
camera.userdata_.resize(model->nuser_cam);
|
||||
tendon.userdata.resize(model->nuser_tendon);
|
||||
actuator.userdata.resize(model->nuser_actuator);
|
||||
actuator.userdata_.resize(model->nuser_actuator);
|
||||
}
|
||||
|
||||
|
||||
@@ -3963,35 +3963,13 @@ void mjCWrap::Compile(void) {
|
||||
|
||||
// initialize defaults
|
||||
mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
|
||||
// actuator defaults
|
||||
group = 0;
|
||||
ctrllimited = 2;
|
||||
forcelimited = 2;
|
||||
actlimited = 2;
|
||||
actdim = -1;
|
||||
plugin_actdim = 0;
|
||||
trntype = mjTRN_UNDEFINED;
|
||||
dyntype = mjDYN_NONE;
|
||||
gaintype = mjGAIN_FIXED;
|
||||
biastype = mjBIAS_NONE;
|
||||
mjuu_zerovec(dynprm, mjNDYN);
|
||||
mjuu_zerovec(gainprm, mjNGAIN);
|
||||
mjuu_zerovec(biasprm, mjNBIAS);
|
||||
mjuu_zerovec(ctrlrange, 2);
|
||||
mjuu_zerovec(forcerange, 2);
|
||||
mjuu_zerovec(actrange, 2);
|
||||
mjuu_zerovec(lengthrange, 2);
|
||||
mjuu_zerovec(gear, 6);
|
||||
gear[0] = 1;
|
||||
dynprm[0] = 1;
|
||||
gainprm[0] = 1;
|
||||
cranklength = 0;
|
||||
target.clear();
|
||||
slidersite.clear();
|
||||
refsite.clear();
|
||||
userdata.clear();
|
||||
mjm_defaultActuator(spec);
|
||||
|
||||
// clear private variables
|
||||
spec_target_.clear();
|
||||
spec_slidersite_.clear();
|
||||
spec_refsite_.clear();
|
||||
spec_userdata_.clear();
|
||||
trnid[0] = trnid[1] = -1;
|
||||
|
||||
// reset to default if given
|
||||
@@ -4003,23 +3981,59 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
|
||||
model = _model;
|
||||
def = (_def ? _def : (_model ? _model->defaults[0] : 0));
|
||||
|
||||
// in case this actuator is not compiled
|
||||
CopyFromSpec();
|
||||
|
||||
// point to local (needs to be after defaults)
|
||||
plugin.name = (mjString)&plugin_name;
|
||||
plugin.instance_name = (mjString)&plugin_instance_name;
|
||||
MakePointerLocal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mjCActuator::MakePointerLocal() {
|
||||
spec.element = (mjElement)this;
|
||||
spec.name = (mjString)&name;
|
||||
spec.classname = (mjString)&classname;
|
||||
spec.userdata = (mjDouble)&spec_userdata_;
|
||||
spec.target = (mjString)&spec_target_;
|
||||
spec.refsite = (mjString)&spec_refsite_;
|
||||
spec.slidersite = (mjString)&spec_slidersite_;
|
||||
spec.plugin.name = (mjString)&plugin_name;
|
||||
spec.plugin.instance_name = (mjString)&plugin_instance_name;
|
||||
spec.info = (mjString)&info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mjCActuator::CopyFromSpec() {
|
||||
*static_cast<mjmActuator*>(this) = spec;
|
||||
userdata_ = spec_userdata_;
|
||||
target_ = spec_target_;
|
||||
refsite_ = spec_refsite_;
|
||||
slidersite_ = spec_slidersite_;
|
||||
userdata = (mjDouble)&userdata_;
|
||||
target = (mjString)&target_;
|
||||
refsite = (mjString)&refsite_;
|
||||
slidersite = (mjString)&slidersite_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.name = spec.plugin.name;
|
||||
plugin.instance_name = spec.plugin.instance_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// compiler
|
||||
void mjCActuator::Compile(void) {
|
||||
CopyFromSpec();
|
||||
mjCJoint* pjnt;
|
||||
|
||||
// resize userdata
|
||||
if (userdata.size() > model->nuser_actuator) {
|
||||
if (userdata_.size() > model->nuser_actuator) {
|
||||
throw mjCError(this, "user has more values than nuser_actuator in actuator '%s' (id = %d)",
|
||||
name.c_str(), id);
|
||||
}
|
||||
userdata.resize(model->nuser_actuator);
|
||||
userdata_.resize(model->nuser_actuator);
|
||||
|
||||
// if limited is auto, set to 1 if range is specified, otherwise unlimited
|
||||
if (forcelimited==2) {
|
||||
@@ -4104,7 +4118,7 @@ void mjCActuator::Compile(void) {
|
||||
}
|
||||
|
||||
// check for missing target name
|
||||
if (target.empty()) {
|
||||
if (target_.empty()) {
|
||||
throw mjCError(this,
|
||||
"missing transmission target for actuator '%s' (id = %d)", name.c_str(), id);
|
||||
}
|
||||
@@ -4115,10 +4129,10 @@ void mjCActuator::Compile(void) {
|
||||
case mjTRN_JOINT:
|
||||
case mjTRN_JOINTINPARENT:
|
||||
// get joint
|
||||
ptarget = model->FindObject(mjOBJ_JOINT, target);
|
||||
ptarget = model->FindObject(mjOBJ_JOINT, target_);
|
||||
if (!ptarget) {
|
||||
throw mjCError(this,
|
||||
"unknown transmission target '%s' for actuator id = %d", target.c_str(), id);
|
||||
"unknown transmission target '%s' for actuator id = %d", target_.c_str(), id);
|
||||
}
|
||||
pjnt = (mjCJoint*) ptarget;
|
||||
|
||||
@@ -4132,12 +4146,12 @@ void mjCActuator::Compile(void) {
|
||||
|
||||
case mjTRN_SLIDERCRANK:
|
||||
// get slidersite, copy in trnid[1]
|
||||
if (slidersite.empty()) {
|
||||
if (slidersite_.empty()) {
|
||||
throw mjCError(this, "missing base site for slider-crank '%s' (id = %d)", name.c_str(), id);
|
||||
}
|
||||
ptarget = model->FindObject(mjOBJ_SITE, slidersite);
|
||||
ptarget = model->FindObject(mjOBJ_SITE, slidersite_);
|
||||
if (!ptarget) {
|
||||
throw mjCError(this, "base site '%s' not found for actuator %d", slidersite.c_str(), id);
|
||||
throw mjCError(this, "base site '%s' not found for actuator %d", slidersite_.c_str(), id);
|
||||
}
|
||||
trnid[1] = ptarget->id;
|
||||
|
||||
@@ -4148,31 +4162,31 @@ void mjCActuator::Compile(void) {
|
||||
}
|
||||
|
||||
// proceed with regular target
|
||||
ptarget = model->FindObject(mjOBJ_SITE, target);
|
||||
ptarget = model->FindObject(mjOBJ_SITE, target_);
|
||||
break;
|
||||
|
||||
case mjTRN_TENDON:
|
||||
// get tendon
|
||||
ptarget = model->FindObject(mjOBJ_TENDON, target);
|
||||
ptarget = model->FindObject(mjOBJ_TENDON, target_);
|
||||
break;
|
||||
|
||||
case mjTRN_SITE:
|
||||
// get refsite, copy into trnid[1]
|
||||
if (!refsite.empty()) {
|
||||
ptarget = model->FindObject(mjOBJ_SITE, refsite);
|
||||
if (!refsite_.empty()) {
|
||||
ptarget = model->FindObject(mjOBJ_SITE, refsite_);
|
||||
if (!ptarget) {
|
||||
throw mjCError(this, "reference site '%s' not found for actuator %d", refsite.c_str(), id);
|
||||
throw mjCError(this, "reference site '%s' not found for actuator %d", refsite_.c_str(), id);
|
||||
}
|
||||
trnid[1] = ptarget->id;
|
||||
}
|
||||
|
||||
// proceed with regular site target
|
||||
ptarget = model->FindObject(mjOBJ_SITE, target);
|
||||
ptarget = model->FindObject(mjOBJ_SITE, target_);
|
||||
break;
|
||||
|
||||
case mjTRN_BODY:
|
||||
// get body
|
||||
ptarget = model->FindObject(mjOBJ_BODY, target);
|
||||
ptarget = model->FindObject(mjOBJ_BODY, target_);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4181,7 +4195,7 @@ void mjCActuator::Compile(void) {
|
||||
|
||||
// assign and check
|
||||
if (!ptarget) {
|
||||
throw mjCError(this, "transmission target '%s' not found in actuator %d", target.c_str(), id);
|
||||
throw mjCError(this, "transmission target '%s' not found in actuator %d", target_.c_str(), id);
|
||||
} else {
|
||||
trnid[0] = ptarget->id;
|
||||
}
|
||||
@@ -4209,41 +4223,67 @@ void mjCActuator::Compile(void) {
|
||||
|
||||
// initialize defaults
|
||||
mjCSensor::mjCSensor(mjCModel* _model) {
|
||||
mjm_defaultSensor(spec);
|
||||
|
||||
// set model
|
||||
model = _model;
|
||||
|
||||
// set sensor defaults (somewhat arbitrary)
|
||||
type = mjSENS_TOUCH;
|
||||
datatype = mjDATATYPE_REAL;
|
||||
needstage = mjSTAGE_ACC;
|
||||
objtype = mjOBJ_UNKNOWN;
|
||||
objname.clear();
|
||||
reftype = mjOBJ_UNKNOWN;
|
||||
refname.clear();
|
||||
cutoff = 0;
|
||||
noise = 0;
|
||||
userdata.clear();
|
||||
dim = 0;
|
||||
|
||||
// clear private variables
|
||||
spec_objname_.clear();
|
||||
spec_refname_.clear();
|
||||
spec_userdata_.clear();
|
||||
obj = nullptr;
|
||||
refid = -1;
|
||||
|
||||
// point to local (needs to be after defaults)
|
||||
plugin.name = (mjString)&plugin_name;
|
||||
plugin.instance_name = (mjString)&plugin_instance_name;
|
||||
// in case this sensor is not compiled
|
||||
CopyFromSpec();
|
||||
|
||||
// point to local
|
||||
MakePointerLocal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mjCSensor::MakePointerLocal() {
|
||||
spec.element = (mjElement)this;
|
||||
spec.name = (mjString)&name;
|
||||
spec.classname = (mjString)&classname;
|
||||
spec.userdata = (mjDouble)&spec_userdata_;
|
||||
spec.objname = (mjString)&spec_objname_;
|
||||
spec.refname = (mjString)&spec_refname_;
|
||||
spec.plugin.name = (mjString)&plugin_name;
|
||||
spec.plugin.instance_name = (mjString)&plugin_instance_name;
|
||||
spec.info = (mjString)&info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mjCSensor::CopyFromSpec() {
|
||||
*static_cast<mjmSensor*>(this) = spec;
|
||||
userdata_ = spec_userdata_;
|
||||
objname_ = spec_objname_;
|
||||
refname_ = spec_refname_;
|
||||
userdata = (mjDouble)&userdata_;
|
||||
objname = (mjString)&objname_;
|
||||
refname = (mjString)&refname_;
|
||||
plugin.active = spec.plugin.active;
|
||||
plugin.instance = spec.plugin.instance;
|
||||
plugin.name = spec.plugin.name;
|
||||
plugin.instance_name = spec.plugin.instance_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// compiler
|
||||
void mjCSensor::Compile(void) {
|
||||
CopyFromSpec();
|
||||
|
||||
// resize userdata
|
||||
if (userdata.size() > model->nuser_sensor) {
|
||||
if (userdata_.size() > model->nuser_sensor) {
|
||||
throw mjCError(this, "user has more values than nuser_sensor in sensor '%s' (id = %d)",
|
||||
name.c_str(), id);
|
||||
}
|
||||
userdata.resize(model->nuser_sensor);
|
||||
userdata_.resize(model->nuser_sensor);
|
||||
|
||||
// require non-negative noise
|
||||
if (noise<0) {
|
||||
@@ -4258,14 +4298,14 @@ void mjCSensor::Compile(void) {
|
||||
// get objid from objtype and objname
|
||||
if (objtype!=mjOBJ_UNKNOWN) {
|
||||
// check for missing object name
|
||||
if (objname.empty()) {
|
||||
if (objname_.empty()) {
|
||||
throw mjCError(this,
|
||||
"missing name of sensorized object in sensor '%s' (id = %d)",
|
||||
name.c_str(), id);
|
||||
}
|
||||
|
||||
// find name
|
||||
obj = model->FindObject(objtype, objname);
|
||||
obj = model->FindObject(objtype, objname_);
|
||||
if (!obj) {
|
||||
throw mjCError(this,
|
||||
"unrecognized name of sensorized object in sensor '%s' (id = %d)",
|
||||
@@ -4285,14 +4325,14 @@ void mjCSensor::Compile(void) {
|
||||
// get refid from reftype and refname
|
||||
if (reftype!=mjOBJ_UNKNOWN) {
|
||||
// check for missing object name
|
||||
if (refname.empty()) {
|
||||
if (refname_.empty()) {
|
||||
throw mjCError(this,
|
||||
"missing name of reference frame object in sensor '%s' (id = %d)",
|
||||
name.c_str(), id);
|
||||
}
|
||||
|
||||
// find name
|
||||
mjCBase* pref = model->FindObject(reftype, refname);
|
||||
mjCBase* pref = model->FindObject(reftype, refname_);
|
||||
if (!pref) {
|
||||
throw mjCError(this,
|
||||
"unrecognized name of reference frame object in sensor '%s' (id = %d)",
|
||||
@@ -4351,7 +4391,7 @@ void mjCSensor::Compile(void) {
|
||||
|
||||
// check for camera resolution for camera projection sensor
|
||||
if (type==mjSENS_CAMPROJECTION) {
|
||||
mjCCamera* camref = (mjCCamera*) model->FindObject(mjOBJ_CAMERA, refname);
|
||||
mjCCamera* camref = (mjCCamera*) model->FindObject(mjOBJ_CAMERA, refname_);
|
||||
if (!camref->resolution[0] || !camref->resolution[1]) {
|
||||
throw mjCError(this,
|
||||
"camera projection sensor requires camera resolution '%s' (id = %d)",
|
||||
|
||||
+45
-39
@@ -1141,43 +1141,41 @@ class mjCPlugin : public mjCBase {
|
||||
//------------------------- class mjCActuator ------------------------------------------------------
|
||||
// Describes an actuator
|
||||
|
||||
class mjCActuator : public mjCBase {
|
||||
class mjCActuator : public mjCBase, private mjmActuator {
|
||||
friend class mjCDef;
|
||||
friend class mjCModel;
|
||||
friend class mjXWriter;
|
||||
|
||||
public:
|
||||
// variables set by user or API
|
||||
int group; // group for visualization
|
||||
int ctrllimited; // are control limits defined: 0 false, 1 true, 2 auto
|
||||
int forcelimited; // are force limits defined: 0 false, 1 true, 2 auto
|
||||
int actlimited; // are activation limits defined: 0 false, 1 true, 2 auto
|
||||
int actdim; // dimension of associated activations
|
||||
int plugin_actdim; // actuator state size for plugins
|
||||
mjtDyn dyntype; // dynamics type
|
||||
mjtTrn trntype; // transmission type
|
||||
mjtGain gaintype; // gain type
|
||||
mjtBias biastype; // bias type
|
||||
double dynprm[mjNDYN]; // dynamics parameters
|
||||
double gainprm[mjNGAIN]; // gain parameters
|
||||
double biasprm[mjNGAIN]; // bias parameters
|
||||
bool actearly = false; // apply activations to qfrc instantly
|
||||
double ctrlrange[2]; // control range
|
||||
double forcerange[2]; // force range
|
||||
double actrange[2]; // activation range
|
||||
double lengthrange[2]; // length range
|
||||
double gear[6]; // length and transmitted force scaling
|
||||
double cranklength; // crank length, for slider-crank only
|
||||
std::vector<double> userdata; // user data
|
||||
std::string target; // transmission target name
|
||||
std::string slidersite; // site defining cylinder, for slider-crank only
|
||||
std::string refsite; // reference site, for site transmission only
|
||||
mjmActuator spec;
|
||||
using mjCBase::name;
|
||||
using mjCBase::classname;
|
||||
using mjCBase::info;
|
||||
using mjCBase::plugin;
|
||||
|
||||
// used by mjXWriter and mjCModel
|
||||
const std::vector<double>& get_userdata() { return userdata_; }
|
||||
const std::string& get_target() { return spec_target_; }
|
||||
const std::string& get_slidersite() { return spec_slidersite_; }
|
||||
const std::string& get_refsite() { return spec_refsite_; }
|
||||
|
||||
private:
|
||||
mjCActuator(mjCModel* = 0, mjCDef* = 0); // constructor
|
||||
void Compile(void); // compiler
|
||||
void CopyFromSpec();
|
||||
void MakePointerLocal();
|
||||
|
||||
int trnid[2]; // id of transmission target
|
||||
|
||||
// variable-size data
|
||||
std::string target_;
|
||||
std::string slidersite_;
|
||||
std::string refsite_;
|
||||
std::vector<double> userdata_;
|
||||
std::string spec_target_;
|
||||
std::string spec_slidersite_;
|
||||
std::string spec_refsite_;
|
||||
std::vector<double> spec_userdata_;
|
||||
};
|
||||
|
||||
|
||||
@@ -1185,31 +1183,39 @@ class mjCActuator : public mjCBase {
|
||||
//------------------------- class mjCSensor --------------------------------------------------------
|
||||
// Describes a sensor
|
||||
|
||||
class mjCSensor : public mjCBase {
|
||||
class mjCSensor : public mjCBase, private mjmSensor {
|
||||
friend class mjCDef;
|
||||
friend class mjCModel;
|
||||
friend class mjXWriter;
|
||||
|
||||
public:
|
||||
// variables set by user or API
|
||||
mjtSensor type; // type of sensor
|
||||
mjtDataType datatype; // data type for sensor measurement
|
||||
mjtStage needstage; // compute stage needed to simulate sensor
|
||||
mjtObj objtype; // type of sensorized object
|
||||
std::string objname; // name of sensorized object
|
||||
mjtObj reftype;
|
||||
std::string refname;
|
||||
int dim; // number of scalar outputs
|
||||
double cutoff; // cutoff for real and positive datatypes
|
||||
double noise; // noise stdev
|
||||
std::vector<double> userdata; // user data
|
||||
mjmSensor spec;
|
||||
using mjCBase::name;
|
||||
using mjCBase::classname;
|
||||
using mjCBase::info;
|
||||
using mjCBase::plugin;
|
||||
|
||||
// used by mjXWriter and mjCModel
|
||||
const std::vector<double>& get_userdata() { return userdata_; }
|
||||
const std::string& get_objname() { return spec_objname_; }
|
||||
const std::string& get_refname() { return spec_refname_; }
|
||||
|
||||
private:
|
||||
mjCSensor(mjCModel*); // constructor
|
||||
void Compile(void); // compiler
|
||||
void CopyFromSpec();
|
||||
void MakePointerLocal();
|
||||
|
||||
mjCBase* obj; // sensorized object
|
||||
int refid; // id of reference frame
|
||||
|
||||
// variable-size data
|
||||
std::string objname_;
|
||||
std::string refname_;
|
||||
std::vector<double> userdata_;
|
||||
std::string spec_objname_;
|
||||
std::string spec_refname_;
|
||||
std::vector<double> spec_userdata_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user