Added functionality for user payload data in mjSpec.
PiperOrigin-RevId: 738343134 Change-Id: I6217362ced9993afcd5a2914c78718ffe3bf753a
This commit is contained in:
committed by
Copybara-Service
parent
dc50fbbb9b
commit
209d2bd2c5
@@ -4458,6 +4458,33 @@ Resolve alternative orientations to quat, return error if any.
|
|||||||
|
|
||||||
Transform body into a frame.
|
Transform body into a frame.
|
||||||
|
|
||||||
|
.. _mjs_setUserValue:
|
||||||
|
|
||||||
|
`mjs_setUserValue <#mjs_setUserValue>`__
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_setUserValue
|
||||||
|
|
||||||
|
Set user payload, overriding the existing value for the specified key if present.
|
||||||
|
|
||||||
|
.. _mjs_getUserValue:
|
||||||
|
|
||||||
|
`mjs_getUserValue <#mjs_getUserValue>`__
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_getUserValue
|
||||||
|
|
||||||
|
Return user payload or NULL if none found.
|
||||||
|
|
||||||
|
.. _mjs_deleteUserValue:
|
||||||
|
|
||||||
|
`mjs_deleteUserValue <#mjs_deleteUserValue>`__
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_deleteUserValue
|
||||||
|
|
||||||
|
Delete user payload.
|
||||||
|
|
||||||
.. _ElementInitialization:
|
.. _ElementInitialization:
|
||||||
|
|
||||||
Element initialization
|
Element initialization
|
||||||
|
|||||||
@@ -3677,6 +3677,9 @@ void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
|||||||
const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
||||||
const mjsOrientation* orientation);
|
const mjsOrientation* orientation);
|
||||||
mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
||||||
|
void mjs_setUserValue(mjsElement* element, const char* key, const void* data);
|
||||||
|
const void* mjs_getUserValue(mjsElement* element, const char* key);
|
||||||
|
void mjs_deleteUserValue(mjsElement* element, const char* key);
|
||||||
void mjs_defaultSpec(mjSpec* spec);
|
void mjs_defaultSpec(mjSpec* spec);
|
||||||
void mjs_defaultOrientation(mjsOrientation* orient);
|
void mjs_defaultOrientation(mjsOrientation* orient);
|
||||||
void mjs_defaultBody(mjsBody* body);
|
void mjs_defaultBody(mjsBody* body);
|
||||||
|
|||||||
@@ -1648,6 +1648,15 @@ MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const c
|
|||||||
// Transform body into a frame.
|
// Transform body into a frame.
|
||||||
MJAPI mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
MJAPI mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
||||||
|
|
||||||
|
// Set user payload, overriding the existing value for the specified key if present.
|
||||||
|
MJAPI void mjs_setUserValue(mjsElement* element, const char* key, const void* data);
|
||||||
|
|
||||||
|
// Return user payload or NULL if none found.
|
||||||
|
MJAPI const void* mjs_getUserValue(mjsElement* element, const char* key);
|
||||||
|
|
||||||
|
// Delete user payload.
|
||||||
|
MJAPI void mjs_deleteUserValue(mjsElement* element, const char* key);
|
||||||
|
|
||||||
//---------------------------------- Element initialization ---------------------------------------
|
//---------------------------------- Element initialization ---------------------------------------
|
||||||
|
|
||||||
// Default spec attributes.
|
// Default spec attributes.
|
||||||
|
|||||||
@@ -10471,6 +10471,74 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Transform body into a frame.',
|
doc='Transform body into a frame.',
|
||||||
)),
|
)),
|
||||||
|
('mjs_setUserValue',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_setUserValue',
|
||||||
|
return_type=ValueType(name='void'),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='key',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='data',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='void', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Set user payload, overriding the existing value for the specified key if present.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_getUserValue',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_getUserValue',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='void', is_const=True),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='key',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Return user payload or NULL if none found.',
|
||||||
|
)),
|
||||||
|
('mjs_deleteUserValue',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_deleteUserValue',
|
||||||
|
return_type=ValueType(name='void'),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='key',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Delete user payload.',
|
||||||
|
)),
|
||||||
('mjs_defaultSpec',
|
('mjs_defaultSpec',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_defaultSpec',
|
name='mjs_defaultSpec',
|
||||||
|
|||||||
@@ -769,6 +769,30 @@ mjsFrame* mjs_bodyToFrame(mjsBody** body) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// set user payload
|
||||||
|
void mjs_setUserValue(mjsElement* element, const char* key, const void* data) {
|
||||||
|
mjCBase* baseC = static_cast<mjCBase*>(element);
|
||||||
|
baseC->SetUserValue(key, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return user payload or NULL if none found
|
||||||
|
const void* mjs_getUserValue(mjsElement* element, const char* key) {
|
||||||
|
mjCBase* baseC = static_cast<mjCBase*>(element);
|
||||||
|
return baseC->GetUserValue(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// delete user payload
|
||||||
|
void mjs_deleteUserValue(mjsElement* element, const char* key) {
|
||||||
|
mjCBase* baseC = static_cast<mjCBase*>(element);
|
||||||
|
baseC->DeleteUserValue(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// get id
|
// get id
|
||||||
int mjs_getId(mjsElement* element) {
|
int mjs_getId(mjsElement* element) {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
|
|||||||
@@ -378,6 +378,15 @@ MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const c
|
|||||||
// Transform body into a frame.
|
// Transform body into a frame.
|
||||||
MJAPI mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
MJAPI mjsFrame* mjs_bodyToFrame(mjsBody** body);
|
||||||
|
|
||||||
|
// Set user payload.
|
||||||
|
MJAPI void mjs_setUserValue(mjsElement* element, const char* key, const void* data);
|
||||||
|
|
||||||
|
// Return user payload or NULL if none found.
|
||||||
|
MJAPI const void* mjs_getUserValue(mjsElement* element, const char* key);
|
||||||
|
|
||||||
|
// Delete user payload.
|
||||||
|
MJAPI void mjs_deleteUserValue(mjsElement* element, const char* key);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Initialization -----------------------------------------------
|
//---------------------------------- Initialization -----------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -766,6 +766,22 @@ void mjCBase::SetFrame(mjCFrame* _frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mjCBase::SetUserValue(std::string_view key, const void* data) {
|
||||||
|
user_payload_[std::string(key)] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const void* mjCBase::GetUserValue(std::string_view key) {
|
||||||
|
auto found = user_payload_.find(std::string(key));
|
||||||
|
return found != user_payload_.end() ? found->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mjCBase::DeleteUserValue(std::string_view key) {
|
||||||
|
user_payload_.erase(std::string(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------ class mjCBody implementation --------------------------------------------------
|
//------------------ class mjCBody implementation --------------------------------------------------
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
|
|||||||
+13
-2
@@ -23,11 +23,14 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mujoco/mjmodel.h>
|
||||||
|
#include <mujoco/mjplugin.h>
|
||||||
#include <mujoco/mjspec.h>
|
#include <mujoco/mjspec.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include "user/user_cache.h"
|
#include "user/user_cache.h"
|
||||||
#include "user/user_util.h"
|
#include "user/user_util.h"
|
||||||
#include <tiny_obj_loader.h>
|
#include <tiny_obj_loader.h>
|
||||||
@@ -274,12 +277,20 @@ class mjCBase : public mjCBase_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set and get user payload
|
||||||
|
void SetUserValue(std::string_view key, const void* data);
|
||||||
|
const void* GetUserValue(std::string_view key);
|
||||||
|
void DeleteUserValue(std::string_view key);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mjCBase(); // constructor
|
mjCBase(); // constructor
|
||||||
mjCBase(const mjCBase& other); // copy constructor
|
mjCBase(const mjCBase& other); // copy constructor
|
||||||
|
|
||||||
// reference count for allowing deleting an attached object
|
// reference count for allowing deleting an attached object
|
||||||
int refcount = 1;
|
int refcount = 1;
|
||||||
|
|
||||||
|
// user payload
|
||||||
|
std::unordered_map<std::string, const void*> user_payload_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -781,7 +792,7 @@ class mjCLight : public mjCLight_, private mjsLight {
|
|||||||
|
|
||||||
class mjCFlex_ : public mjCBase {
|
class mjCFlex_ : public mjCBase {
|
||||||
protected:
|
protected:
|
||||||
int nvert; // number of verices
|
int nvert; // number of vertices
|
||||||
int nnode; // number of nodes
|
int nnode; // number of nodes
|
||||||
int nedge; // number of edges
|
int nedge; // number of edges
|
||||||
int nelem; // number of elements
|
int nelem; // number of elements
|
||||||
|
|||||||
@@ -2585,5 +2585,20 @@ TEST_F(MujocoTest, SetFrameReverseOrder) {
|
|||||||
mj_deleteSpec(copy);
|
mj_deleteSpec(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MujocoTest, UserValue) {
|
||||||
|
mjSpec* spec = mj_makeSpec();
|
||||||
|
EXPECT_THAT(spec, NotNull());
|
||||||
|
mjsBody* body = mjs_addBody(mjs_findBody(spec, "world"), nullptr);
|
||||||
|
EXPECT_THAT(body, NotNull());
|
||||||
|
std::string data = "data";
|
||||||
|
mjs_setUserValue(body->element, "key", data.data());
|
||||||
|
EXPECT_THAT(mjs_getUserValue(body->element, "invalid_key"), IsNull());
|
||||||
|
const void* payload = mjs_getUserValue(body->element, "key");
|
||||||
|
EXPECT_STREQ(static_cast<const char*>(payload), data.c_str());
|
||||||
|
mjs_deleteUserValue(body->element, "key");
|
||||||
|
EXPECT_THAT(mjs_getUserValue(body->element, "key"), IsNull());
|
||||||
|
mj_deleteSpec(spec);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
Reference in New Issue
Block a user