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
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
Comments