Add compiler C API for mjmSite.

PiperOrigin-RevId: 604573450
Change-Id: I6ba7fcece0942ddc0d109413ba5684b2df3fab96
This commit is contained in:
Alessio Quaglino
2024-02-06 01:50:01 -08:00
committed by Copybara-Service
parent f763254a00
commit 3b2dd06c54
13 changed files with 342 additions and 73 deletions
+2
View File
@@ -13,6 +13,8 @@
# limitations under the License.
set(MUJOCO_USER_SRCS
user_api.cc
user_api.h
user_composite.cc
user_composite.h
user_flexcomp.cc
+110
View File
@@ -0,0 +1,110 @@
// Copyright 2021 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.
#include "user/user_api.h"
#include <string>
#include <vector>
#include <mujoco/mujoco.h>
#include "user/user_model.h"
#include "user/user_objects.h"
// create model
void* mjm_createModel() {
mjCModel* modelC = new mjCModel();
return modelC;
}
// delete model
void mjm_deleteModel(void* model) {
mjCModel* modelC = static_cast<mjCModel*>(model);
delete modelC;
}
// add body to body
void* mjm_addBody(void* body, void* def) {
mjCDef* defC = static_cast<mjCDef*>(def);
mjCBody* bodyC = static_cast<mjCBody*>(body);
return bodyC->AddBody(defC);
}
// add site to body
mjmSite* mjm_addSite(void* body, void* def) {
mjCDef* defC = static_cast<mjCDef*>(def);
mjCSite* siteC = static_cast<mjCBody*>(body)->AddSite(defC);
return &siteC->spec;
}
// get object of given type
void* mjm_findObject(void* model, mjtObj type, const char* name) {
mjCModel* modelC = static_cast<mjCModel*>(model);
return modelC->FindObject(type, std::string(name));
}
// set parent frame of dest
void mjm_setFrame(void* dest, void* frame) {
mjCFrame* frameC = static_cast<mjCFrame*>(frame);
mjCBase* baseC = static_cast<mjCBase*>(dest);
baseC->SetFrame(frameC);
}
// set string
void mjm_setString(mjString dest, const char* text) {
std::string* str = reinterpret_cast<std::string*>(dest);
*str = std::string(text);
}
// set double array
void mjm_setDouble(mjDouble dest, const double* array, int size) {
std::vector<double>* v = reinterpret_cast<std::vector<double>*>(dest);
v->assign(size, 0.0);
for (int i = 0; i < size; ++i) {
(*v)[i] = array[i];
}
}
// get string
const char* mjm_getString(const mjString source) {
std::string* str = reinterpret_cast<std::string*>(source);
return str->c_str();
}
// get double array
const double* mjm_getDouble(const mjDouble source, int* size) {
std::vector<double>* v = reinterpret_cast<std::vector<double>*>(source);
if (size) {
*size = v->size();
}
return v->data();
}
+92
View File
@@ -0,0 +1,92 @@
// Copyright 2021 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_SRC_USER_USER_API_H_
#define MUJOCO_SRC_USER_USER_API_H_
#include <mujoco/mjexport.h>
#include <mujoco/mjmodel.h>
typedef struct _mjString* mjString;
typedef struct _mjDouble* mjDouble;
typedef struct _mjElement* mjElement;
//---------------------------------- Public structs ------------------------------------------------
typedef struct _mjmOrientation {
double axisangle[4]; // rotation axis and angle
double xyaxes[6]; // x and y axes
double zaxis[3]; // z axis (use minimal rotation)
double euler[3]; // euler rotations
double fullinertia[6]; // non-axis-aligned inertia matrix
} mjmOrientation;
typedef struct _mjmSite {
mjElement element; // only used internally, do not modify
mjString name; // name
mjString classname; // class name
mjString info; // message appended to errors
mjtGeom type; // geom type for rendering
int group; // group id, used for visualization
double size[3]; // geom size for rendering
double pos[3]; // position
double quat[4]; // orientation
mjString material; // name of material for rendering
mjDouble userdata; // user data
float rgba[4]; // rgba when material is omitted
double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid
mjmOrientation alt; // alternative orientation specification
} mjmSite;
//---------------------------------- Public API ----------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
// Create model.
MJAPI void* mjm_createModel();
// Delete model.
MJAPI void mjm_deleteModel(void* model);
// Add body to body.
MJAPI void* mjm_addBody(void* body, void* def);
// Add site to body.
MJAPI mjmSite* mjm_addSite(void* body, void* def);
// Find object of given type.
MJAPI void* mjm_findObject(void* model, mjtObj type, const char* name);
// Copy input text to destination string.
MJAPI void mjm_setString(mjString dest, const char* text);
// Copy input array to destination vector.
MJAPI void mjm_setDouble(mjDouble dest, const double* array, int size);
// Get const pointer to mjString data.
MJAPI const char* mjm_getString(mjString source);
// Get const pointer to mjDouble data and its size.
MJAPI const double* mjm_getDouble(mjDouble source, int* size);
// Set frame.
MJAPI void mjm_setFrame(void* dest, void* frame);
#ifdef __cplusplus
}
#endif
#endif // MUJOCO_SRC_USER_USER_API_H_
+24 -8
View File
@@ -43,6 +43,7 @@
#include "engine/engine_util_solve.h"
#include "engine/engine_util_spatial.h"
#include "engine/engine_vfs.h"
#include "user/user_api.h"
#include "user/user_model.h"
#include "user/user_util.h"
@@ -1931,25 +1932,35 @@ mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) {
spec.group = 0;
mjuu_setvec(spec.quat, 1, 0, 0, 0);
mjuu_setvec(spec.pos, 0, 0, 0);
spec.material = nullptr;
spec_material_.clear();
spec.rgba[0] = spec.rgba[1] = spec.rgba[2] = 0.5f;
spec.rgba[3] = 1.0f;
spec.fromto[0] = mjNAN;
spec.userdata = nullptr;
spec_userdata_.clear();
spec.alt.axisangle[0] = spec.alt.xyaxes[0] = spec.alt.zaxis[0] =
spec.alt.euler[0] = spec.alt.fullinertia[0] = mjNAN;
// clear internal variables
body = 0;
matid = -1;
// initialize private attributes
CopyFromSpec();
// reset to default if given
if (_def) {
_def->site.CopyFromSpec();
*this = _def->site;
}
// point to local, not to default
spec.element = (mjElement)this;
spec.name = (mjString)&name;
spec.info = (mjString)&info;
spec.classname = (mjString)&classname;
spec.material = (mjString)&spec_material_;
spec.userdata = (mjDouble)&spec_userdata_;
// initialize private attributes in case object won't be compiled
CopyFromSpec();
// set model, def
model = _model;
def = (_def ? _def : (_model ? _model->defaults[0] : 0));
@@ -1961,8 +1972,13 @@ void mjCSite::CopyFromSpec() {
*static_cast<mjmSite*>(this) = spec;
userdata_ = spec_userdata_;
material_ = spec_material_;
userdata = userdata_.data();
material = material_.data();
userdata = (mjDouble)&userdata_;
material = (mjString)&material_;
mju_copy4(alt_.axisangle, alt.axisangle);
mju_copy(alt_.xyaxes, alt.xyaxes, 6);
mju_copy3(alt_.zaxis, alt.zaxis);
mju_copy3(alt_.euler, alt.euler);
mju_copy(alt_.fullinertia, alt.fullinertia, 6);
}
@@ -2034,7 +2050,7 @@ void mjCSite::Compile(void) {
// alternative orientation
else {
const char* err = alt.Set(quat, 0, model->degree, model->euler);
const char* err = alt_.Set(quat, 0, model->degree, model->euler);
if (err) {
throw mjCError(this, "orientation specification error '%s' in site %d", err, id);
}
+14 -34
View File
@@ -24,11 +24,10 @@
#include <utility>
#include <vector>
#include "lodepng.h"
#include <mujoco/mjtnum.h>
#include <mujoco/mjmodel.h>
#include <mujoco/mjplugin.h>
#include "user/user_api.h"
// forward declarations of all mjC/X classes
class mjCError;
@@ -109,18 +108,12 @@ class [[nodiscard]] mjCError {
// alternative specifications of frame orientation
class mjCAlternative {
class mjCAlternative : public mjmOrientation {
public:
mjCAlternative(); // constuctor
const char* Set(double* quat, double* inertia, // set frame quat and diag. inertia
bool degree, // angle format: degree/radian
const char* sequence); // euler sequence format: "xyz"
double axisangle[4]; // rotation axis and angle
double xyaxes[6]; // x and y axes
double zaxis[3]; // z axis (use minimal rotation)
double euler[3]; // euler rotations
double fullinertia[6]; // non-axis-aligned inertia matrix
};
@@ -458,19 +451,6 @@ class mjCGeom : public mjCBase {
//------------------------- class mjCSite ----------------------------------------------------------
// Describes a site on a body
typedef struct _mjmSite {
mjtGeom type; // geom type for rendering
int group; // group id, used for visualization
double size[3]; // geom size for rendering
double pos[3]; // position
double quat[4]; // orientation
char* material; // name of material for rendering
double* userdata; // user data
float rgba[4]; // rgba when material is omitted
double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid
mjCAlternative alt; // alternative orientation specification
} mjmSite;
class mjCSite : public mjCBase, private mjmSite {
friend class mjCDef;
friend class mjCBody;
@@ -481,30 +461,30 @@ class mjCSite : public mjCBase, private mjmSite {
public:
mjmSite spec; // variables set by user
void set_material(std::string _material) {
spec_material_ = _material;
spec.material = spec_material_.data();
}
void set_userdata(std::vector<double> _userdata) {
spec_userdata_ = _userdata;
spec.userdata = spec_userdata_.data();
}
std::vector<double>& get_userdata() { return userdata_; }
std::string& get_material() { return material_; }
// use strings from mjCBase rather than mjStrings from mjmSite
using mjCBase::name;
using mjCBase::classname;
using mjCBase::info;
// used by mjXWriter and mjCModel
const std::vector<double>& get_userdata() { return userdata_; }
const std::string& get_material() { return material_; }
// variables computed by 'compile' and 'mjCBody::addSite'
private:
mjCSite(mjCModel* = 0, mjCDef* = 0); // constructor
void Compile(void); // compiler
void CopyFromSpec(); // copy spec into attributes
mjCAlternative alt_;
mjCAlternative spec_alt_;
// variable-size data
std::string material_;
std::vector<double> userdata_;
std::string spec_material_;
std::vector<double> spec_userdata_;
// variables computed by 'compile' and 'mjCBody::addSite'
mjCBody* body; // site's body
int matid; // material id for rendering
};