From 0e19722c616daf465fbaf94c231a20d381b487c6 Mon Sep 17 00:00:00 2001 From: Saran Tunyasuvunakool Date: Thu, 27 Jun 2024 10:49:25 -0700 Subject: [PATCH] Split `name2id` and `id2name` into a separate source file. PiperOrigin-RevId: 647373431 Change-Id: I3bab0ea7157750b79826739e3d739e4114fa0af7 --- src/engine/CMakeLists.txt | 2 + src/engine/engine_name.c | 284 ++++++++++++++++++++++++++++++ src/engine/engine_name.h | 41 +++++ src/engine/engine_print.c | 1 + src/engine/engine_support.c | 264 --------------------------- src/engine/engine_support.h | 14 -- src/engine/engine_vis_visualize.c | 1 + src/user/user_model.cc | 1 + 8 files changed, 330 insertions(+), 278 deletions(-) create mode 100644 src/engine/engine_name.c create mode 100644 src/engine/engine_name.h diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index e659bd1db0..b1ec5d23ea 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -47,6 +47,8 @@ set(MUJOCO_ENGINE_SRCS engine_io.c engine_io.h engine_macro.h + engine_name.c + engine_name.h engine_passive.c engine_passive.h engine_plugin.cc diff --git a/src/engine/engine_name.c b/src/engine/engine_name.c new file mode 100644 index 0000000000..013ae8ad50 --- /dev/null +++ b/src/engine/engine_name.c @@ -0,0 +1,284 @@ +// 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 "engine/engine_name.h" + +#include +#include + +#include +#include "engine/engine_crossplatform.h" +#include "engine/engine_io.h" + + + +//-------------------------- name functions -------------------------------------------------------- +// get number of objects and name addresses for given object type +static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) { + int num = -1; + // map address starts at the end, subtract with explicit switch fallthrough below + *mapadr = m->nnames_map; + + // get address list and size for object type + switch (type) { + case mjOBJ_BODY: + case mjOBJ_XBODY: + *mapadr -= mjLOAD_MULTIPLE*m->nbody; + *padr = m->name_bodyadr; + num = m->nbody; + mjFALLTHROUGH; + + case mjOBJ_JOINT: + *mapadr -= mjLOAD_MULTIPLE*m->njnt; + if (num < 0) { + *padr = m->name_jntadr; + num = m->njnt; + } + mjFALLTHROUGH; + + case mjOBJ_GEOM: + *mapadr -= mjLOAD_MULTIPLE*m->ngeom; + if (num < 0) { + *padr = m->name_geomadr; + num = m->ngeom; + } + mjFALLTHROUGH; + + case mjOBJ_SITE: + *mapadr -= mjLOAD_MULTIPLE*m->nsite; + if (num < 0) { + *padr = m->name_siteadr; + num = m->nsite; + } + mjFALLTHROUGH; + + case mjOBJ_CAMERA: + *mapadr -= mjLOAD_MULTIPLE*m->ncam; + if (num < 0) { + *padr = m->name_camadr; + num = m->ncam; + } + mjFALLTHROUGH; + + case mjOBJ_LIGHT: + *mapadr -= mjLOAD_MULTIPLE*m->nlight; + if (num < 0) { + *padr = m->name_lightadr; + num = m->nlight; + } + mjFALLTHROUGH; + + case mjOBJ_FLEX: + *mapadr -= mjLOAD_MULTIPLE*m->nflex; + if (num < 0) { + *padr = m->name_flexadr; + num = m->nflex; + } + mjFALLTHROUGH; + + case mjOBJ_MESH: + *mapadr -= mjLOAD_MULTIPLE*m->nmesh; + if (num < 0) { + *padr = m->name_meshadr; + num = m->nmesh; + } + mjFALLTHROUGH; + + case mjOBJ_SKIN: + *mapadr -= mjLOAD_MULTIPLE*m->nskin; + if (num < 0) { + *padr = m->name_skinadr; + num = m->nskin; + } + mjFALLTHROUGH; + + case mjOBJ_HFIELD: + *mapadr -= mjLOAD_MULTIPLE*m->nhfield; + if (num < 0) { + *padr = m->name_hfieldadr; + num = m->nhfield; + } + mjFALLTHROUGH; + + case mjOBJ_TEXTURE: + *mapadr -= mjLOAD_MULTIPLE*m->ntex; + if (num < 0) { + *padr = m->name_texadr; + num = m->ntex; + } + mjFALLTHROUGH; + + case mjOBJ_MATERIAL: + *mapadr -= mjLOAD_MULTIPLE*m->nmat; + if (num < 0) { + *padr = m->name_matadr; + num = m->nmat; + } + mjFALLTHROUGH; + + case mjOBJ_PAIR: + *mapadr -= mjLOAD_MULTIPLE*m->npair; + if (num < 0) { + *padr = m->name_pairadr; + num = m->npair; + } + mjFALLTHROUGH; + + case mjOBJ_EXCLUDE: + *mapadr -= mjLOAD_MULTIPLE*m->nexclude; + if (num < 0) { + *padr = m->name_excludeadr; + num = m->nexclude; + } + mjFALLTHROUGH; + + case mjOBJ_EQUALITY: + *mapadr -= mjLOAD_MULTIPLE*m->neq; + if (num < 0) { + *padr = m->name_eqadr; + num = m->neq; + } + mjFALLTHROUGH; + + case mjOBJ_TENDON: + *mapadr -= mjLOAD_MULTIPLE*m->ntendon; + if (num < 0) { + *padr = m->name_tendonadr; + num = m->ntendon; + } + mjFALLTHROUGH; + + case mjOBJ_ACTUATOR: + *mapadr -= mjLOAD_MULTIPLE*m->nu; + if (num < 0) { + *padr = m->name_actuatoradr; + num = m->nu; + } + mjFALLTHROUGH; + + case mjOBJ_SENSOR: + *mapadr -= mjLOAD_MULTIPLE*m->nsensor; + if (num < 0) { + *padr = m->name_sensoradr; + num = m->nsensor; + } + mjFALLTHROUGH; + + case mjOBJ_NUMERIC: + *mapadr -= mjLOAD_MULTIPLE*m->nnumeric; + if (num < 0) { + *padr = m->name_numericadr; + num = m->nnumeric; + } + mjFALLTHROUGH; + + case mjOBJ_TEXT: + *mapadr -= mjLOAD_MULTIPLE*m->ntext; + if (num < 0) { + *padr = m->name_textadr; + num = m->ntext; + } + mjFALLTHROUGH; + + case mjOBJ_TUPLE: + *mapadr -= mjLOAD_MULTIPLE*m->ntuple; + if (num < 0) { + *padr = m->name_tupleadr; + num = m->ntuple; + } + mjFALLTHROUGH; + + case mjOBJ_KEY: + *mapadr -= mjLOAD_MULTIPLE*m->nkey; + if (num < 0) { + *padr = m->name_keyadr; + num = m->nkey; + } + mjFALLTHROUGH; + + case mjOBJ_PLUGIN: + *mapadr -= mjLOAD_MULTIPLE*m->nplugin; + if (num < 0) { + *padr = m->name_pluginadr; + num = m->nplugin; + } + mjFALLTHROUGH; + + default: + if (num < 0) { + *padr = 0; + num = 0; + } + } + + return num; +} + +// get string hash, see http://www.cse.yorku.ca/~oz/hash.html +uint64_t mj_hashString(const char* s, uint64_t n) { + uint64_t h = 5381; + int c; + while ((c = *s++)) { + h = ((h << 5) + h) ^ c; + } + return h % n; +} + +// get id of object with the specified mjtObj type and name, +// returns -1 if id not found +int mj_name2id(const mjModel* m, int type, const char* name) { + int mapadr; + int* adr = 0; + + // get number of objects and name addresses + int num = mjLOAD_MULTIPLE*_getnumadr(m, type, &adr, &mapadr); + + // search + if (num) { // look up at hash address + uint64_t hash = mj_hashString(name, num); + uint64_t i = hash; + + do { + int j = m->names_map[mapadr + i]; + if (j < 0) { + return -1; + } + + if (!strncmp(name, m->names+adr[j], m->nnames-adr[j])) { + return j; + } + if ((++i) == num)i = 0; + } while (i != hash); + } + return -1; +} + + + +// get name of object with the specified mjtObj type and id, +// returns NULL if name not found +const char* mj_id2name(const mjModel* m, int type, int id) { + int mapadr; + int* adr = 0; + + // get number of objects and name addresses + int num = _getnumadr(m, type, &adr, &mapadr); + + // id is in [0, num) and the found name is not the empty string "\0" + if (id >= 0 && id < num && m->names[adr[id]]) { + return m->names+adr[id]; + } + + return NULL; +} diff --git a/src/engine/engine_name.h b/src/engine/engine_name.h new file mode 100644 index 0000000000..3bb98b2c1c --- /dev/null +++ b/src/engine/engine_name.h @@ -0,0 +1,41 @@ +// 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_ENGINE_ENGINE_NAME_H_ +#define MUJOCO_SRC_ENGINE_ENGINE_NAME_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------- name functions -------------------------------------------------------- + +// get string hash, see http://www.cse.yorku.ca/~oz/hash.html +uint64_t mj_hashString(const char* s, uint64_t n); + +// get id of object with the specified mjtObj type and name, returns -1 if id not found +MJAPI int mj_name2id(const mjModel* m, int type, const char* name); + +// get name of object with the specified mjtObj type and id, returns NULL if name not found +MJAPI const char* mj_id2name(const mjModel* m, int type, int id); +#ifdef __cplusplus +} +#endif + +#endif // MUJOCO_SRC_ENGINE_ENGINE_NAME_H_ diff --git a/src/engine/engine_print.c b/src/engine/engine_print.c index 8fee7ebf64..0504c768c1 100644 --- a/src/engine/engine_print.c +++ b/src/engine/engine_print.c @@ -25,6 +25,7 @@ #include #include "engine/engine_core_constraint.h" #include "engine/engine_io.h" +#include "engine/engine_name.h" #include "engine/engine_support.h" #include "engine/engine_util_errmem.h" #include "engine/engine_util_misc.h" diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 6740f2aebb..09a5373f60 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -15,7 +15,6 @@ #include "engine/engine_support.h" #include -#include #include #include @@ -868,269 +867,6 @@ void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body) { -//-------------------------- name functions -------------------------------------------------------- - -// get number of objects and name addresses for given object type -static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) { - int num = -1; - // map address starts at the end, subtract with explicit switch fallthrough below - *mapadr = m->nnames_map; - - // get address list and size for object type - switch (type) { - case mjOBJ_BODY: - case mjOBJ_XBODY: - *mapadr -= mjLOAD_MULTIPLE*m->nbody; - *padr = m->name_bodyadr; - num = m->nbody; - mjFALLTHROUGH; - - case mjOBJ_JOINT: - *mapadr -= mjLOAD_MULTIPLE*m->njnt; - if (num < 0) { - *padr = m->name_jntadr; - num = m->njnt; - } - mjFALLTHROUGH; - - case mjOBJ_GEOM: - *mapadr -= mjLOAD_MULTIPLE*m->ngeom; - if (num < 0) { - *padr = m->name_geomadr; - num = m->ngeom; - } - mjFALLTHROUGH; - - case mjOBJ_SITE: - *mapadr -= mjLOAD_MULTIPLE*m->nsite; - if (num < 0) { - *padr = m->name_siteadr; - num = m->nsite; - } - mjFALLTHROUGH; - - case mjOBJ_CAMERA: - *mapadr -= mjLOAD_MULTIPLE*m->ncam; - if (num < 0) { - *padr = m->name_camadr; - num = m->ncam; - } - mjFALLTHROUGH; - - case mjOBJ_LIGHT: - *mapadr -= mjLOAD_MULTIPLE*m->nlight; - if (num < 0) { - *padr = m->name_lightadr; - num = m->nlight; - } - mjFALLTHROUGH; - - case mjOBJ_FLEX: - *mapadr -= mjLOAD_MULTIPLE*m->nflex; - if (num < 0) { - *padr = m->name_flexadr; - num = m->nflex; - } - mjFALLTHROUGH; - - case mjOBJ_MESH: - *mapadr -= mjLOAD_MULTIPLE*m->nmesh; - if (num < 0) { - *padr = m->name_meshadr; - num = m->nmesh; - } - mjFALLTHROUGH; - - case mjOBJ_SKIN: - *mapadr -= mjLOAD_MULTIPLE*m->nskin; - if (num < 0) { - *padr = m->name_skinadr; - num = m->nskin; - } - mjFALLTHROUGH; - - case mjOBJ_HFIELD: - *mapadr -= mjLOAD_MULTIPLE*m->nhfield; - if (num < 0) { - *padr = m->name_hfieldadr; - num = m->nhfield; - } - mjFALLTHROUGH; - - case mjOBJ_TEXTURE: - *mapadr -= mjLOAD_MULTIPLE*m->ntex; - if (num < 0) { - *padr = m->name_texadr; - num = m->ntex; - } - mjFALLTHROUGH; - - case mjOBJ_MATERIAL: - *mapadr -= mjLOAD_MULTIPLE*m->nmat; - if (num < 0) { - *padr = m->name_matadr; - num = m->nmat; - } - mjFALLTHROUGH; - - case mjOBJ_PAIR: - *mapadr -= mjLOAD_MULTIPLE*m->npair; - if (num < 0) { - *padr = m->name_pairadr; - num = m->npair; - } - mjFALLTHROUGH; - - case mjOBJ_EXCLUDE: - *mapadr -= mjLOAD_MULTIPLE*m->nexclude; - if (num < 0) { - *padr = m->name_excludeadr; - num = m->nexclude; - } - mjFALLTHROUGH; - - case mjOBJ_EQUALITY: - *mapadr -= mjLOAD_MULTIPLE*m->neq; - if (num < 0) { - *padr = m->name_eqadr; - num = m->neq; - } - mjFALLTHROUGH; - - case mjOBJ_TENDON: - *mapadr -= mjLOAD_MULTIPLE*m->ntendon; - if (num < 0) { - *padr = m->name_tendonadr; - num = m->ntendon; - } - mjFALLTHROUGH; - - case mjOBJ_ACTUATOR: - *mapadr -= mjLOAD_MULTIPLE*m->nu; - if (num < 0) { - *padr = m->name_actuatoradr; - num = m->nu; - } - mjFALLTHROUGH; - - case mjOBJ_SENSOR: - *mapadr -= mjLOAD_MULTIPLE*m->nsensor; - if (num < 0) { - *padr = m->name_sensoradr; - num = m->nsensor; - } - mjFALLTHROUGH; - - case mjOBJ_NUMERIC: - *mapadr -= mjLOAD_MULTIPLE*m->nnumeric; - if (num < 0) { - *padr = m->name_numericadr; - num = m->nnumeric; - } - mjFALLTHROUGH; - - case mjOBJ_TEXT: - *mapadr -= mjLOAD_MULTIPLE*m->ntext; - if (num < 0) { - *padr = m->name_textadr; - num = m->ntext; - } - mjFALLTHROUGH; - - case mjOBJ_TUPLE: - *mapadr -= mjLOAD_MULTIPLE*m->ntuple; - if (num < 0) { - *padr = m->name_tupleadr; - num = m->ntuple; - } - mjFALLTHROUGH; - - case mjOBJ_KEY: - *mapadr -= mjLOAD_MULTIPLE*m->nkey; - if (num < 0) { - *padr = m->name_keyadr; - num = m->nkey; - } - mjFALLTHROUGH; - - case mjOBJ_PLUGIN: - *mapadr -= mjLOAD_MULTIPLE*m->nplugin; - if (num < 0) { - *padr = m->name_pluginadr; - num = m->nplugin; - } - mjFALLTHROUGH; - - default: - if (num < 0) { - *padr = 0; - num = 0; - } - } - - return num; -} - -// get string hash, see http://www.cse.yorku.ca/~oz/hash.html -uint64_t mj_hashString(const char* s, uint64_t n) { - uint64_t h = 5381; - int c; - while ((c = *s++)) { - h = ((h << 5) + h) ^ c; - } - return h % n; -} - -// get id of object with the specified mjtObj type and name, -// returns -1 if id not found -int mj_name2id(const mjModel* m, int type, const char* name) { - int mapadr; - int* adr = 0; - - // get number of objects and name addresses - int num = mjLOAD_MULTIPLE*_getnumadr(m, type, &adr, &mapadr); - - // search - if (num) { // look up at hash address - uint64_t hash = mj_hashString(name, num); - uint64_t i = hash; - - do { - int j = m->names_map[mapadr + i]; - if (j < 0) { - return -1; - } - - if (!strncmp(name, m->names+adr[j], m->nnames-adr[j])) { - return j; - } - if ((++i) == num)i = 0; - } while (i != hash); - } - return -1; -} - - - -// get name of object with the specified mjtObj type and id, -// returns NULL if name not found -const char* mj_id2name(const mjModel* m, int type, int id) { - int mapadr; - int* adr = 0; - - // get number of objects and name addresses - int num = _getnumadr(m, type, &adr, &mapadr); - - // id is in [0, num) and the found name is not the empty string "\0" - if (id >= 0 && id < num && m->names[adr[id]]) { - return m->names+adr[id]; - } - - return NULL; -} - - - //-------------------------- inertia functions ----------------------------------------------------- // convert sparse inertia matrix M into full matrix diff --git a/src/engine/engine_support.h b/src/engine/engine_support.h index ae3df31cb7..df1c8e025b 100644 --- a/src/engine/engine_support.h +++ b/src/engine/engine_support.h @@ -15,8 +15,6 @@ #ifndef MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_ #define MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_ -#include - #include #include #include @@ -113,18 +111,6 @@ int mj_jacSum(const mjModel* m, mjData* d, int* chain, MJAPI void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body); -//-------------------------- name functions -------------------------------------------------------- - -// get string hash, see http://www.cse.yorku.ca/~oz/hash.html -uint64_t mj_hashString(const char* s, uint64_t n); - -// get id of object with the specified mjtObj type and name, returns -1 if id not found -MJAPI int mj_name2id(const mjModel* m, int type, const char* name); - -// get name of object with the specified mjtObj type and id, returns NULL if name not found -MJAPI const char* mj_id2name(const mjModel* m, int type, int id); - - //-------------------------- inertia functions ----------------------------------------------------- // convert sparse inertia matrix M into full matrix diff --git a/src/engine/engine_vis_visualize.c b/src/engine/engine_vis_visualize.c index 66177c4f70..ffed1b502e 100644 --- a/src/engine/engine_vis_visualize.c +++ b/src/engine/engine_vis_visualize.c @@ -23,6 +23,7 @@ #include #include "engine/engine_array_safety.h" #include "engine/engine_io.h" +#include "engine/engine_name.h" #include "engine/engine_plugin.h" #include "engine/engine_support.h" #include "engine/engine_util_blas.h" diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 0fadddd022..953d3bfdc1 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -36,6 +36,7 @@ #include "cc/array_safety.h" #include "engine/engine_forward.h" #include "engine/engine_io.h" +#include "engine/engine_name.h" #include "engine/engine_plugin.h" #include "engine/engine_setconst.h" #include "engine/engine_support.h"