Robotics StackExchange | Archived questions

Serialize state machines.

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

Asked by Pedro Pereira on 2019-02-13 07:18:08 UTC

Comments

Answers

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/pickle.html#pickling-and-unpickling-normal-class-instances

Asked by ct2034 on 2019-02-13 10:33:58 UTC

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 :(

Asked by Pedro Pereira on 2019-02-13 11:59:42 UTC

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

Asked by ct2034 on 2019-02-15 07:03:18 UTC

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!

Asked by Pedro Pereira on 2019-02-18 04:37:37 UTC

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

Asked by ct2034 on 2019-08-09 10:47:56 UTC