graspit-simulator/graspit

Headless Graspit

Closed this issue · 1 comments

@mateiciocarlie
@JenniferBuehler

I wanted to migrate the conversation here about how to best modify GraspIt! to run in a headless mode.

Great, let's keep the general discussion here then, and discuss specifics in the PRs.

I have submitted a PR with only the cmake files added, so we can start with that.
Before I send out a PR for my other changes, we should agree on them.

Most important required updates to the graspit repo in order for my packages to work are:

  1. Fix locale problems. I accidently once had my system on the German locale. Then I noticed problems reading the contact files. That's because of the use of fscanf to read the float values. fscanf/fwritef have pretty much been superseded by std streams. Here are two options to solve the issue:

    • workaround I implemented now is just manually switching to US locale before relevant fscanf/fwrite commands, and then switching back to whatever it was before. This incurs minimal changes to original source.
    • move to std streams everywhere is probably the better solution but it requires more changes to the original source.
  2. Abstract IVmgr. IVmgr pretty much only controls the displaying of the GUI and access to the graspit World object and scene graph. So we can remove the need to display the GUI simply by having another version of IVmgr which only manages the grasit World, and runs the SoQt loop without displaying the GUI. I created an abstract superclass IVmgrAbstract, which has only the methods which are used from core classes not directly related the GUI. Then made IVmgr derive from it. NO changes to IVmgr source are required apart from following minor details

    • the inheritance from IVmgrAbstract
    • setCamera() and getCamera() made virtual, because they exist in IVmgrAbstract
    • added implementation of virtual function viewAll() which simply calls getViewer()->viewAll().

    Further, the World class now has to use a reference to IVmgrAbstract instead of IVmgr. Aside from the reference change, only one line needs to change:

    • calling myIVmgr->viewAll() instead of myIVmgr->getViewer()->viewAll()
  3. Issue when graspItGUI is NULL in Body.cpp: Functions setCoG() and setMaxRadius() have to check for NULL pointer of graspItGUI before using axesTranToCOG / axesScale which are undefined if there is no graspItGUI (should also initialize them to NULL in constructor!).

  4. Removing only registered bodies from collision interface. Probably not that crucial, but in world.cpp World::destroyElement(), if a body is removed, it is always removed from the collision interface as well with CollisionInterface::removeBody(), even if it is not registered in the world. This prints an error from collision interface if the body wasn't in the world. So I moved this line into the loop (see line 427 in the linked world.cpp). I noticed this issue when I removed a robot and all its links from the scene and kept the pointer (deleteElement=false) to maintain it in my database, so I could add it again later. But destroyElement() is called from the Robot destructor. If the robot is destroyed but not part of the world, it will still remove its links from the collision interface... is this supposed to happen?

With the above changes, I could add a new subclass IVMgrNoGUI which can be used instead of IVmgr in order to run the SoQt loop without displaying the GUI. I have successfully used the Eigengrasp planner with this in my graspit wrapper API.

You can look at my fork of this repo including all above changes.

Let me know what you think about the above changes and if it would be possible to integrate them with your repo, or what you think should be re-designed before a merge. I'm happy to send out a PR as soon as we agree about the changes. I'm also happy to change my current solution in 1.) to the std streams, though as mentioned, this will imply more changes to the original source.

Cheers