Skip to content

Commit e9da6d6

Browse files
author
hephaestus
committed
Add printing of the names of the links
1 parent 628453a commit e9da6d6

File tree

2 files changed

+87
-56
lines changed

2 files changed

+87
-56
lines changed

src/main/java/org/mujoco/MuJoCoModelManager.java

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.net.URL;
88

99
import org.bytedeco.javacpp.BytePointer;
10+
import org.bytedeco.javacpp.IntPointer;
1011
import org.mujoco.MuJoCoLib.mjData;
1112
import org.mujoco.MuJoCoLib.mjData_;
1213
import org.mujoco.MuJoCoLib.mjModel;
@@ -19,10 +20,16 @@ public class MuJoCoModelManager {
1920

2021
private mjModel m;
2122
private mjData d;
22-
private mjModel_ maccessable;
23-
private mjData_ daccessable;
23+
private mjModel_ model;
24+
private mjData_ data;
2425
private mjOption_ opt;
2526
private IMujocoController controller = null;
27+
28+
private BytePointer modelNames;
29+
30+
private IntPointer jointNameIndexes;
31+
32+
private IntPointer bodyNameIndex;
2633
public MuJoCoModelManager(File config){
2734
loadFromFile(config);
2835
}
@@ -47,9 +54,37 @@ private void loadFromFile(File config) {
4754
setModel(new mjModel_(m));
4855
setData(new mjData_(d));
4956
setOpt(new mjOption_(getModel().opt()));
50-
57+
setModelNames(model.names());
58+
jointNameIndexes = model.name_jntadr();
59+
bodyNameIndex = model.name_bodyadr();
60+
}
61+
public double getCurrentSimulationTimeSeconds() {
62+
return data.time();
63+
}
64+
public int getNumberOfJoints() {
65+
return model.nu();
66+
}
67+
public String getJointName(int i) {
68+
if(i<0)
69+
throw new IndexOutOfBoundsException("Joint index must be positive or zero");
70+
if(i>=getNumberOfJoints()) {
71+
throw new IndexOutOfBoundsException("Joint index must be less than "+i);
72+
}
73+
BytePointer byp = modelNames.getPointer(jointNameIndexes.getPointer(i).get());
74+
return byp.getString();
75+
}
76+
public int getNumberOfBodys() {
77+
return model.nbody();
78+
}
79+
public String getBodyName(int i) {
80+
if(i<0)
81+
throw new IndexOutOfBoundsException("Body index must be positive or zero");
82+
if(i>=getNumberOfJoints()) {
83+
throw new IndexOutOfBoundsException("Body index must be less than "+i);
84+
}
85+
BytePointer byp = modelNames.getPointer(bodyNameIndex.getPointer(i).get());
86+
return byp.getString();
5187
}
52-
5388
public double getTimestepSeconds() {
5489
return getOpt().timestep();
5590
}
@@ -65,33 +100,33 @@ public void close() {
65100
* @return the maccessable
66101
*/
67102
public mjModel_ getModel() {
68-
return maccessable;
103+
return model;
69104
}
70105

71106
/**
72107
* @param maccessable the maccessable to set
73108
*/
74109
private void setModel(mjModel_ maccessable) {
75-
this.maccessable = maccessable;
110+
this.model = maccessable;
76111
}
77112

78113
/**
79114
* @return the daccessable
80115
*/
81116
public mjData_ getData() {
82-
return daccessable;
117+
return data;
83118
}
84119

85120
/**
86121
* @param daccessable the daccessable to set
87122
*/
88123
public void setData(mjData_ daccessable) {
89-
this.daccessable = daccessable;
124+
this.data = daccessable;
90125
}
91126
public void step() {
92127
stepOne();
93128
if(controller!=null)
94-
controller.controlStep(daccessable, maccessable);
129+
controller.controlStep(data, model);
95130
stepTwo();
96131
}
97132
public void stepOne() {
@@ -124,4 +159,16 @@ public IMujocoController getController() {
124159
public void setController(IMujocoController controller) {
125160
this.controller = controller;
126161
}
162+
/**
163+
* @return the modelNames
164+
*/
165+
public BytePointer getModelNames() {
166+
return modelNames;
167+
}
168+
/**
169+
* @param modelNames the modelNames to set
170+
*/
171+
public void setModelNames(BytePointer modelNames) {
172+
this.modelNames = modelNames;
173+
}
127174
}

src/test/java/mujoco/java/MuJoColibTest.java

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import java.io.File;
99

1010
import org.bytedeco.javacpp.BytePointer;
11+
import org.bytedeco.javacpp.IntPointer;
12+
import org.bytedeco.javacpp.Pointer;
1113
import org.junit.Test;
1214
import org.mujoco.IMujocoController;
1315
import org.mujoco.MuJoCoLib;
@@ -21,31 +23,54 @@
2123

2224
public class MuJoColibTest {
2325
IMujocoController controller = (d, m) -> {
24-
// apply controls https://mujoco.readthedocs.io/en/stable/programming/simulation.html#simulation-loop
25-
if( m.nu()==m.nv() )
26+
/**
27+
* This illustrates two concepts. First, we are checking
28+
* if the number of controls mjModel.nu equals the number
29+
* of DoFs mjModel.nv. In general, the same callback may
30+
* be used with multiple models depending on how the user
31+
* code is structured, and so it is a good idea to check
32+
* the model dimensions in the callback. Second, MuJoCo
33+
* has a library of BLAS-like functions that are very
34+
* useful; indeed a large part of the code base consists
35+
* of calling such functions internally. The mju_scl
36+
* function above scales the velocity vector mjData.qvel
37+
* by a constant feedback gain and copies the result into
38+
* the control vector mjData.ctrl.
39+
*/
40+
// apply controls
41+
// https://mujoco.readthedocs.io/en/stable/programming/simulation.html#simulation-loop
42+
if (m.nu() == m.nv())
2643
MuJoCoLib.mju_scl(d.ctrl(), d.qvel(), -0.1, m.nv());
2744
};
45+
2846
@Test
2947
public void managerTest() throws InterruptedException {
3048
System.out.println("managerTest");
3149
String filename = "model/humanoid/humanoid.xml";
3250
File file = new File(filename);
33-
if(!file.exists()) {
51+
if (!file.exists()) {
3452
fail("File is missing from the disk");
3553
}
3654
MuJoCoModelManager m = new MuJoCoModelManager(file);
37-
mjModel_ model = m.getModel();
38-
mjData_ data = m.getData();
3955
System.out.println("Run ModelManager for 10 seconds");
4056

57+
58+
for (int i = 0; i < m.getNumberOfJoints(); i++) {
59+
System.out.println(i + " link = " + m.getJointName(i));
60+
}
61+
for (int i = 0; i < m.getNumberOfBodys(); i++) {
62+
System.out.println(i + " Body = " + m.getBodyName(i));
63+
}
64+
4165
m.setController(controller);
42-
while (data.time() < 10) {
66+
while (m.getCurrentSimulationTimeSeconds() < 10) {
4367
m.step();
4468
// sleep
4569
Thread.sleep(m.getTimestepMilliSeconds());
4670
}
4771
m.close();
4872
}
73+
4974
@Test
5075
public void mujocoJNILoadTest() {
5176
System.out.println("mujocoJNILoadTest");
@@ -54,47 +79,6 @@ public void mujocoJNILoadTest() {
5479
MuJoCoLib lib = new MuJoCoLib();
5580

5681
System.out.println("Starting " + MuJoCoLib.mj_versionString().getString());
57-
int error_sz = 1000;
58-
BytePointer error = new BytePointer(error_sz);
59-
String filename = "model/humanoid/humanoid.xml";
60-
File file = new File(filename);
61-
if(!file.exists()) {
62-
fail("File is missing from the disk");
63-
}
64-
filename = file.getAbsolutePath();
65-
mjModel m = MuJoCoLib.mj_loadXML(
66-
filename, null, error,
67-
error_sz);
68-
69-
if(m==null) {
70-
String message = "Model failed to load from "+filename+"\n"+error.getString();
71-
System.err.println(message);
72-
fail(message);
73-
}
74-
System.out.println("Humanoid model loaded " + filename);
75-
mjData d = MuJoCoLib.mj_makeData(m);
76-
try {
77-
mjModel_ Maccessable = new mjModel_(m);
78-
try (mjData_ accessable = new mjData_(d)) {
79-
System.out.println("Run model for 10 seconds");
80-
while (accessable.time() < 10) {
81-
MuJoCoLib.mj_step1(m, d);
82-
// apply controls https://mujoco.readthedocs.io/en/stable/programming/simulation.html
83-
controller.controlStep(accessable, Maccessable);
84-
MuJoCoLib.mj_step2(m, d);
85-
double timestep = new mjOption_(Maccessable.opt()).timestep()*1000;
86-
Thread.sleep((long) timestep);
87-
88-
}
89-
90-
}
91-
} catch (Exception e) {
92-
// TODO Auto-generated catch block
93-
e.printStackTrace();
94-
}
95-
System.out.println("Clean up data objects");
9682

97-
MuJoCoLib.mj_deleteData(d);
98-
MuJoCoLib.mj_deleteModel(m);
9983
}
10084
}

0 commit comments

Comments
 (0)