def __getattr__(self, name):
""" Override the __getattr__ method so that function calls become server requests
If the name is a method of the YuMiArm class, this returns a function that calls that
function on the YuMiArm instance in the server. The wait_for_res argument is not available
remotely and will always be set to True. This is to prevent odd desynchronized crashes
Otherwise, the name is considered to be an attribute, and getattr is called on the
YuMiArm instance in the server. Note that if it isn't an attribute either a RuntimeError
will be raised.
The difference here is that functions access the server *on call* and non-functions do
*on getting the name*
Also note that this is __getattr__, so things like __init__ and __dict__ WILL NOT trigger
this function as the YuMiArm_ROS object already has these as attributes.
"""
if name in YuMiArm.__dict__:
def handle_remote_call(*args, **kwargs):
""" Handle the remote call to some YuMiArm function.
"""
rospy.wait_for_service(self.arm_service, timeout = self.timeout)
arm = rospy.ServiceProxy(self.arm_service, ROSYumiArm)
if 'wait_for_res' in kwargs:
kwargs['wait_for_res'] = True
try:
response = arm(pickle.dumps(name), pickle.dumps(args), pickle.dumps(kwargs))
except rospy.ServiceException, e:
raise RuntimeError("Service call failed: {0}".format(str(e)))
return pickle.loads(response.ret)
return handle_remote_call
else:
rospy.wait_for_service(self.arm_service, timeout = self.timeout)
arm = rospy.ServiceProxy(self.arm_service, ROSYumiArm)
try:
response = arm(pickle.dumps('__getattribute__'), pickle.dumps(name), pickle.dumps(None))
except rospy.ServiceException, e:
raise RuntimeError("Could not get attribute: {0}".format(str(e)))
return pickle.loads(response.ret)
评论列表
文章目录