# Visualize programmed perturbations

Discussion in 'Visualization' started by Jonathan Vorndamme, Nov 8, 2019.

1. Hello,

I would like visualize cartesian forces (external perturbations, I somehow generate to test controllers etc.) on bodies in the simulation with an arrow similar to the contact force visualization. How can I achieve this? I assume, I could use mjv_applyPerturbForce, and the perturbance force visualization for that, but I would need to know, how to specify the force and tmoments correctly. Also this does not seem to be usage as it was meant to be.

Best Jonathan

2. Hi Jonathan, I suggest for you to use mj_applyFT for external perturbation forces. Did you solve your visualization issue? I have the same problem for visualization part.

Best Gokce

3. You could use the perturbation data structure to apply a perturbation and visualise it: http://www.mujoco.org/book/programming.html#viPerturb

But to asnwer you question, since we might want to visualise other forces or other arrows. You could add abstract shapes to your scene and control their shape (see this older question). A very basic example:

This example relied on an actuator with a fixed axis. It shouldn't be hard to turn this into a function that only needs a single vector as input.

Code:
```// ...

mjv_updateScene(m, d, &(viewer.opt), NULL, &(viewer.cam), mjCAT_ALL, &(viewer.scn));

double force = ... // From some computation maybe

mjvGeom* arrow = viewer.scn.geoms + viewer.scn.ngeom;
makeArrow(arrow);
viewer.scn.ngeom++;

arrow->size = abs(force) * 0.01;
mjtNum quat, mat;
mjtNum axis = {0.0, 1.0, 0.0};
mju_axisAngle2Quat(quat, axis, 0.5 * mjPI * ((force > 0) ? 1 : -1));
mju_quat2Mat(mat, quat);
mju_n2f(arrow->mat, mat, 9);

mjr_render(m, d);

// ...
```
Code:
```/**
* Turn geom pointer into an arrow
*
* Set type, color, postion etc.
* Rotation still has to be set! Without it, it won't appear at all
*/
void makeArrow(mjvGeom* arrow)
{
arrow->type = mjGEOM_ARROW;
arrow->dataid = -1;
arrow->objtype = mjOBJ_SITE;
arrow->objid = -1;
arrow->category = mjCAT_DECOR;
arrow->texid = -1;
arrow->texuniform = 0;
arrow->texrepeat = 1;
arrow->texrepeat = 1;
arrow->emission = 0;
arrow->specular = 0.5;
arrow->shininess = 0.5;
arrow->reflectance = 0;
arrow->label = 0;
arrow->size = 0.02f;
arrow->size = 0.02f;
arrow->size = 1.0f;
arrow->rgba = 1.0f;
arrow->rgba = 0.1f;
arrow->rgba = 0.1f;
arrow->rgba = 1.0f;
arrow->pos = 0.0f;
arrow->pos = 0.0f;
arrow->pos = 0.5f;
}
```