// Copyright 2024 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 #include #include #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* modelspec) { mjCModel* model = static_cast(modelspec); delete model; } // copy spec into private attributes MJAPI void mjm_finalize(mjElement object) { mjCBase* baseC = reinterpret_cast(object); baseC->CopyFromSpec(); } // add child body to body, return child spec mjmBody* mjm_addBody(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element)->AddBody(def); return &body->spec; } // add site to body, return site spec mjmSite* mjm_addSite(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element); mjCSite* site = body->AddSite(def); return &site->spec; } // add joint to body mjmJoint* mjm_addJoint(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element); mjCJoint* joint = body->AddJoint(def); return &joint->spec; } // add free joint to body mjmJoint* mjm_addFreeJoint(mjmBody* bodyspec) { mjCBody* body = reinterpret_cast(bodyspec->element); mjCJoint* joint = body->AddFreeJoint(); return &joint->spec; } // add geom to body mjmGeom* mjm_addGeom(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element); mjCGeom* geom = body->AddGeom(def); return &geom->spec; } // add camera to body mjmCamera* mjm_addCamera(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element); mjCCamera* camera = body->AddCamera(def); return &camera->spec; } // add light to body mjmLight* mjm_addLight(mjmBody* bodyspec, void* defspec) { mjCDef* def = static_cast(defspec); mjCBody* body = reinterpret_cast(bodyspec->element); mjCLight* light = body->AddLight(def); return &light->spec; } // add frame to body void* mjm_addFrame(mjmBody* bodyspec, void* parentframe) { mjCFrame* parentframeC = static_cast(parentframe); mjCFrame* frameC = reinterpret_cast(bodyspec->element)->AddFrame(parentframeC); return frameC; } // add equality to model mjmEquality* mjm_addEquality(void* model, void* defspec) { mjCModel* modelC = static_cast(model); mjCDef* def = static_cast(defspec); mjCEquality* equality = modelC->AddEquality(def); return &equality->spec; } // add tendon to model mjmTendon* mjm_addTendon(void* model, void* defspec) { mjCModel* modelC = static_cast(model); mjCDef* def = static_cast(defspec); mjCTendon* tendon = modelC->AddTendon(def); return &tendon->spec; } // wrap site using tendon MJAPI mjmWrap* mjm_wrapSite(mjmTendon* tendonspec, const char* name) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapSite(name); return &tendon->path.back()->spec; } // wrap geom using tendon mjmWrap* mjm_wrapGeom(mjmTendon* tendonspec, const char* name, const char* sidesite) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapGeom(name, sidesite); return &tendon->path.back()->spec; } // wrap joint using tendon mjmWrap* mjm_wrapJoint(mjmTendon* tendonspec, const char* name, double coef) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapJoint(name, coef); return &tendon->path.back()->spec; } // wrap pulley using tendon mjmWrap* mjm_wrapPulley(mjmTendon* tendonspec, double divisor) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapPulley(divisor); return &tendon->path.back()->spec; } // add actuator to model mjmActuator* mjm_addActuator(void* model, void* defspec) { mjCModel* modelC = static_cast(model); mjCDef* def = static_cast(defspec); mjCActuator* actuator = modelC->AddActuator(def); return &actuator->spec; } // add sensor to model mjmSensor* mjm_addSensor(void* model) { mjCModel* modelC = static_cast(model); mjCSensor* sensor = modelC->AddSensor(); return &sensor->spec; } // Add plugin to model. mjElement mjm_addPlugin(void* model) { mjCModel* modelC = static_cast(model); mjCPlugin* plugin = modelC->AddPlugin(); return (mjElement)plugin; } // get objects void* mjm_getModel(mjmBody* bodyspec) { return reinterpret_cast(bodyspec->element)->model; } // get default void* mjm_getDefault(mjElement element) { return reinterpret_cast(element)->def; } // find body in model by name mjmBody* mjm_findBody(void* modelspec, const char* name) { mjCModel* model = static_cast(modelspec); mjCBase* body = model->FindObject(mjOBJ_BODY, std::string(name)); if (!body) { return 0; } return &(static_cast(body)->spec); } // find child of a body by name mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) { mjCBody* body = reinterpret_cast(bodyspec->element); mjCBase* child = body->FindObject(mjOBJ_BODY, std::string(name)); if (!child) { return 0; } return &(static_cast(child)->spec); } // set frame void mjm_setFrame(mjElement dest, void* frame) { mjCFrame* frameC = static_cast(frame); mjCBase* baseC = reinterpret_cast(dest); baseC->SetFrame(frameC); } // get id int mjm_getId(mjElement element) { return reinterpret_cast(element)->id; } // set default void mjm_setDefault(mjElement element, void* defspec) { mjCBase* baseC = reinterpret_cast(element); baseC->def = static_cast(defspec); } // set string void mjm_setString(mjString dest, const char* text) { std::string* str = reinterpret_cast(dest); *str = std::string(text); } // set double array void mjm_setDouble(mjDouble dest, const double* array, int size) { std::vector* v = reinterpret_cast*>(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(source); return str->c_str(); } // get double array const double* mjm_getDouble(const mjDouble source, int* size) { std::vector* v = reinterpret_cast*>(source); if (size) { *size = v->size(); } return v->data(); } // compute full inertia const char* mjm_setFullInertia(mjmBody* bodyspec, double quat[4], double inertia[3]) { mjCBody* body = reinterpret_cast(bodyspec->element); return body->FullInertia(quat, inertia); }