From 7edacd39cdfeef72329975e0754fd48ca39b8c37 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Wed, 21 Feb 2024 02:24:53 -0800 Subject: [PATCH] Add engine settings to mjmModel. PiperOrigin-RevId: 608915453 Change-Id: Ic58566d7a9cdb57e25954caec69f595c8c9ee88a --- src/user/user_api.h | 26 +++++++++++++++++++++++++- src/user/user_init.cc | 18 ++++++++++++++++++ src/user/user_model.cc | 30 +++++++----------------------- src/user/user_model.h | 24 ++++-------------------- src/xml/xml_native_reader.cc | 14 ++++++++------ src/xml/xml_native_reader.h | 3 +-- src/xml/xml_native_writer.cc | 2 +- src/xml/xml_urdf.cc | 9 ++++++--- 8 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/user/user_api.h b/src/user/user_api.h index bed0b699..91dfffbe 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -15,6 +15,7 @@ #ifndef MUJOCO_SRC_USER_USER_API_H_ #define MUJOCO_SRC_USER_USER_API_H_ +#include #include #include #include @@ -82,7 +83,7 @@ typedef struct _mjmModel { // model specification mjElement element; // internal, do not modify mjStatistic stat; // statistics override (if defined) - //------------------------ compiler settings + // compiler settings mjtByte autolimits; // infer "limited" attribute based on range double boundmass; // enforce minimum body mass double boundinertia; // enforce minimum body diagonal inertia @@ -102,8 +103,31 @@ typedef struct _mjmModel { // model specification int inertiagrouprange[2]; // range of geom groups used to compute inertia mjtByte exactmeshinertia; // if false, use old formula mjLROpt LRopt; // options for lengthrange computation + + // engine data + mjString modelname; // model name + mjOption option; // options + mjVisual visual; // visual options + size_t memory; // size of arena+stack memory in bytes + int nemax; // max number of equality constraints + int njmax; // max number of constraints (Jacobian rows) + int nconmax; // max number of detected contacts (mjContact array size) + size_t nstack; // (deprecated) number of fields in mjData stack + int nuserdata; // number extra fields in mjData + 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 + int nuser_site; // number of mjtNums in site_user + int nuser_cam; // number of mjtNums in cam_user + int nuser_tendon; // number of mjtNums in tendon_user + int nuser_actuator; // number of mjtNums in actuator_user + int nuser_sensor; // number of mjtNums in sensor_user + + // sizes + int nkey; // number of keyframes } mjmModel; + typedef struct _mjmOrientation { // alternative orientation specifiers double axisangle[4]; // rotation axis and angle double xyaxes[6]; // x and y axes diff --git a/src/user/user_init.cc b/src/user/user_init.cc index 212944c4..2f0d4ecd 100644 --- a/src/user/user_init.cc +++ b/src/user/user_init.cc @@ -53,6 +53,24 @@ void mjm_defaultModel(mjmModel& model) { model.inertiagrouprange[1] = mjNGROUP-1; model.exactmeshinertia = false; mj_defaultLROpt(&model.LRopt); + + // engine data + mj_defaultOption(&model.option); + mj_defaultVisual(&model.visual); + model.memory = -1; + model.nemax = 0; + model.njmax = -1; + model.nconmax = -1; + model.nstack = -1; + model.nuserdata = 0; + model.nuser_body = -1; + model.nuser_jnt = -1; + model.nuser_geom = -1; + model.nuser_site = -1; + model.nuser_cam = -1; + model.nuser_tendon = -1; + model.nuser_actuator = -1; + model.nuser_sensor = -1; } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 2dc399c6..af5e05b4 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -88,6 +88,7 @@ mjCModel::mjCModel() { modelfiledir.clear(); spec_meshdir_.clear(); spec_texturedir_.clear(); + spec_modelname_ = "MuJoCo Model"; //------------------------ auto-computed statistics #ifndef MEMORY_SANITIZER @@ -99,28 +100,8 @@ mjCModel::mjCModel() { center_auto[0] = center_auto[1] = center_auto[2] = 0; #endif - //------------------------ engine data - modelname = "MuJoCo Model"; - mj_defaultOption(&option); - mj_defaultVisual(&visual); - memory = -1; - nemax = 0; - njmax = -1; - nconmax = -1; - nstack = -1; - nuserdata = 0; - nkey = 0; nmocap = 0; nplugin = 0; - nuser_body = -1; - nuser_jnt = -1; - nuser_geom = -1; - nuser_site = -1; - nuser_cam = -1; - nuser_tendon = -1; - nuser_actuator = -1; - nuser_sensor = -1; - //------------------------ private variables cameras.clear(); lights.clear(); @@ -196,6 +177,7 @@ mjCModel::mjCModel() { void mjCModel::PointToLocal() { spec.element = (mjElement)this; + spec.modelname = (mjString)&spec_modelname_; spec.meshdir = (mjString)&spec_meshdir_; spec.texturedir = (mjString)&spec_texturedir_; } @@ -204,8 +186,10 @@ void mjCModel::PointToLocal() { void mjCModel::CopyFromSpec() { *static_cast(this) = spec; + modelname_ = spec_modelname_; meshdir_ = spec_meshdir_; texturedir_ = spec_texturedir_; + modelname = (mjString)&modelname_; meshdir = (mjString)&meshdir_; texturedir = (mjString)&texturedir_; } @@ -1072,7 +1056,7 @@ void mjCModel::SetSizes(void) { for (int i=0; iflattened_attributes.size(); // nnames - nnames = (int)modelname.size() + 1; + nnames = (int)modelname_.size() + 1; for (int i=0; iname.length() + 1; for (int i=0; iname.length() + 1; for (int i=0; iname.length() + 1; @@ -1351,9 +1335,9 @@ static int namelist(vector& list, int adr, int* name_adr, char* names, int* // copy names, compute name addresses void mjCModel::CopyNames(mjModel* m) { // start with model name - int adr = (int)modelname.size()+1; + int adr = (int)modelname_.size()+1; int* map_adr = m->names_map; - mju_strncpy(m->names, modelname.c_str(), m->nnames); + mju_strncpy(m->names, modelname_.c_str(), m->nnames); memset(m->names_map, -1, sizeof(int) * m->nnames_map); // process all lists diff --git a/src/user/user_model.h b/src/user/user_model.h index 93b18cc8..d25af4b2 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -57,6 +57,8 @@ class mjCModel : private mjmModel { friend class mjCTendon; friend class mjCTexture; friend class mjCActuator; + friend class mjCSensor; + friend class mjCDef; friend class mjXReader; friend class mjXWriter; @@ -131,25 +133,6 @@ class mjCModel : private mjmModel { std::string modelfiledir; // path to model file std::vector defaults; // settings for each defaults class - //------------------------ engine data - std::string modelname; // model name - mjOption option; // options - mjVisual visual; // visual options - std::size_t memory; // size of arena+stack memory in bytes - int nemax; // max number of equality constraints - int njmax; // max number of constraints (Jacobian rows) - int nconmax; // max number of detected contacts (mjContact array size) - size_t nstack; // (deprecated) number of fields in mjData stack - int nuserdata; // number extra fields in mjData - 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 - int nuser_site; // number of mjtNums in site_user - int nuser_cam; // number of mjtNums in cam_user - int nuser_tendon; // number of mjtNums in tendon_user - int nuser_actuator; // number of mjtNums in actuator_user - int nuser_sensor; // number of mjtNums in sensor_user - private: void TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs); mjModel* _Compile(const mjVFS* vfs); @@ -202,7 +185,6 @@ class mjCModel : private mjmModel { int nnumeric; // number of numeric fields int ntext; // number of text fields int ntuple; // number of tuple fields - int nkey; // number of keyframes int nmocap; // number of mocap bodies int nplugin; // number of plugin instances @@ -297,8 +279,10 @@ class mjCModel : private mjmModel { std::vector qpos0; // save qpos0, to recognize changed key_qpos in write // variable-size attributes + std::string modelname_; std::string meshdir_; std::string texturedir_; + std::string spec_modelname_; std::string spec_meshdir_; std::string spec_texturedir_; }; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 37776f2d..f394bcec 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -39,7 +39,6 @@ #include "user/user_api.h" #include "user/user_composite.h" #include "user/user_flexcomp.h" -#include "user/user_model.h" #include "user/user_util.h" #include "xml/xml_base.h" #include "xml/xml_util.h" @@ -805,7 +804,10 @@ void mjXReader::Parse(XMLElement* root) { } // get model name - ReadAttrTxt(root, "model", model->modelname); + string modelname; + if (ReadAttrTxt(root, "model", modelname)) { + mjm_setString(model->spec.modelname, modelname.c_str()); + } // get comment if (root->FirstChild() && root->FirstChild()->ToComment()) { @@ -823,12 +825,12 @@ void mjXReader::Parse(XMLElement* root) { for (XMLElement* section = FirstChildElement(root, "option"); section; section = NextSiblingElement(section, "option")) { - Option(section, &model->option); + Option(section, &model->spec.option); } for (XMLElement* section = FirstChildElement(root, "size"); section; section = NextSiblingElement(section, "size")) { - Size(section, model); + Size(section, &model->spec); } //------------------ parse MJCF-specific sections @@ -1096,7 +1098,7 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) { // size section parser -void mjXReader::Size(XMLElement* section, mjCModel* mod) { +void mjXReader::Size(XMLElement* section, mjmModel* mod) { // read memory bytes { constexpr char err_msg[] = @@ -2936,7 +2938,7 @@ void mjXReader::Custom(XMLElement* section) { void mjXReader::Visual(XMLElement* section) { string text, name; XMLElement* elem; - mjVisual* vis = &model->visual; + mjVisual* vis = &model->spec.visual; // iterate over child elements elem = FirstChildElement(section); diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index 51a3bb8f..c84c15e3 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -22,7 +22,6 @@ #include #include "user/user_api.h" -#include "user/user_model.h" #include "xml/xml_base.h" #include "xml/xml_util.h" @@ -45,7 +44,7 @@ class mjXReader : public mjXBase { // XML sections embedded in all formats static void Compiler(tinyxml2::XMLElement* section, mjmModel* mod); // compiler section static void Option(tinyxml2::XMLElement* section, mjOption* opt); // option section - static void Size(tinyxml2::XMLElement* section, mjCModel* mod); // size section + static void Size(tinyxml2::XMLElement* section, mjmModel* mod); // size section private: // XML section specific to MJCF diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 43efe352..7e6be6aa 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -775,7 +775,7 @@ string mjXWriter::Write(char *error, size_t error_sz) { // create document and root XMLDocument doc; XMLElement* root = doc.NewElement("mujoco"); - root->SetAttribute("model", model->modelname.c_str()); + root->SetAttribute("model", mjm_getString(model->modelname)); // insert root doc.InsertFirstChild(root); diff --git a/src/xml/xml_urdf.cc b/src/xml/xml_urdf.cc index fc31f5c5..f24ed933 100644 --- a/src/xml/xml_urdf.cc +++ b/src/xml/xml_urdf.cc @@ -97,11 +97,11 @@ void mjXURDF::Parse( } if ((section = FindSubElem(mjc, "option"))) { - mjXReader::Option(section, &model->option); + mjXReader::Option(section, &model->spec.option); } if ((section = FindSubElem(mjc, "size"))) { - mjXReader::Size(section, model); + mjXReader::Size(section, &model->spec); } } @@ -109,7 +109,10 @@ void mjXURDF::Parse( model->spec.degree = false; // get model name - ReadAttrTxt(root, "name", model->modelname); + std::string modelname; + if (ReadAttrTxt(root, "name", modelname)) { + mjm_setString(model->spec.modelname, modelname.c_str()); + } // find and register all materials MakeMaterials(root);