Simulate: fix reload button causing segfault, make interface changes needed for Python bindings
This commit is contained in:
+3
-2
@@ -7,6 +7,7 @@ COMMON=-O2 -I../include -L../lib -std=c++11 -pthread -Wl,-rpath,'$$ORIGIN'/../li
|
|||||||
all:
|
all:
|
||||||
$(CC) -c -O2 -fPIC -I../include uitools.c
|
$(CC) -c -O2 -fPIC -I../include uitools.c
|
||||||
$(CXX) -c -O2 -fPIC -I../include simulate.cc
|
$(CXX) -c -O2 -fPIC -I../include simulate.cc
|
||||||
$(CXX) -shared -o libmjsimulate.so simulate.o uitools.o
|
$(CXX) $(COMMON) -shared -Wl,-no-as-needed -Wl,-soname,libmjsimulate.so.2.1.5 -lmujoco -o libmjsimulate.so.2.1.5 simulate.o uitools.o
|
||||||
mv libmjsimulate.so ../lib/libmjsimulate.so
|
mv libmjsimulate.so.2.1.5 ../lib/libmjsimulate.so.2.1.5
|
||||||
|
ln -sf ../lib/libmjsimulate.so.2.1.5 ../lib/libmjsimulate.so
|
||||||
$(CXX) $(COMMON) -Wl,-no-as-needed main.cc -lmjsimulate -lmujoco -lGL -lglfw -o ../bin/simulate
|
$(CXX) $(COMMON) -Wl,-no-as-needed main.cc -lmjsimulate -lmujoco -lGL -lglfw -o ../bin/simulate
|
||||||
|
|||||||
+44
-17
@@ -102,15 +102,37 @@ void SimulateLoop(mj::Simulate& simulate) {
|
|||||||
|
|
||||||
if (simulate.droploadrequest) {
|
if (simulate.droploadrequest) {
|
||||||
mjModel* mnew = LoadModel(simulate.dropfilename, simulate);
|
mjModel* mnew = LoadModel(simulate.dropfilename, simulate);
|
||||||
|
simulate.droploadrequest = 0;
|
||||||
if (mnew) {
|
if (mnew) {
|
||||||
mjData* dnew = mj_makeData(mnew);
|
mjData* dnew = mj_makeData(mnew);
|
||||||
simulate.load(simulate.dropfilename, mnew, dnew, true);
|
simulate.load(simulate.dropfilename, mnew, dnew, true);
|
||||||
|
|
||||||
simulate.droploadrequest = 0;
|
m = mnew;
|
||||||
|
d = dnew;
|
||||||
|
mj_forward(m, d);
|
||||||
|
|
||||||
|
// allocate ctrlnoise
|
||||||
|
free(ctrlnoise);
|
||||||
|
ctrlnoise = (mjtNum*) malloc(sizeof(mjtNum)*m->nu);
|
||||||
|
mju_zero(ctrlnoise, m->nu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simulate.uiloadrequest) {
|
||||||
|
mjModel* mnew = LoadModel(simulate.filename, simulate);
|
||||||
|
simulate.uiloadrequest = 0;
|
||||||
|
if (mnew) {
|
||||||
|
mjData* dnew = mj_makeData(mnew);
|
||||||
|
simulate.load(simulate.filename, mnew, dnew, true);
|
||||||
|
|
||||||
m = mnew;
|
m = mnew;
|
||||||
d = dnew;
|
d = dnew;
|
||||||
mj_forward(m, d);
|
mj_forward(m, d);
|
||||||
|
|
||||||
|
// allocate ctrlnoise
|
||||||
|
free(ctrlnoise);
|
||||||
|
ctrlnoise = (mjtNum*) malloc(sizeof(mjtNum)*m->nu);
|
||||||
|
mju_zero(ctrlnoise, m->nu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,8 +179,8 @@ void SimulateLoop(mj::Simulate& simulate) {
|
|||||||
|
|
||||||
// clear old perturbations, apply new
|
// clear old perturbations, apply new
|
||||||
mju_zero(d->xfrc_applied, 6*m->nbody);
|
mju_zero(d->xfrc_applied, 6*m->nbody);
|
||||||
mjv_applyPerturbPose(m, d, &simulate.pert, 0); // move mocap bodies only
|
simulate.applyposepertubations(0); // move mocap bodies only
|
||||||
mjv_applyPerturbForce(m, d, &simulate.pert);
|
simulate.applyforceperturbations();
|
||||||
|
|
||||||
// run single step, let next iteration deal with timing
|
// run single step, let next iteration deal with timing
|
||||||
mj_step(m, d);
|
mj_step(m, d);
|
||||||
@@ -171,8 +193,8 @@ void SimulateLoop(mj::Simulate& simulate) {
|
|||||||
(glfwGetTime()-tmstart) < refreshfactor/simulate.vmode.refreshRate) {
|
(glfwGetTime()-tmstart) < refreshfactor/simulate.vmode.refreshRate) {
|
||||||
// clear old perturbations, apply new
|
// clear old perturbations, apply new
|
||||||
mju_zero(d->xfrc_applied, 6*m->nbody);
|
mju_zero(d->xfrc_applied, 6*m->nbody);
|
||||||
mjv_applyPerturbPose(m, d, &simulate.pert, 0); // move mocap bodies only
|
simulate.applyposepertubations(0); // move mocap bodies only
|
||||||
mjv_applyPerturbForce(m, d, &simulate.pert);
|
simulate.applyforceperturbations();
|
||||||
|
|
||||||
// run mj_step
|
// run mj_step
|
||||||
mjtNum prevtm = d->time*simulate.slow_down;
|
mjtNum prevtm = d->time*simulate.slow_down;
|
||||||
@@ -189,7 +211,7 @@ void SimulateLoop(mj::Simulate& simulate) {
|
|||||||
// paused
|
// paused
|
||||||
else {
|
else {
|
||||||
// apply pose perturbation
|
// apply pose perturbation
|
||||||
mjv_applyPerturbPose(m, d, &simulate.pert, 1); // move mocap and dynamic bodies
|
simulate.applyposepertubations(1); // move mocap and dynamic bodies
|
||||||
|
|
||||||
// run mj_forward, to update rendering and joint sliders
|
// run mj_forward, to update rendering and joint sliders
|
||||||
mj_forward(m, d);
|
mj_forward(m, d);
|
||||||
@@ -210,19 +232,9 @@ int main(int argc, const char** argv) {
|
|||||||
mju_error("Headers and library have different versions");
|
mju_error("Headers and library have different versions");
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate object for encapsulates UI
|
// simulate object encapsulates the UI
|
||||||
mj::Simulate simulate;
|
mj::Simulate simulate;
|
||||||
|
|
||||||
// request loadmodel if file given (otherwise drag-and-drop)
|
|
||||||
if (argc>1) {
|
|
||||||
m = LoadModel(argv[1], simulate);
|
|
||||||
if (m) {
|
|
||||||
d = mj_makeData(m);
|
|
||||||
simulate.load(argv[1], m, d, true);
|
|
||||||
mj_forward(m, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// init GLFW
|
// init GLFW
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
mju_error("could not initialize GLFW");
|
mju_error("could not initialize GLFW");
|
||||||
@@ -231,6 +243,21 @@ int main(int argc, const char** argv) {
|
|||||||
// start simulation thread (this creates the UI)
|
// start simulation thread (this creates the UI)
|
||||||
simulate.startthread();
|
simulate.startthread();
|
||||||
|
|
||||||
|
// request loadmodel if file given (otherwise drag-and-drop)
|
||||||
|
if (argc>1) {
|
||||||
|
m = LoadModel(argv[1], simulate);
|
||||||
|
if (m) {
|
||||||
|
d = mj_makeData(m);
|
||||||
|
simulate.load(argv[1], m, d, true);
|
||||||
|
mj_forward(m, d);
|
||||||
|
|
||||||
|
// allocate ctrlnoise
|
||||||
|
free(ctrlnoise);
|
||||||
|
ctrlnoise = (mjtNum*) malloc(sizeof(mjtNum)*m->nu);
|
||||||
|
mju_zero(ctrlnoise, m->nu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SimulateLoop(simulate);
|
SimulateLoop(simulate);
|
||||||
|
|
||||||
// If simulate loop exited its time to stop the UI
|
// If simulate loop exited its time to stop the UI
|
||||||
|
|||||||
+22
-2
@@ -1150,7 +1150,7 @@ void uiEvent(mjuiState* state) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Reload
|
case 2: // Reload
|
||||||
simulate->loadrequest = 1;
|
simulate->uiloadrequest = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Align
|
case 3: // Align
|
||||||
@@ -1548,8 +1548,21 @@ void Simulate::stopthread(void) {
|
|||||||
this->renderthreadhandle.join();
|
this->renderthreadhandle.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------ apply pose perturbations ----------------------------
|
||||||
|
void Simulate::applyposepertubations(int flg_paused) {
|
||||||
|
if (this->m != nullptr) {
|
||||||
|
mjv_applyPerturbPose(this->m, this->d, &this->pert, flg_paused); // move mocap bodies only
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------- Tell the render thread to load a file -------------------
|
//------------------------ apply force perturbations ---------------------------
|
||||||
|
void Simulate::applyforceperturbations(void) {
|
||||||
|
if (this->m != nullptr) {
|
||||||
|
mjv_applyPerturbForce(this->m, this->d, &this->pert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------- Tell the render thread to load a file and wait ----------
|
||||||
void Simulate::load(const char* file,
|
void Simulate::load(const char* file,
|
||||||
mjModel* mnew,
|
mjModel* mnew,
|
||||||
mjData* dnew,
|
mjData* dnew,
|
||||||
@@ -1559,6 +1572,13 @@ void Simulate::load(const char* file,
|
|||||||
this->delete_old_m_d = delete_old_m_d;
|
this->delete_old_m_d = delete_old_m_d;
|
||||||
mju::strcpy_arr(this->filename, file);
|
mju::strcpy_arr(this->filename, file);
|
||||||
this->loadrequest = 2;
|
this->loadrequest = 2;
|
||||||
|
|
||||||
|
// Wait for the render thread to be done loading
|
||||||
|
// so that we know the old model and data's memory can
|
||||||
|
// be free'd by the other thread (sometimes python)
|
||||||
|
while (this->loadrequest > 0) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------ load mjb or xml model -------------------------------
|
//------------------------ load mjb or xml model -------------------------------
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ class Simulate {
|
|||||||
// Stop the Simulate UI thread
|
// Stop the Simulate UI thread
|
||||||
void stopthread(void);
|
void stopthread(void);
|
||||||
|
|
||||||
|
// Apply UI pose perturbations to model and data
|
||||||
|
void applyposepertubations(int flg_paused);
|
||||||
|
|
||||||
|
// Apply UI force perturbations to model and data
|
||||||
|
void applyforceperturbations(void);
|
||||||
|
|
||||||
// Request that the Simulate UI thread render a new model
|
// Request that the Simulate UI thread render a new model
|
||||||
// optionally delete the old model and data when done
|
// optionally delete the old model and data when done
|
||||||
void load(const char* file, mjModel* m, mjData* d, bool delete_old_m_d);
|
void load(const char* file, mjModel* m, mjData* d, bool delete_old_m_d);
|
||||||
@@ -91,6 +97,7 @@ class Simulate {
|
|||||||
// simulation
|
// simulation
|
||||||
int run = 1;
|
int run = 1;
|
||||||
int key = 0;
|
int key = 0;
|
||||||
|
int uiloadrequest = 0;
|
||||||
int droploadrequest = 0;
|
int droploadrequest = 0;
|
||||||
int loadrequest = 0;
|
int loadrequest = 0;
|
||||||
// strings
|
// strings
|
||||||
|
|||||||
Reference in New Issue
Block a user