Improved behaviour of mouse-spring interactions.
Also:
- Renamed recently introduced `mjvPerturb` member `reflocalpos` -> `refselpos` and corrected docstring.
- Added `mjvPerturb.localmass`: body spatial inertia at selection point.
- Removed `const` qualifier to `mjData` argument of `mjv_initPerturb()`, to facilitate spatial inertia computation.
- Improved `mj_Object{Velocity, Acceleration}` docstrings, clarifying that rotational velocities precede linear velocities.
- Removed redundant const qualifiers from non pointer arguments to `mju_dot` and `mju_writeNumBytes`.
PiperOrigin-RevId: 511002168
Change-Id: I27400f497947f330072d4abb7c9bf7e71e6c5d49
This commit is contained in:
committed by
Copybara-Service
parent
9756ed0d80
commit
7542c90cd2
@@ -1029,7 +1029,7 @@ mj_objectVelocity
|
|||||||
|
|
||||||
.. mujoco-include:: mj_objectVelocity
|
.. mujoco-include:: mj_objectVelocity
|
||||||
|
|
||||||
Compute object 6D velocity in object-centered frame, world/local orientation.
|
Compute object 6D velocity (rot:lin) in object-centered frame, world/local orientation.
|
||||||
|
|
||||||
.. _mj_objectAcceleration:
|
.. _mj_objectAcceleration:
|
||||||
|
|
||||||
@@ -1038,7 +1038,7 @@ mj_objectAcceleration
|
|||||||
|
|
||||||
.. mujoco-include:: mj_objectAcceleration
|
.. mujoco-include:: mj_objectAcceleration
|
||||||
|
|
||||||
Compute object 6D acceleration in object-centered frame, world/local orientation.
|
Compute object 6D acceleration (rot:lin) in object-centered frame, world/local orientation.
|
||||||
|
|
||||||
.. _mj_contactForce:
|
.. _mj_contactForce:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ Bug fixes
|
|||||||
:align: right
|
:align: right
|
||||||
:width: 300px
|
:width: 300px
|
||||||
|
|
||||||
#. The ``launch_repl`` functionality in the Python viewer has been fixed.
|
6. The ``launch_repl`` functionality in the Python viewer has been fixed.
|
||||||
#. Set ``time`` correctly in ``mjd_transitionFD``, to support time-dependent user code.
|
#. Set ``time`` correctly in ``mjd_transitionFD``, to support time-dependent user code.
|
||||||
#. Fixed sensor data dimension validation when ``user`` type sensors are present.
|
#. Fixed sensor data dimension validation when ``user`` type sensors are present.
|
||||||
#. Fixed incorrect plugin error message when a null ``nsensordata`` callback is encountered during model compilation.
|
#. Fixed incorrect plugin error message when a null ``nsensordata`` callback is encountered during model compilation.
|
||||||
|
|||||||
@@ -1641,8 +1641,9 @@ struct mjvPerturb_ { // object selection and perturbation
|
|||||||
int active2; // secondary perturbation bitmask (mjtPertBit)
|
int active2; // secondary perturbation bitmask (mjtPertBit)
|
||||||
mjtNum refpos[3]; // reference position for selected object
|
mjtNum refpos[3]; // reference position for selected object
|
||||||
mjtNum refquat[4]; // reference orientation for selected object
|
mjtNum refquat[4]; // reference orientation for selected object
|
||||||
mjtNum reflocalpos[3]; // reference selection point in object coordinates
|
mjtNum refselpos[3]; // reference position for selection point
|
||||||
mjtNum localpos[3]; // selection point in object coordinates
|
mjtNum localpos[3]; // selection point in object coordinates
|
||||||
|
mjtNum localmass; // spatial inertia at selection point
|
||||||
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
|
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
|
||||||
};
|
};
|
||||||
typedef struct mjvPerturb_ mjvPerturb;
|
typedef struct mjvPerturb_ mjvPerturb;
|
||||||
@@ -1973,8 +1974,7 @@ void mjv_movePerturb(const mjModel* m, const mjData* d, int action, mjtNum reldx
|
|||||||
mjtNum reldy, const mjvScene* scn, mjvPerturb* pert);
|
mjtNum reldy, const mjvScene* scn, mjvPerturb* pert);
|
||||||
void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reldy,
|
void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reldy,
|
||||||
const mjtNum roomup[3], mjvScene* scn);
|
const mjtNum roomup[3], mjvScene* scn);
|
||||||
void mjv_initPerturb(const mjModel* m, const mjData* d,
|
void mjv_initPerturb(const mjModel* m, mjData* d, const mjvScene* scn, mjvPerturb* pert);
|
||||||
const mjvScene* scn, mjvPerturb* pert);
|
|
||||||
void mjv_applyPerturbPose(const mjModel* m, mjData* d, const mjvPerturb* pert,
|
void mjv_applyPerturbPose(const mjModel* m, mjData* d, const mjvPerturb* pert,
|
||||||
int flg_paused);
|
int flg_paused);
|
||||||
void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert);
|
void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert);
|
||||||
@@ -2087,7 +2087,7 @@ void mju_addToScl(mjtNum* res, const mjtNum* vec, mjtNum scl, int n);
|
|||||||
void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n);
|
void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n);
|
||||||
mjtNum mju_normalize(mjtNum* res, int n);
|
mjtNum mju_normalize(mjtNum* res, int n);
|
||||||
mjtNum mju_norm(const mjtNum* res, int n);
|
mjtNum mju_norm(const mjtNum* res, int n);
|
||||||
mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n);
|
mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, int n);
|
||||||
void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||||
void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||||
mjtNum mju_mulVecMatVec(const mjtNum* vec1, const mjtNum* mat, const mjtNum* vec2, int n);
|
mjtNum mju_mulVecMatVec(const mjtNum* vec1, const mjtNum* mat, const mjtNum* vec2, int n);
|
||||||
@@ -2146,7 +2146,7 @@ mjtNum mju_sign(mjtNum x);
|
|||||||
int mju_round(mjtNum x);
|
int mju_round(mjtNum x);
|
||||||
const char* mju_type2Str(int type);
|
const char* mju_type2Str(int type);
|
||||||
int mju_str2Type(const char* str);
|
int mju_str2Type(const char* str);
|
||||||
const char* mju_writeNumBytes(const size_t nbytes);
|
const char* mju_writeNumBytes(size_t nbytes);
|
||||||
const char* mju_warningText(int warning, size_t info);
|
const char* mju_warningText(int warning, size_t info);
|
||||||
int mju_isBad(mjtNum x);
|
int mju_isBad(mjtNum x);
|
||||||
int mju_isZero(mjtNum* vec, int n);
|
int mju_isZero(mjtNum* vec, int n);
|
||||||
|
|||||||
@@ -157,8 +157,9 @@ struct mjvPerturb_ { // object selection and perturbation
|
|||||||
int active2; // secondary perturbation bitmask (mjtPertBit)
|
int active2; // secondary perturbation bitmask (mjtPertBit)
|
||||||
mjtNum refpos[3]; // reference position for selected object
|
mjtNum refpos[3]; // reference position for selected object
|
||||||
mjtNum refquat[4]; // reference orientation for selected object
|
mjtNum refquat[4]; // reference orientation for selected object
|
||||||
mjtNum reflocalpos[3]; // reference selection point in object coordinates
|
mjtNum refselpos[3]; // reference position for selection point
|
||||||
mjtNum localpos[3]; // selection point in object coordinates
|
mjtNum localpos[3]; // selection point in object coordinates
|
||||||
|
mjtNum localmass; // spatial inertia at selection point
|
||||||
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
|
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
|
||||||
};
|
};
|
||||||
typedef struct mjvPerturb_ mjvPerturb;
|
typedef struct mjvPerturb_ mjvPerturb;
|
||||||
|
|||||||
@@ -423,11 +423,11 @@ MJAPI void mj_addM(const mjModel* m, mjData* d, mjtNum* dst, int* rownnz, int* r
|
|||||||
MJAPI void mj_applyFT(const mjModel* m, mjData* d, const mjtNum force[3], const mjtNum torque[3],
|
MJAPI void mj_applyFT(const mjModel* m, mjData* d, const mjtNum force[3], const mjtNum torque[3],
|
||||||
const mjtNum point[3], int body, mjtNum* qfrc_target);
|
const mjtNum point[3], int body, mjtNum* qfrc_target);
|
||||||
|
|
||||||
// Compute object 6D velocity in object-centered frame, world/local orientation.
|
// Compute object 6D velocity (rot:lin) in object-centered frame, world/local orientation.
|
||||||
MJAPI void mj_objectVelocity(const mjModel* m, const mjData* d,
|
MJAPI void mj_objectVelocity(const mjModel* m, const mjData* d,
|
||||||
int objtype, int objid, mjtNum res[6], int flg_local);
|
int objtype, int objid, mjtNum res[6], int flg_local);
|
||||||
|
|
||||||
// Compute object 6D acceleration in object-centered frame, world/local orientation.
|
// Compute object 6D acceleration (rot:lin) in object-centered frame, world/local orientation.
|
||||||
MJAPI void mj_objectAcceleration(const mjModel* m, const mjData* d,
|
MJAPI void mj_objectAcceleration(const mjModel* m, const mjData* d,
|
||||||
int objtype, int objid, mjtNum res[6], int flg_local);
|
int objtype, int objid, mjtNum res[6], int flg_local);
|
||||||
|
|
||||||
@@ -546,8 +546,7 @@ MJAPI void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reld
|
|||||||
const mjtNum roomup[3], mjvScene* scn);
|
const mjtNum roomup[3], mjvScene* scn);
|
||||||
|
|
||||||
// Copy perturb pos,quat from selected body; set scale for perturbation.
|
// Copy perturb pos,quat from selected body; set scale for perturbation.
|
||||||
MJAPI void mjv_initPerturb(const mjModel* m, const mjData* d,
|
MJAPI void mjv_initPerturb(const mjModel* m, mjData* d, const mjvScene* scn, mjvPerturb* pert);
|
||||||
const mjvScene* scn, mjvPerturb* pert);
|
|
||||||
|
|
||||||
// Set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise.
|
// Set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise.
|
||||||
// Write d->qpos only if flg_paused and subtree root for selected body has free joint.
|
// Write d->qpos only if flg_paused and subtree root for selected body has free joint.
|
||||||
@@ -919,7 +918,7 @@ MJAPI mjtNum mju_normalize(mjtNum* res, int n);
|
|||||||
MJAPI mjtNum mju_norm(const mjtNum* res, int n);
|
MJAPI mjtNum mju_norm(const mjtNum* res, int n);
|
||||||
|
|
||||||
// Return dot-product of vec1 and vec2.
|
// Return dot-product of vec1 and vec2.
|
||||||
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n);
|
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, int n);
|
||||||
|
|
||||||
// Multiply matrix and vector: res = mat * vec.
|
// Multiply matrix and vector: res = mat * vec.
|
||||||
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||||
@@ -1104,7 +1103,7 @@ MJAPI const char* mju_type2Str(int type);
|
|||||||
MJAPI int mju_str2Type(const char* str);
|
MJAPI int mju_str2Type(const char* str);
|
||||||
|
|
||||||
// Return human readable number of bytes using standard letter suffix.
|
// Return human readable number of bytes using standard letter suffix.
|
||||||
MJAPI const char* mju_writeNumBytes(const size_t nbytes);
|
MJAPI const char* mju_writeNumBytes(size_t nbytes);
|
||||||
|
|
||||||
// Construct a warning message given the warning type and info.
|
// Construct a warning message given the warning type and info.
|
||||||
MJAPI const char* mju_warningText(int warning, size_t info);
|
MJAPI const char* mju_warningText(int warning, size_t info);
|
||||||
|
|||||||
@@ -2432,7 +2432,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Compute object 6D velocity in object-centered frame, world/local orientation.', # pylint: disable=line-too-long
|
doc='Compute object 6D velocity (rot:lin) in object-centered frame, world/local orientation.', # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
('mj_objectAcceleration',
|
('mj_objectAcceleration',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -2471,7 +2471,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Compute object 6D acceleration in object-centered frame, world/local orientation.', # pylint: disable=line-too-long
|
doc='Compute object 6D acceleration (rot:lin) in object-centered frame, world/local orientation.', # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
('mj_contactForce',
|
('mj_contactForce',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -3353,7 +3353,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
FunctionParameterDecl(
|
FunctionParameterDecl(
|
||||||
name='d',
|
name='d',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjData', is_const=True),
|
inner_type=ValueType(name='mjData'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FunctionParameterDecl(
|
FunctionParameterDecl(
|
||||||
@@ -5651,7 +5651,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
FunctionParameterDecl(
|
FunctionParameterDecl(
|
||||||
name='n',
|
name='n',
|
||||||
type=ValueType(name='int', is_const=True),
|
type=ValueType(name='int'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Return dot-product of vec1 and vec2.',
|
doc='Return dot-product of vec1 and vec2.',
|
||||||
@@ -6978,7 +6978,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
parameters=(
|
parameters=(
|
||||||
FunctionParameterDecl(
|
FunctionParameterDecl(
|
||||||
name='nbytes',
|
name='nbytes',
|
||||||
type=ValueType(name='size_t', is_const=True),
|
type=ValueType(name='size_t'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Return human readable number of bytes using standard letter suffix.', # pylint: disable=line-too-long
|
doc='Return human readable number of bytes using standard letter suffix.', # pylint: disable=line-too-long
|
||||||
|
|||||||
@@ -627,7 +627,7 @@ mjtNum mju_norm(const mjtNum* res, int n) {
|
|||||||
|
|
||||||
|
|
||||||
// vector dot-product
|
// vector dot-product
|
||||||
mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n) {
|
mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, int n) {
|
||||||
mjtNum res = 0;
|
mjtNum res = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int n_4 = n - 4;
|
int n_4 = n - 4;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ MJAPI mjtNum mju_normalize(mjtNum* res, int n);
|
|||||||
MJAPI mjtNum mju_norm(const mjtNum* res, int n);
|
MJAPI mjtNum mju_norm(const mjtNum* res, int n);
|
||||||
|
|
||||||
// vector dot-product
|
// vector dot-product
|
||||||
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n);
|
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, int n);
|
||||||
|
|
||||||
|
|
||||||
//------------------------------ matrix-vector operations ------------------------------------------
|
//------------------------------ matrix-vector operations ------------------------------------------
|
||||||
|
|||||||
@@ -947,7 +947,7 @@ int mju_str2Type(const char* str) {
|
|||||||
|
|
||||||
|
|
||||||
// return human readable number of bytes using standard letter suffix
|
// return human readable number of bytes using standard letter suffix
|
||||||
const char* mju_writeNumBytes(const size_t nbytes) {
|
const char* mju_writeNumBytes(size_t nbytes) {
|
||||||
int i;
|
int i;
|
||||||
static mjTHREADLOCAL char message[20];
|
static mjTHREADLOCAL char message[20];
|
||||||
static const char suffix[] = " KMGTPE";
|
static const char suffix[] = " KMGTPE";
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ MJAPI const char* mju_type2Str(int type);
|
|||||||
MJAPI int mju_str2Type(const char* str);
|
MJAPI int mju_str2Type(const char* str);
|
||||||
|
|
||||||
// return human readable number of bytes using standard letter suffix
|
// return human readable number of bytes using standard letter suffix
|
||||||
MJAPI const char* mju_writeNumBytes(const size_t nbytes);
|
MJAPI const char* mju_writeNumBytes(size_t nbytes);
|
||||||
|
|
||||||
// warning text
|
// warning text
|
||||||
MJAPI const char* mju_warningText(int warning, size_t info);
|
MJAPI const char* mju_warningText(int warning, size_t info);
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
#include <mujoco/mjexport.h>
|
#include <mujoco/mjexport.h>
|
||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
|
#include "engine/engine_core_smooth.h"
|
||||||
|
#include "engine/engine_io.h"
|
||||||
|
#include "engine/engine_macro.h"
|
||||||
#include "engine/engine_ray.h"
|
#include "engine/engine_ray.h"
|
||||||
#include "engine/engine_support.h"
|
#include "engine/engine_support.h"
|
||||||
#include "engine/engine_util_blas.h"
|
#include "engine/engine_util_blas.h"
|
||||||
@@ -385,7 +388,7 @@ void mjv_movePerturb(const mjModel* m, const mjData* d, int action, mjtNum reldx
|
|||||||
case mjMOUSE_MOVE_V:
|
case mjMOUSE_MOVE_V:
|
||||||
case mjMOUSE_MOVE_H:
|
case mjMOUSE_MOVE_H:
|
||||||
mju_addToScl3(pert->refpos, vec, pert->scale);
|
mju_addToScl3(pert->refpos, vec, pert->scale);
|
||||||
mju_addToScl3(pert->reflocalpos, vec, pert->scale);
|
mju_addToScl3(pert->refselpos, vec, pert->scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjMOUSE_ROTATE_V:
|
case mjMOUSE_ROTATE_V:
|
||||||
@@ -514,10 +517,16 @@ void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reldy,
|
|||||||
|
|
||||||
|
|
||||||
// copy perturb pos,quat from selected body; set scale for perturbation
|
// copy perturb pos,quat from selected body; set scale for perturbation
|
||||||
void mjv_initPerturb(const mjModel* m, const mjData* d, const mjvScene* scn, mjvPerturb* pert) {
|
void mjv_initPerturb(const mjModel* m, mjData* d, const mjvScene* scn, mjvPerturb* pert) {
|
||||||
|
mjMARKSTACK;
|
||||||
|
|
||||||
|
int nv = m->nv;
|
||||||
int sel = pert->select;
|
int sel = pert->select;
|
||||||
mjtNum headpos[3], forward[3], dif[3];
|
mjtNum headpos[3], forward[3], dif[3];
|
||||||
|
|
||||||
|
mjtNum* jac = mj_stackAlloc(d, 3*nv);
|
||||||
|
mjtNum* jacM2 = mj_stackAlloc(d, 3*nv);
|
||||||
|
|
||||||
// invalid selected body: return
|
// invalid selected body: return
|
||||||
if (sel<=0 || sel>=m->nbody) {
|
if (sel<=0 || sel>=m->nbody) {
|
||||||
return;
|
return;
|
||||||
@@ -528,25 +537,34 @@ void mjv_initPerturb(const mjModel* m, const mjData* d, const mjvScene* scn, mjv
|
|||||||
mju_rotVecMat(selpos, pert->localpos, d->xmat+9*sel);
|
mju_rotVecMat(selpos, pert->localpos, d->xmat+9*sel);
|
||||||
mju_addTo3(selpos, d->xpos+3*sel);
|
mju_addTo3(selpos, d->xpos+3*sel);
|
||||||
|
|
||||||
|
// compute average spatial inertia at selection point
|
||||||
|
mj_jac(m, d, jac, NULL, selpos, sel);
|
||||||
|
mj_solveM2(m, d, jacM2, jac, 3);
|
||||||
|
mjtNum invmass = mju_dot(jacM2+0*nv, jacM2+0*nv, nv) +
|
||||||
|
mju_dot(jacM2+1*nv, jacM2+1*nv, nv) +
|
||||||
|
mju_dot(jacM2+2*nv, jacM2+2*nv, nv);
|
||||||
|
pert->localmass = 3 / mju_max(invmass, mjMINVAL);
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
mju_copy3(pert->refpos, d->xipos+3*sel);
|
mju_copy3(pert->refpos, d->xipos+3*sel);
|
||||||
mju_mulQuat(pert->refquat, d->xquat+4*sel, m->body_iquat+4*sel);
|
mju_mulQuat(pert->refquat, d->xquat+4*sel, m->body_iquat+4*sel);
|
||||||
mju_copy3(pert->reflocalpos, selpos);
|
mju_copy3(pert->refselpos, selpos);
|
||||||
|
|
||||||
// get camera info
|
// get camera info
|
||||||
mjv_cameraInModel(headpos, forward, NULL, scn);
|
mjv_cameraInModel(headpos, forward, NULL, scn);
|
||||||
|
|
||||||
// compute scaling: rendered pert->refpos displacement = mouse displacement
|
// compute scaling: rendered pert->refselpos displacement = mouse displacement
|
||||||
mju_sub3(dif, pert->reflocalpos, headpos);
|
mju_sub3(dif, pert->refselpos, headpos);
|
||||||
pert->scale = mjv_frustumHeight(scn) * mju_dot3(dif, forward);
|
pert->scale = mjv_frustumHeight(scn) * mju_dot3(dif, forward);
|
||||||
|
|
||||||
|
mjFREESTACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise
|
// set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise
|
||||||
// d->qpos written only if flg_paused and subtree root for selected body has free joint
|
// d->qpos written only if flg_paused and subtree root for selected body has free joint
|
||||||
void mjv_applyPerturbPose(const mjModel* m, mjData* d, const mjvPerturb* pert,
|
void mjv_applyPerturbPose(const mjModel* m, mjData* d, const mjvPerturb* pert, int flg_paused) {
|
||||||
int flg_paused) {
|
|
||||||
int rootid = 0, sel = pert->select;
|
int rootid = 0, sel = pert->select;
|
||||||
mjtNum pos1[3], quat1[4], pos2[3], quat2[4], refpos[3], refquat[4];
|
mjtNum pos1[3], quat1[4], pos2[3], quat2[4], refpos[3], refquat[4];
|
||||||
mjtNum *Rpos, *Rquat, *Cpos, *Cquat;
|
mjtNum *Rpos, *Rquat, *Cpos, *Cquat;
|
||||||
@@ -600,7 +618,6 @@ void mjv_applyPerturbPose(const mjModel* m, mjData* d, const mjvPerturb* pert,
|
|||||||
|
|
||||||
// set perturb force,torque in d->xfrc_applied, if selected body is dynamic
|
// set perturb force,torque in d->xfrc_applied, if selected body is dynamic
|
||||||
void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert) {
|
void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert) {
|
||||||
mjtNum xiquat[4], difquat[4], bvel[6], mass, stiffness, *result;
|
|
||||||
int sel = pert->select;
|
int sel = pert->select;
|
||||||
|
|
||||||
// exit if nothing to do
|
// exit if nothing to do
|
||||||
@@ -608,11 +625,18 @@ void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get pointer to body xfrc_applied
|
// pointers to body xfrc_applied, force and torque
|
||||||
result = d->xfrc_applied + 6*sel;
|
mjtNum *force = d->xfrc_applied + 6*sel;
|
||||||
|
mjtNum *torque = d->xfrc_applied + 6*sel + 3;
|
||||||
|
|
||||||
// global selbody velocity
|
// pointers to global selbody velocity, linear and rotational
|
||||||
|
mjtNum bvel[6];
|
||||||
mj_objectVelocity(m, d, mjOBJ_BODY, sel, bvel, 0);
|
mj_objectVelocity(m, d, mjOBJ_BODY, sel, bvel, 0);
|
||||||
|
mjtNum *body_linvel = bvel + 3;
|
||||||
|
mjtNum *body_rotvel = bvel;
|
||||||
|
|
||||||
|
// body rotational inertia
|
||||||
|
mjtNum inertia = 1.0/mju_max(mjMINVAL, m->body_invweight0[2*sel+1]);
|
||||||
|
|
||||||
if (((pert->active | pert->active2) & mjPERT_TRANSLATE)) {
|
if (((pert->active | pert->active2) & mjPERT_TRANSLATE)) {
|
||||||
// compute selection point in world coordinates
|
// compute selection point in world coordinates
|
||||||
@@ -620,33 +644,45 @@ void mjv_applyPerturbForce(const mjModel* m, mjData* d, const mjvPerturb* pert)
|
|||||||
mju_rotVecMat(selpos, pert->localpos, d->xmat+9*sel);
|
mju_rotVecMat(selpos, pert->localpos, d->xmat+9*sel);
|
||||||
mju_addTo3(selpos, d->xpos+3*sel);
|
mju_addTo3(selpos, d->xpos+3*sel);
|
||||||
|
|
||||||
// spring perturbation force, with critical damping
|
// displacement of selection point from reference point
|
||||||
stiffness = m->vis.map.stiffness;
|
mjtNum diff[3];
|
||||||
mass = 1.0/mju_max(mjMINVAL, m->body_invweight0[2*sel]);
|
mju_sub3(diff, selpos, pert->refselpos);
|
||||||
mju_sub3(result, pert->reflocalpos, selpos);
|
|
||||||
mju_scl3(result, result, stiffness*mass);
|
|
||||||
mju_addToScl3(result, bvel+3, -sqrtf(stiffness)*mass);
|
|
||||||
|
|
||||||
// torque w.r.t body com
|
// spring perturbation force
|
||||||
mju_subFrom3(selpos, d->xipos+3*sel);
|
mjtNum stiffness = m->vis.map.stiffness;
|
||||||
mju_cross(result+3, selpos, result);
|
mju_copy3(force, diff);
|
||||||
|
mju_scl3(force, force, -stiffness*pert->localmass);
|
||||||
|
|
||||||
// add critically damped torque (torsional only)
|
// moment arm w.r.t body com
|
||||||
|
mjtNum moment_arm[3];
|
||||||
|
mju_sub3(moment_arm, selpos, d->xipos+3*sel);
|
||||||
|
|
||||||
|
// translational velocity of selection point
|
||||||
|
mjtNum svel[3];
|
||||||
|
mju_cross(svel, body_rotvel, moment_arm);
|
||||||
|
mju_addTo3(svel, body_linvel);
|
||||||
|
|
||||||
|
// add critical damping force of selection point
|
||||||
|
mju_addToScl3(force, svel, -sqrtf(stiffness)*pert->localmass);
|
||||||
|
|
||||||
|
// torque on body com due to force
|
||||||
|
mju_cross(torque, moment_arm, force);
|
||||||
|
|
||||||
|
// add critically damped torsional torque along displacement axis
|
||||||
stiffness = m->vis.map.stiffnessrot;
|
stiffness = m->vis.map.stiffnessrot;
|
||||||
mass = 1.0/mju_max(mjMINVAL, m->body_invweight0[2*sel+1]);
|
mju_normalize3(diff);
|
||||||
mju_normalize3(selpos);
|
mju_addToScl3(torque, diff, -sqrtf(stiffness)*inertia*mju_dot3(diff, body_rotvel));
|
||||||
mju_addToScl3(result+3, selpos, -sqrtf(stiffness)*mass*mju_dot3(selpos, bvel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((pert->active | pert->active2) & mjPERT_ROTATE)) {
|
if (((pert->active | pert->active2) & mjPERT_ROTATE)) {
|
||||||
// spring perturbation torque, with critical damping
|
// spring perturbation torque, with critical damping
|
||||||
stiffness = m->vis.map.stiffnessrot;
|
mjtNum stiffness = m->vis.map.stiffnessrot;
|
||||||
mass = 1.0/mju_max(mjMINVAL, m->body_invweight0[2*sel+1]);
|
mjtNum xiquat[4], difquat[4];
|
||||||
mju_mulQuat(xiquat, d->xquat+4*sel, m->body_iquat+4*sel);
|
mju_mulQuat(xiquat, d->xquat+4*sel, m->body_iquat+4*sel);
|
||||||
mju_negQuat(xiquat, xiquat);
|
mju_negQuat(xiquat, xiquat);
|
||||||
mju_mulQuat(difquat, pert->refquat, xiquat);
|
mju_mulQuat(difquat, pert->refquat, xiquat);
|
||||||
mju_quat2Vel(result+3, difquat, 1.0/(stiffness*mass));
|
mju_quat2Vel(torque, difquat, 1.0/(stiffness*inertia));
|
||||||
mju_addToScl3(result+3, bvel, -sqrtf(stiffness)*mass);
|
mju_addToScl3(torque, body_rotvel, -sqrtf(stiffness)*inertia);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ MJAPI void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reld
|
|||||||
const mjtNum roomup[3], mjvScene* scn);
|
const mjtNum roomup[3], mjvScene* scn);
|
||||||
|
|
||||||
// copy perturb pos,quat from selected body; set scale perturbation
|
// copy perturb pos,quat from selected body; set scale perturbation
|
||||||
MJAPI void mjv_initPerturb(const mjModel* m, const mjData* d,
|
MJAPI void mjv_initPerturb(const mjModel* m, mjData* d, const mjvScene* scn, mjvPerturb* pert);
|
||||||
const mjvScene* scn, mjvPerturb* pert);
|
|
||||||
|
|
||||||
// set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise
|
// set perturb pos,quat in d->mocap when selected body is mocap, and in d->qpos otherwise
|
||||||
// d->qpos written only if flg_paused and subtree root for selected body has free joint
|
// d->qpos written only if flg_paused and subtree root for selected body has free joint
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
|
|||||||
sz[0] = scl * m->vis.scale.constraint;
|
sz[0] = scl * m->vis.scale.constraint;
|
||||||
mjv_makeConnector(thisgeom, mjGEOM_CAPSULE, sz[0],
|
mjv_makeConnector(thisgeom, mjGEOM_CAPSULE, sz[0],
|
||||||
selpos[0], selpos[1], selpos[2],
|
selpos[0], selpos[1], selpos[2],
|
||||||
pert->reflocalpos[0], pert->reflocalpos[1], pert->reflocalpos[2]);
|
pert->refselpos[0], pert->refselpos[1], pert->refselpos[2]);
|
||||||
|
|
||||||
// prepare color
|
// prepare color
|
||||||
mixcolor(rgba, m->vis.rgba.constraint,
|
mixcolor(rgba, m->vis.rgba.constraint,
|
||||||
@@ -605,7 +605,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
|
|||||||
sz[0] = 2*sz[0];
|
sz[0] = 2*sz[0];
|
||||||
sz[1] = sz[2] = sz[0];
|
sz[1] = sz[2] = sz[0];
|
||||||
mju_quat2Mat(mat, pert->refquat);
|
mju_quat2Mat(mat, pert->refquat);
|
||||||
mjv_initGeom(thisgeom, mjGEOM_SPHERE, sz, pert->reflocalpos, mat, rgba);
|
mjv_initGeom(thisgeom, mjGEOM_SPHERE, sz, pert->refselpos, mat, rgba);
|
||||||
|
|
||||||
FINISH
|
FINISH
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+18
-5
@@ -1,24 +1,37 @@
|
|||||||
<mujoco>
|
<mujoco>
|
||||||
|
<visual>
|
||||||
|
<scale constraint="0.02"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<light pos="0 0 3"/>
|
<light pos="0 0 3"/>
|
||||||
<geom type="plane" size="1 1 .01"/>
|
<geom type="plane" size="1 1 .01"/>
|
||||||
|
|
||||||
<body pos="0 0 1" quat="0 0.534522 0.801784 0.267261">
|
<body name="non-diag inertia" pos="0 0 1" quat="0 0.534522 0.801784 0.267261">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<geom type="box" size="0.15 0.1 0.05" pos="0.15 0.1 0.05" euler="30 30 30" rgba="1 0 0 1"/>
|
<geom type="box" size="0.15 0.1 0.05" pos="0.15 0.1 0.05" euler="30 30 30" rgba="1 0 0 1"/>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<body pos="0 0 2" quat="0 0.534522 0.801784 0.267261">
|
<body name="diagonal inertia" pos="0 0 2" quat="0 0.534522 0.801784 0.267261">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<geom type="box" size="0.15 0.1 0.05" rgba="0 0 1 1"/>
|
<geom type="box" size="0.15 0.1 0.05" rgba="0 0 1 1"/>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<body pos="-.5 -.5 .5" mocap="true" quat=".1 .2 .3 .4">
|
<body name="mocap body" pos="-.5 -.5 .5" mocap="true" quat=".1 .2 .3 .4">
|
||||||
<geom type="box" size="0.15 0.1 0.05" pos="0.15 0.1 0.05" euler="30 30 30" rgba="0 .7 0 1"/>
|
<geom type="box" size="0.15 0.1 0.05" pos="0.15 0.1 0.05" euler="30 30 30" rgba="0 .7 0 1"/>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- TODO(b/266543914): Fix force perurbation on ball joints -->
|
<body name="small sphere" pos="-0.4 0.4 0.2">
|
||||||
<body pos=".5 -.5 .5" >
|
<freejoint/>
|
||||||
|
<geom type="sphere" size="0.01" rgba="1 1 1 1"/>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<body name="heavy sphere" pos="-0.5 0.4 0.2">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="sphere" size="0.02" rgba="1 1 1 1" mass="1000"/>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<body name="ball joint" pos=".5 -.5 .5" >
|
||||||
<joint type="ball" damping="10"/>
|
<joint type="ball" damping="10"/>
|
||||||
<geom type="box" size="0.1 0.1 0.1"/>
|
<geom type="box" size="0.1 0.1 0.1"/>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -2472,8 +2472,9 @@ public unsafe struct mjvPerturb_ {
|
|||||||
public int active2;
|
public int active2;
|
||||||
public fixed double refpos[3];
|
public fixed double refpos[3];
|
||||||
public fixed double refquat[4];
|
public fixed double refquat[4];
|
||||||
public fixed double reflocalpos[3];
|
public fixed double refselpos[3];
|
||||||
public fixed double localpos[3];
|
public fixed double localpos[3];
|
||||||
|
public double localmass;
|
||||||
public double scale;
|
public double scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user