krishauser / Klampt

Kris' Locomotion and Manipulation Planning Toolkit
BSD 3-Clause "New" or "Revised" License
377 stars 96 forks source link

Segmentation fault when setting robot config inside a custom class #158

Closed smeng9 closed 1 year ago

smeng9 commented 2 years ago

Hi Professor,

We tried convert some legacy code into a well structured python class and we encountered a segmentation fault.

I have created a minimum example that can trigger the bug.

from klampt.robotsim import WorldModel

class MyRobotClass():
    def __init__(self):
        world = WorldModel()
        # Change the following line to a path of urdf file
        world.loadElement("example_robot.urdf")
        self.robot = world.robot(0)
        # self.DoF should be some integer > 0
        self.DoF = len(self.robot.getConfig())

    def setConfig(self):
        # The next line prints [], which should not be empty
        print(self.robot.getConfig())
        # đź’Ą The next line segfaults
        self.robot.setConfig([0]*self.DoF)

r = MyRobotClass()
r.setConfig()

In the above example, when inside the init function, everything works normally. However when calling the class instance method it triggers segmentation fault. If I don't write the above code in a class, it works normally, but then I cannot encapsulate other custom logic into my own class.

The cause of the bug may be some part of the RobotModel class's data gets messed up during garbage collection. Same as before, I will attach a gdb output to help debugging.

(gdb) run
Starting program: /home/motion/.local/share/virtualenvs/flexiv-OyifXPml/bin/python3 test_arc.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff07ff640 (LWP 4180651)]
[New Thread 0x7fffefffe640 (LWP 4180652)]
[New Thread 0x7fffeb7fd640 (LWP 4180653)]
[New Thread 0x7fffeaffc640 (LWP 4180654)]
[New Thread 0x7fffe67fb640 (LWP 4180655)]
[New Thread 0x7fffe5ffa640 (LWP 4180656)]
[New Thread 0x7fffe37f9640 (LWP 4180657)]
WorldModel::LoadRobot: static/flexiv_rizon4_kinematics.urdf
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Material [rizon_light_grey] color has no rgba
URDFParser: Material [rizon_light_grey] not defined in file
URDFParser: material has only name, actual material definition may be in the model
URDFParser: Link size: 14
URDFParser: Joint size: 9
LoadAssimp: Loaded model static/meshes/collision/link0.stl (595 verts, 200 tris)
LoadAssimp: Loaded model static/meshes/collision/link1.stl (785 verts, 264 tris)
LoadAssimp: Loaded model static/meshes/collision/link2.stl (622 verts, 210 tris)
LoadAssimp: Loaded model static/meshes/collision/link3.stl (642 verts, 218 tris)
LoadAssimp: Loaded model static/meshes/collision/link4.stl (696 verts, 232 tris)
LoadAssimp: Loaded model static/meshes/collision/link5.stl (513 verts, 172 tris)
LoadAssimp: Loaded model static/meshes/collision/link6.stl (594 verts, 198 tris)
LoadAssimp: Loaded model static/meshes/collision/link7.stl (894 verts, 298 tris)
URDFParser: Done loading robot file static/flexiv_rizon4_kinematics.urdf
[]

Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
0x00007ffff6707ce8 in RobotKinematics3D::UpdateFrames() () from /home/motion/.local/share/virtualenvs/flexiv-OyifXPml/lib/python3.10/site-packages/klampt/_robotsim.cpython-310-x86_64-linux-gnu.so
(gdb) bt
#0  0x00007ffff6707ce8 in RobotKinematics3D::UpdateFrames() ()
   from /home/motion/.local/share/virtualenvs/flexiv-OyifXPml/lib/python3.10/site-packages/klampt/_robotsim.cpython-310-x86_64-linux-gnu.so
#1  0x00007ffff62107a8 in RobotModel::setConfig (
    this=this@entry=0x5555560abb30, 
    q=std::vector of length 14, capacity 16 = {...})
    at klampt/src/robotsim.cpp:4325
#2  0x00007ffff62b4a0d in _wrap_RobotModel_setConfig (args=<optimized out>)
    at klampt/src/robotsim_wrap.cxx:40845
#3  0x00005555556af798 in ?? ()
#4  0x00005555556a630b in _PyObject_MakeTpCall ()
#5  0x000055555569ec67 in _PyEval_EvalFrameDefault ()
#6  0x00005555556affbc in _PyFunction_Vectorcall ()
#7  0x00005555556985c9 in _PyEval_EvalFrameDefault ()
#8  0x00005555556affbc in _PyFunction_Vectorcall ()
#9  0x00005555556985c9 in _PyEval_EvalFrameDefault ()
#10 0x0000555555694cc6 in ?? ()
#11 0x0000555555789eb6 in PyEval_EvalCode ()
#12 0x00005555557b7318 in ?? ()
#13 0x00005555557b003b in ?? ()
#14 0x00005555557b7065 in ?? ()
#15 0x00005555557b6548 in _PyRun_SimpleFileObject ()
#16 0x00005555557b6243 in _PyRun_AnyFileObject ()
--Type <RET> for more, q to quit, c to continue without paging--Quit
krishauser commented 2 years ago

Yes, the world to which a robot is attached needs to be stored for the life of the robot. You should put “self.world = world” somewhere so the GC doesn’t throw it out.