notifyUpdate() bad function call issue

Hello. I am trying to put lines on simulator

initialize lineset pointer

void initializeLineMarker(SimpleControllerIO* io, const Vector3& foot0, const Vector3& foot1, const Vector3& foot2, const Vector3& foot3) {
    // (R, G, B)
    Vector3f color(0.0f, 1.0f, 0.0f); // 초록색
    // 
    SgLineSetPtr lineSet = new SgLineSet;
    // 
    SgVertexArrayPtr vertices = lineSet->getOrCreateVertices();
    int startIndex = vertices->size();
    vertices->push_back(foot0.cast<float>());
    vertices->push_back(foot1.cast<float>());
    vertices->push_back(foot2.cast<float>());
    vertices->push_back(foot3.cast<float>());

    // add lines
    lineSet->addLine(startIndex, startIndex + 1);
    lineSet->addLine(startIndex + 1, startIndex + 2);
    lineSet->addLine(startIndex + 2, startIndex + 3);
    lineSet->addLine(startIndex + 3, startIndex);

    // color
    SgColorArrayPtr colors = new SgColorArray;
    colors->resize(1);
    (*colors)[0] = color;
    lineSet->setColors(colors);
    // thickness
    lineSet->setLineWidth(5.0f); // 원하는 굵기로 설정
    // 
    SupportLine = new SgPosTransform;
    SupportLine->addChild(lineSet);
    //
    SceneView::instance()->scene()->addChild(SupportLine);

}

and update line position like this

void updateLineSupportLine(const Vector3& foot0, const Vector3& foot1, const Vector3& foot2, const Vector3& foot3) {
    lineSet_update = dynamic_cast<SgLineSet*>(SupportLine->child(0));

    vertices_update = lineSet_update->vertices();
    
    vertices_update->at(0) = foot0.cast<float>();
    vertices_update->at(1) = foot1.cast<float>();
    vertices_update->at(2) = foot2.cast<float>();
    vertices_update->at(3) = foot3.cast<float>();

    // SceneGraph notify update
    lineSet_update->notifyUpdate();

}

when I use this code in my controller. it works well for a while

but after some moment, simulation stopped.

I checked this by using exception catch
catch (const std::exception& e) {
std::cerr << "Exception in control: " << e.what() << std::endl;
return false;
}

then, terminal said
“Exception in control: bad_function_call”

I checked many times to find what function causes this exception

i think nofityUpdate cause this exception.

How can I fix it?

Hi. In my experience, manipulating scenegraph from the controller does not work because of some implementation reasons. I am not the developer of Choreonoid so I am not aware of the exact reason. Maybe it is conflict between threads or that OpenGL APIs much be called from the main thread.

I understand it is safe to manipulate scenegraph from a plugin.
In a library I developed (see below), I wrote a plugin that help visualizing stuff by communicating with a controller via shared memory.

I hope this gives you some ideas to cope with your case.

Thank you for your comment, ytazz.
As you pointed out, this is an issue with thread conflicts.
Thank you very much for introducing your plugin; it is indeed a good solution.

Let me provide a basic explanation of the issue:
Rendering to the scene view is handled in the main (GUI) thread. Meanwhile, simulation and control are processed in separate threads for efficiency. Accessing objects or functions in the main thread from another thread can lead to crashes due to thread conficts. This is a typical issue in multithread programming.

A solution for visualizaing data output from a controller is as follows:

  1. Outpu data from the controller as log data
  2. Visualize the log data in the main thread

This approach is implemented in BodyContactPointLoggerItem included in the Body plugin. (The source files are “BodyContactPointLoggerItem.[h/cpp]”)

As a sample using this, a project named “FallingBoxesContactPoints.cnoid” is available in the sample/general directory.

To understand the implementation and usage of the above method, please check this sample and the implementation of BodyContactPointLoggerItem.