Ask Your Question
0

Serialize state machines.

asked 2019-02-13 06:18:08 -0500

Pedro Pereira gravatar image

Hello everyone,

I have a ROS node that receives SCXML files and converts them into state machines using the smach library. All the generated states machines are currently being stored in memory but only executed when required. Additionally the mentioned translation step takes some time to finish. I want to increase performance by serializing the state machines.

Since the code was written in Python ( rospy ), I tried doing this using the pickle library. However I got the following error :

pickle.dump(sm, open("sm.p", "wb" ))
  File "/usr/lib/python2.7/pickle.py", line 1376, in dump
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.7/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.7/pickle.py", line 425, in save_reduce
    save(state)
  File "/usr/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.7/pickle.py", line 655, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.7/pickle.py", line 669, in _batch_setitems
    save(v)
  File "/usr/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
**TypeError: can't pickle lock objects**

From my understanding of the error ( I'm a beginner ) I tried to manually change the smach library code by overwriting the defaut _ _getstate_ _ and _ _setstate_ _ methods to delete/release locks before serialization, as shown:

# example of used __getstate__
def __getstate__(self):

    if self._locks.locked() :
        self._locks.release()
    return self.__dict__

# example of used __setstate__
def __setstate__(self, d):

    if not self._locks.locked() :
        self._locks.acquire()
    self.__dict__.update(d)

I still got the same error. I'm running ROS Kinetic under Ubuntu 16.04 ( 64-bit - Intel® Core™ i7-6700HQ CPU @ 2.60GHz × 8 ).

Is there is a solution/workaround for this problem? Many thanks in advance.

Pedro Pereira

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2019-02-13 09:33:58 -0500

ct2034 gravatar image

updated 2019-02-15 06:02:37 -0500

You are using pickle to serialize the state machine. So you need o give pickle a way to serialize the state machine: https://docs.python.org/2/library/pic...

edit flag offensive delete link more

Comments

Thank you for your answer! I took the code from the smach tutorials ( Section 2.3 here ) and created a brand new test node where I try to serialize the state machine. I removed all mentioned changes to the library and still get the error :(

Pedro Pereira gravatar imagePedro Pereira ( 2019-02-13 10:59:42 -0500 )edit

yes, you still need to give pickle a way to serialize the state machine.

ct2034 gravatar imagect2034 ( 2019-02-15 06:03:18 -0500 )edit

The provided __getstate__ / __setstate__ methods are already real code examples I added to the library. I provided just those since they all look similar.

Can you give me an insight regarding where my strategy is failing or what is the best strategy to solve this?

Many thanks in advance!

Pedro Pereira gravatar imagePedro Pereira ( 2019-02-18 03:37:37 -0500 )edit

do you also implement __getinitargs__() or __getnewargs__()?

ct2034 gravatar imagect2034 ( 2019-08-09 10:47:56 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2019-02-13 06:18:08 -0500

Seen: 57 times

Last updated: Feb 15