27 from threading
import Thread
30 from itertools
import izip
as zip
35 import pygraphviz
as pgv
40 from actionlib.msg
import TestAction, TestGoal
41 from actionlib_msgs.msg
import GoalStatus
46 from std_msgs.msg
import String,ColorRGBA
47 from std_srvs.srv
import Trigger
48 from sensor_msgs.msg
import JointState
49 from geometry_msgs.msg
import PoseStamped, Twist
50 from trajectory_msgs.msg
import JointTrajectory, JointTrajectoryPoint
51 from move_base_msgs.msg
import MoveBaseAction, MoveBaseGoal
52 from control_msgs.msg
import FollowJointTrajectoryAction, FollowJointTrajectoryGoal
53 from tf.transformations
import quaternion_from_euler
56 from cob_actions.msg
import SetStringAction, SetStringGoal
57 from cob_sound.msg
import SayAction, SayGoal, PlayAction, PlayGoal
58 from cob_script_server.msg
import ScriptState
59 from cob_light.msg
import LightMode, LightModes, SetLightModeGoal, SetLightModeAction
60 from cob_mimic.msg
import SetMimicGoal, SetMimicAction
66 graph.node_attr[
'shape']=
'box' 75 filename = os.path.basename(sys.argv[0])
76 self.basename, extension = os.path.splitext(filename)
77 rospy.init_node(self.basename)
78 self.
graph_pub = rospy.Publisher(
"/script_server/graph", String, queue_size=1)
96 rospy.loginfo(
"Starting <<%s>> script...",self.basename)
100 rospy.loginfo(
"Wait for script to finish...")
101 while ah_counter != 0:
103 rospy.loginfo(
"...script finished.")
109 rospy.loginfo(
"Start parsing...")
118 rospy.set_param(
"/script_server/graph", graph.string())
119 self.graph_pub.publish(graph.string())
120 rospy.loginfo(
"...parsing finished")
121 return graph.string()
136 robot_description = rospy.search_param(
'robot_description')
if rospy.search_param(
'robot_description')
else '/robot_description' 137 rospy.loginfo(
"Initialize urdf structure from '{}'".format(robot_description))
138 self.
robot_urdf = URDF.from_parameter_server(key=robot_description)
139 except KeyError
as key_err:
141 message =
"Unable to initialize urdf structure: {}".format(key_err)
142 rospy.logerr(message)
151 def init(self,component_name,blocking=True):
152 return self.
trigger(component_name,
"init",blocking=blocking)
159 def stop(self,component_name,mode="omni",blocking=True):
164 ah.set_active(mode=
"service")
166 rospy.loginfo(
"<<stop>> <<%s>>", component_name)
167 if component_name ==
"base":
168 if(mode ==
None or mode ==
""):
169 action_server_name =
"/move_base" 170 elif(mode ==
"omni"):
171 action_server_name =
"/move_base" 172 elif(mode ==
"diff"):
173 action_server_name =
"/move_base_diff" 174 elif(mode ==
"linear"):
175 action_server_name =
"/move_base_linear" 177 message =
"Given navigation mode " + mode +
" for " + component_name +
" is not valid, aborting..." 178 rospy.logerr(message)
179 ah.set_failed(33, message)
183 parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/action_name" 184 if not rospy.has_param(parameter_name):
185 message =
"Parameter " + parameter_name +
" does not exist on ROS Parameter Server, aborting..." 186 rospy.logerr(message)
187 ah.set_failed(2, message)
189 action_server_name = rospy.get_param(parameter_name)
193 rospy.logdebug(
"calling %s action server",action_server_name)
197 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
198 if not client.wait_for_server(rospy.Duration(1)):
200 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 201 rospy.logerr(message)
202 ah.set_failed(4, message)
205 rospy.logdebug(
"%s action server ready",action_server_name)
208 client.cancel_all_goals()
217 def recover(self,component_name,blocking=True):
218 return self.
trigger(component_name,
"recover",blocking=blocking)
225 def halt(self,component_name,blocking=True):
226 return self.
trigger(component_name,
"halt",blocking=blocking)
235 def trigger(self,component_name,service_name,blocking=True):
240 ah.set_active(mode=
"service")
242 rospy.loginfo(
"<<%s>> <<%s>>", service_name, component_name)
243 parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/service_ns" 244 if not rospy.has_param(parameter_name):
245 message =
"Parameter " + parameter_name +
" does not exist on ROS Parameter Server, aborting..." 246 rospy.logerr(message)
247 ah.set_failed(2, message)
249 service_ns_name = rospy.get_param(parameter_name)
250 service_full_name = service_ns_name +
"/" + service_name
255 rospy.wait_for_service(service_full_name,1)
256 except rospy.ROSException
as e:
257 error_message =
"%s"%e
258 message =
"...service <<" + service_name +
">> of <<" + component_name +
">> not available,\n error: " + error_message
259 rospy.logerr(message)
260 ah.set_failed(4, message)
265 trigger = rospy.ServiceProxy(service_full_name,Trigger)
267 rospy.loginfo(
"Wait for <<%s>> to <<%s>>...", component_name, service_name)
270 Thread(target=trigger).start()
271 except rospy.ServiceException
as e:
272 error_message =
"%s"%e
273 message =
"...calling <<" + service_name +
">> of <<" + component_name +
">> not successfull,\n error: " + error_message
274 rospy.logerr(message)
275 ah.set_failed(10, message)
281 message =
"...response of <<" + service_name +
">> of <<" + component_name +
">> not successfull,\n error: " + resp.message
282 rospy.logerr(message)
283 ah.set_failed(10, message)
287 rospy.loginfo(
"...<<%s>> is <<%s>>", component_name, service_name)
303 ah.set_active(mode=
"action")
305 rospy.loginfo(
"<<%s>> <<%s>>", action_name, component_name)
313 action_full_name =
"/" + component_name +
"/" + action_name
318 if not action_client.wait_for_server(rospy.Duration(1)):
319 message =
"ActionServer %s is not running"%action_full_name
320 rospy.logerr(message)
321 ah.set_failed(4, message)
326 rospy.loginfo(
"Wait for <<%s>> to <<%s>>...", component_name, action_name)
327 goal_state = action_client.send_goal_and_wait(TestGoal())
328 if not (action_client.get_state() == GoalStatus.SUCCEEDED):
329 message =
"...state of <<" + action_name +
">> of <<" + component_name +
">> : " + GoalStatus.to_string(action_client.get_state())
330 rospy.logerr(message)
331 ah.set_failed(10, message)
334 action_client.send_goal(TestGoal())
337 rospy.loginfo(
"...<<%s>> is <<%s>>", component_name, action_name)
350 action_name =
"set_string" 355 ah.set_active(mode=
"action")
357 rospy.loginfo(
"<<%s>> <<%s>>", action_name, component_name)
358 action_full_name =
"/" + component_name +
"/" + action_name
363 if not action_client.wait_for_server(rospy.Duration(1)):
364 message =
"ActionServer %s is not running"%action_full_name
365 rospy.logerr(message)
366 ah.set_failed(4, message)
370 goal = SetStringGoal()
373 rospy.loginfo(
"Wait for <<%s>> to <<%s>>...", component_name, action_name)
374 goal_state = action_client.send_goal_and_wait(goal)
375 if not (action_client.get_state() == GoalStatus.SUCCEEDED):
376 message =
"...state of <<" + action_name +
">> of <<" + component_name +
">> : " + GoalStatus.to_string(action_client.get_state())
377 rospy.logerr(message)
378 ah.set_failed(10, message)
381 action_client.send_goal(goal)
384 rospy.loginfo(
"...<<%s>> is <<%s>>", component_name, action_name)
397 def move(self,component_name,parameter_name,blocking=True, mode=None, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
398 if component_name ==
"base":
399 return self.
move_base(component_name,parameter_name,blocking, mode)
401 return self.
move_traj(component_name,parameter_name,blocking, speed_factor=speed_factor, urdf_vel=urdf_vel, default_vel=default_vel, stop_at_waypoints=stop_at_waypoints)
410 def move_base(self,component_name,parameter_name,blocking, mode):
417 if(mode ==
None or mode ==
""):
418 rospy.loginfo(
"Move <<%s>> to <<%s>>",component_name,parameter_name)
420 rospy.loginfo(
"Move <<%s>> to <<%s>> using <<%s>> mode",component_name,parameter_name,mode)
423 if type(parameter_name)
is str:
424 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + parameter_name
425 if not rospy.has_param(full_parameter_name):
426 message =
"Parameter " + full_parameter_name +
" does not exist on ROS Parameter Server, aborting..." 427 rospy.logerr(message)
428 ah.set_failed(2, message)
430 param = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/" + parameter_name)
432 param = parameter_name
435 if not type(param)
is list:
436 message =
"No valid parameter for " + component_name +
": not a list, aborting..." 437 rospy.logerr(message)
438 print(
"parameter is:",param)
439 ah.set_failed(3, message)
444 if not len(param) == DOF:
445 message =
"No valid parameter for " + component_name +
": dimension should be " + str(DOF) +
" but is " + str(len(param)) +
", aborting..." 446 rospy.logerr(message)
447 print(
"parameter is:",param)
448 ah.set_failed(3, message)
453 if not ((type(i)
is float)
or (type(i)
is int)):
455 message =
"No valid parameter for " + component_name +
": not a list of float or int, aborting..." 456 rospy.logerr(message)
457 print(
"parameter is:",param)
458 ah.set_failed(3, message)
461 rospy.logdebug(
"accepted parameter %f for %s",i,component_name)
465 pose.header.stamp = rospy.Time.now()
466 pose.header.frame_id =
"map" 467 pose.pose.position.x = param[0]
468 pose.pose.position.y = param[1]
469 pose.pose.position.z = 0.0
470 q = quaternion_from_euler(0, 0, param[2])
471 pose.pose.orientation.x = q[0]
472 pose.pose.orientation.y = q[1]
473 pose.pose.orientation.z = q[2]
474 pose.pose.orientation.w = q[3]
477 if(mode ==
None or mode ==
""):
478 action_server_name =
"/move_base" 479 elif(mode ==
"omni"):
480 action_server_name =
"/move_base" 481 elif(mode ==
"diff"):
482 action_server_name =
"/move_base_diff" 483 elif(mode ==
"linear"):
484 action_server_name =
"/move_base_linear" 486 message =
"Given navigation mode " + mode +
" for " + component_name +
" is not valid, aborting..." 487 rospy.logerr(message)
488 ah.set_failed(33, message)
491 rospy.logdebug(
"calling %s action server",action_server_name)
494 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
495 if not client.wait_for_server(rospy.Duration(1)):
497 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 498 rospy.logerr(message)
499 ah.set_failed(4, message)
502 rospy.logdebug(
"%s action server ready",action_server_name)
505 client_goal = MoveBaseGoal()
506 client_goal.target_pose = pose
508 client.send_goal(client_goal)
509 ah.set_client(client)
515 rospy.logdebug(
"using default_vel from argument")
516 if (type(default_vel)
is float)
or (type(default_vel)
is int):
517 default_vel = numpy.array([default_vel
for _
in start_pos])
518 elif (type(default_vel)
is list)
and (len(default_vel) == len(start_pos))
and all(
519 ((type(item)
is float)
or (type(item)
is int))
for item
in default_vel):
520 default_vel = default_vel
522 raise ValueError(
"argument 'default_vel' {} has wrong format (must be float/int or list of float/int) with proper dimensions.".format(default_vel))
524 rospy.logdebug(
"using default_vel parameter server")
525 param_string = self.
ns_global_prefix +
"/" + component_name +
"/default_vel" 526 if not rospy.has_param(param_string):
527 default_vel = numpy.array([0.1
for _
in start_pos])
529 "parameter '{}' does not exist on ROS Parameter Server, using default_vel {} [rad/sec].".format(
530 param_string, default_vel))
532 param_vel = rospy.get_param(param_string)
533 if (type(param_vel)
is float)
or (type(param_vel)
is int):
534 default_vel = numpy.array([param_vel
for _
in start_pos])
535 elif (type(param_vel)
is list)
and (len(param_vel) == len(start_pos))
and all(
536 ((type(item)
is float)
or (type(item)
is int))
for item
in param_vel):
537 default_vel = numpy.array(param_vel)
539 default_vel = numpy.array([0.1
for _
in start_pos])
541 "parameter '{}' {} has wrong format (must be float/int or list of float/int), using default_vel {} [rad/sec].".format(
542 param_string, param_vel, default_vel))
543 rospy.logdebug(
"default_vel: {}".format(default_vel))
546 for idx, joint_name
in enumerate(joint_names):
548 limit_vel.append(self.robot_urdf.joint_map[joint_name].limit.velocity)
549 except Exception
as e:
550 rospy.logwarn(
"Velocity limits for '{}' could not be retrieved from urdf structure:\n{}\nUsing default velocity: {}".format(joint_name, e, default_vel[idx]))
551 limit_vel.append(default_vel[idx])
555 rospy.logdebug(
"using default_vel from urdf_limits")
556 velocities = limit_vel
558 rospy.logdebug(
"using default_vel from argument or parameter server")
559 velocities = list(default_vel)
562 desired_vel = numpy.array(velocities)*speed_factor
563 if (numpy.any(desired_vel > numpy.array(limit_vel))):
564 raise ValueError(
"desired velocities {} exceed velocity limits {},...aborting".format(desired_vel, numpy.array(limit_vel)))
566 if (numpy.any(desired_vel <= numpy.zeros_like(desired_vel))):
567 raise ValueError(
"desired velocities {} cannot be zero or negative,...aborting".format(desired_vel))
568 rospy.logdebug(
"Velocities are: {}".format(desired_vel))
572 def compose_trajectory(self, component_name, parameter_name, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
573 if urdf_vel
and default_vel:
574 rospy.logerr(
"arguments not valid - cannot set 'urdf_vel' and 'default_vel' at the same time, aborting...")
575 return (JointTrajectory(), 3)
578 param_string = self.
ns_global_prefix +
"/" + component_name +
"/joint_names" 579 if not rospy.has_param(param_string):
580 rospy.logerr(
"parameter %s does not exist on ROS Parameter Server, aborting...",param_string)
581 return (JointTrajectory(), 2)
582 joint_names = rospy.get_param(param_string)
585 if not type(joint_names)
is list:
586 rospy.logerr(
"no valid joint_names for %s: not a list, aborting...",component_name)
587 print(
"joint_names are:",joint_names)
588 return (JointTrajectory(), 3)
590 for i
in joint_names:
592 if not type(i)
is str:
593 rospy.logerr(
"no valid joint_names for %s: not a list of strings, aborting...",component_name)
594 print(
"joint_names are:", joint_names)
595 return (JointTrajectory(), 3)
597 rospy.logdebug(
"accepted joint_names for component %s",component_name)
600 if type(parameter_name)
is str:
601 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + parameter_name
602 if not rospy.has_param(full_parameter_name):
603 rospy.logerr(
"parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
604 return (JointTrajectory(), 2)
605 param = rospy.get_param(full_parameter_name)
607 param = parameter_name
610 if not type(param)
is list:
611 rospy.logerr(
"no valid parameter for %s: not a list, aborting...",component_name)
612 print(
"parameter is:",param)
613 return (JointTrajectory(), 3)
618 if type(point)
is str:
619 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + point
620 if not rospy.has_param(full_parameter_name):
621 rospy.logerr(
"parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
622 return (JointTrajectory(), 2)
623 point = rospy.get_param(full_parameter_name)
626 elif type(point)
is list:
627 rospy.logdebug(
"point is a list")
629 rospy.logerr(
"no valid parameter for %s: not a list of lists or strings, aborting...",component_name)
630 print(
"parameter is:",param)
631 return (JointTrajectory(), 3)
635 if not len(point) == len(joint_names):
636 rospy.logerr(
"no valid parameter for %s: dimension should be %d and is %d, aborting...",component_name,len(joint_names),len(point))
637 print(
"parameter is:",param)
638 return (JointTrajectory(), 3)
642 if not ((type(value)
is float)
or (type(value)
is int)):
644 rospy.logerr(
"no valid parameter for %s: not a list of float or int, aborting...",component_name)
645 print(
"parameter is:",param)
646 return (JointTrajectory(), 3)
648 rospy.logdebug(
"accepted value %f for %s",value,component_name)
651 rospy.logdebug(
"accepted trajectory for %s",component_name)
652 rospy.logdebug(
"traj after param: {}".format(traj))
657 joint_state_topic = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/joint_state_topic",
"/" + component_name +
"/joint_states")
658 joint_state_message = rospy.wait_for_message(joint_state_topic, JointState, timeout = timeout)
661 for name
in joint_names:
662 idx = joint_state_message.name.index(name)
663 start_pos.append(joint_state_message.position[idx])
664 except rospy.ROSException
as e:
665 rospy.logwarn(
"no joint states received from %s within timeout of %ssec. using default point time of 8sec.", component_name, str(timeout))
670 traj.insert(0,start_pos)
671 rospy.logdebug(
"traj after add: {}".format(traj))
674 traj_msg = JointTrajectory()
676 traj_msg.joint_names = joint_names
683 except ValueError
as val_err:
684 rospy.logerr(val_err)
685 return (JointTrajectory(), 3)
688 param_string = self.
ns_global_prefix +
"/" + component_name +
"/default_acc" 689 if not rospy.has_param(param_string):
690 default_acc = numpy.array([1.0
for _
in start_pos])
691 rospy.logwarn(
"parameter '{}' does not exist on ROS Parameter Server, using default_acc {} [rad^2/sec].".format(param_string,default_acc))
693 param_acc = rospy.get_param(param_string)
694 if (type(param_acc)
is float)
or (type(param_acc)
is int):
695 default_acc = numpy.array([param_acc
for _
in start_pos])
696 elif (type(param_acc)
is list)
and (len(param_acc) == len(start_pos))
and all(
697 ((type(item)
is float)
or (type(item)
is int))
for item
in param_acc):
698 default_acc = numpy.array(param_acc)
700 default_acc = numpy.array([1.0
for _
in start_pos])
701 rospy.logwarn(
"parameter '{}' {} has wrong format (must be float/int or list of float/int), using default_acc {} [rad^2/sec].".format(param_string,param_acc,default_acc))
705 return numpy.all(numpy.isclose(numpy.array(a), numpy.array(b), atol=0.001))
707 def unique_next(elems):
708 for i, (curr, nxt)
in enumerate(zip(elems, elems[1:]+[
None])):
712 if not is_close(curr, nxt):
715 rospy.logdebug(
"dropping trajectory point {} due to is close: (curr {}, nxt: {})".format(i, curr, nxt))
718 traj = list(unique_next(traj))
719 except Exception
as e:
721 return (JointTrajectory(), 3)
722 rospy.logdebug(
"traj after unique_nxt: {}".format(traj))
726 point_nr = point_nr + 1
727 point_msg = JointTrajectoryPoint()
728 point_msg.positions = point
734 point_time = 8*point_nr
737 point_msg.time_from_start=rospy.Duration(point_time + traj_time)
738 traj_time += point_time
739 traj_msg.points.append(point_msg)
742 prevs, items, nexts = itertools.tee(traj_msg.points, 3)
743 prevs = itertools.chain([
None], prevs)
744 nexts = itertools.chain(itertools.islice(nexts, 1,
None), [
None])
745 for idx, (pre, curr, post)
in enumerate(zip(prevs, items, nexts)):
750 traj_msg.points = traj_msg.points[1:]
755 if isinstance(default_vel, float):
756 default_vel = numpy.array([default_vel
for _
in start_pos])
758 if isinstance(default_acc, float):
759 default_acc = numpy.array([default_acc
for _
in start_pos])
763 dist = numpy.abs(numpy.array(start_pos) - numpy.array(end_pos))
765 t1 = default_vel / default_acc
766 s1 = default_acc / 2.0 * t1**2
768 t = numpy.zeros_like(dist)
770 for i
in range(len(start_pos)):
771 if 2 * s1[i] < dist[i]:
785 s2 = dist[i] - 2 * s1[i]
786 t2 = s2 / default_vel[i]
787 t[i] = 2 * t1[i] + t2
794 t[i] = numpy.sqrt(dist[i] / default_acc[i])
799 point_time = numpy.max(t)
800 except ValueError
as e:
801 print(
"Value Error: {}".format(e))
802 print(
"Likely due to mimic joints. Using default point_time: 3.0 [sec]")
807 rospy.logdebug(
"calculate_point_velocities")
808 rospy.logdebug(
"prev: {}".format(prev))
809 rospy.logdebug(
"curr: {}".format(curr))
810 rospy.logdebug(
"post: {}".format(post))
812 if stop_at_waypoints:
813 rospy.logdebug(
"stop_at_waypoints")
814 point_velocities = numpy.zeros(len(curr.positions))
816 rospy.logdebug(
"not has post")
817 point_velocities = numpy.zeros(len(curr.positions))
819 rospy.logdebug(
"not has prev")
820 point_velocities = numpy.zeros(len(curr.positions))
822 rospy.logdebug(
"has prev, has post")
824 point_velocities = numpy.divide(numpy.subtract(numpy.array(post.positions), numpy.array(prev.positions)), numpy.array([(post.time_from_start-prev.time_from_start).to_sec()]*len(curr.positions)))
825 rospy.logdebug(
"point_velocities diff quot: {}".format(point_velocities))
828 rospy.logdebug(
"has prev")
829 curr_prev_diff = numpy.subtract(numpy.array(curr.positions), numpy.array(prev.positions))
830 post_curr_diff = numpy.subtract(numpy.array(post.positions), numpy.array(curr.positions))
831 rospy.logdebug(
"curr_prev_diff: {}".format(curr_prev_diff))
832 rospy.logdebug(
"post_curr_diff: {}".format(post_curr_diff))
833 same_sign = numpy.equal(numpy.sign(curr_prev_diff), numpy.sign(post_curr_diff))
834 prev_close = numpy.isclose(curr_prev_diff, numpy.zeros_like(curr_prev_diff), atol=0.01)
835 post_close = numpy.isclose(post_curr_diff, numpy.zeros_like(post_curr_diff), atol=0.01)
836 rospy.logdebug(
"same_sign: {}".format(same_sign))
837 rospy.logdebug(
"prev_close: {}".format(prev_close))
838 rospy.logdebug(
"post_close: {}".format(post_close))
840 for idx, vel
in enumerate(point_velocities):
842 rospy.logdebug(
"prev close for joint {} - setting vel to 0.0".format(idx))
843 point_velocities[idx] = 0.0
845 rospy.logdebug(
"post close for joint {} - setting vel to 0.0".format(idx))
846 point_velocities[idx] = 0.0
847 if not same_sign[idx]:
848 rospy.logdebug(
"sign change for joint {} - setting vel to 0.0".format(idx))
849 point_velocities[idx] = 0.0
851 rospy.logdebug(
"point_velocities: {}".format(point_velocities))
852 return list(point_velocities)
855 return [0]*len(curr.positions)
864 def move_traj(self,component_name,parameter_name,blocking, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
871 rospy.loginfo(
"Move <<%s>> to <<%s>>",component_name,parameter_name)
872 (traj_msg, error_code) = self.
compose_trajectory(component_name, parameter_name, speed_factor=speed_factor, urdf_vel=urdf_vel, default_vel=default_vel, stop_at_waypoints=stop_at_waypoints)
874 message =
"Composing the trajectory failed with error: " + str(error_code)
875 ah.set_failed(error_code, message)
879 parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/action_name" 880 if not rospy.has_param(parameter_name):
881 message =
"Parameter " + parameter_name +
" does not exist on ROS Parameter Server, aborting..." 882 rospy.logerr(message)
883 ah.set_failed(2, message)
885 action_server_name = rospy.get_param(parameter_name)
886 rospy.logdebug(
"calling %s action server",action_server_name)
889 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
890 if not client.wait_for_server(rospy.Duration(1)):
892 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 893 rospy.logerr(message)
894 ah.set_failed(4, message)
897 rospy.logdebug(
"%s action server ready",action_server_name)
900 client_goal = FollowJointTrajectoryGoal()
901 client_goal.trajectory = traj_msg
903 client.send_goal(client_goal)
904 ah.set_client(client)
915 def move_base_rel(self, component_name, parameter_name=[0,0,0], blocking=True):
916 ah =
action_handle(
"move_base_rel", component_name, parameter_name, blocking, self.
parse)
920 ah.set_active(mode=
"topic")
922 parameter_topic_name = self.
ns_global_prefix +
"/" + component_name +
"/topic_name" 923 if not rospy.has_param(parameter_topic_name):
924 message =
"Parameter " + parameter_topic_name +
" does not exist on ROS Parameter Server, aborting..." 925 rospy.logerr(message)
926 ah.set_failed(3, message)
928 topic_name = rospy.get_param(parameter_topic_name)
929 rospy.loginfo(
"Move base relatively by <<%s>>", parameter_name)
932 if not len(parameter_name) == 3
or not isinstance(parameter_name[0], (int, float))
or not isinstance(parameter_name[1], (int, float))
or not isinstance(parameter_name[2], (int, float)):
933 message =
"Parameter " + parameter_name +
" not formated correctly (non-numeric list), aborting move_base_rel" 934 rospy.logerr(message)
935 print(
"parameter_name must be numeric list of length 3; (relative x and y transl [m], relative rotation [rad])")
936 ah.set_failed(3, message)
938 max_rel_trans_step = 1.0
939 max_rel_rot_step = math.pi/2
940 if math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) > max_rel_trans_step:
941 message =
"Parameter " + str(parameter_name) +
" exceeds maximal relative translation step (" + str(max_rel_trans_step) +
"), aborting move_base_rel" 942 rospy.logerr(message)
943 ah.set_failed(3, message)
945 if abs(parameter_name[2]) > max_rel_rot_step:
946 message =
"Parameter " + str(parameter_name) +
" exceeds maximal relative rotation step (" + str(max_rel_rot_step) +
"), aborting move_base_rel" 947 rospy.logerr(message)
948 ah.set_failed(3, message)
954 duration_trans_sec = math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) / max_trans_vel
955 duration_rot_sec = abs(parameter_name[2] / max_rot_vel)
956 duration_sec = max(duration_trans_sec, duration_rot_sec)
957 duration_ros = rospy.Duration.from_sec(duration_sec)
960 x_vel = parameter_name[0] / duration_sec
961 y_vel = parameter_name[1] / duration_sec
962 rot_vel = parameter_name[2] / duration_sec
965 pub = rospy.Publisher(topic_name, Twist, queue_size=1)
967 twist.linear.x = x_vel
968 twist.linear.y = y_vel
969 twist.angular.z = rot_vel
970 end_time = rospy.Time.now() + duration_ros
973 rospy.loginfo(
"Wait for <<%s>> to finish move_base_rel...", component_name)
976 Thread(target=self.
publish_twist, args=(pub, twist, end_time)).start()
983 while not rospy.is_shutdown()
and rospy.Time.now() < end_time:
997 def move_rel(self, component_name, parameter_name, blocking=True, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
1002 ah.set_active(mode=
"topic")
1004 rospy.loginfo(
"Move <<%s>> relatively by <<%s>>", component_name, parameter_name)
1007 param_string = self.
ns_global_prefix +
"/" + component_name +
"/joint_names" 1008 if not rospy.has_param(param_string):
1009 message =
"parameter " + str(param_string) +
" does not exist on ROS Parameter Server, aborting move_rel" 1010 rospy.logerr(message)
1011 ah.set_failed(3, message)
1013 joint_names = rospy.get_param(param_string)
1016 if not type(joint_names)
is list:
1017 message =
"no valid joint_names for " + str(component_name) +
": not a list, aborting move_rel" 1018 rospy.logerr(message)
1019 print(
"joint_names are:",joint_names)
1020 ah.set_failed(3, message)
1023 for i
in joint_names:
1025 if not type(i)
is str:
1026 message =
"no valid joint_names for " + str(component_name) +
": not a list of strings, aborting move_rel" 1027 rospy.logerr(message)
1028 print(
"joint_names are:", joint_names)
1029 ah.set_failed(3, message)
1032 rospy.logdebug(
"accepted joint_names for component %s",component_name)
1035 if not isinstance(parameter_name, list):
1036 message =
"Parameter " + str(parameter_name) +
" not formated correctly (not a list), aborting move_rel" 1037 rospy.logerr(message)
1038 ah.set_failed(3, message)
1040 for parameter
in parameter_name:
1041 if not isinstance(parameter, list):
1042 message =
"Parameter " + str(parameter_name) +
" not formated correctly (not a list of lists), aborting move_rel" 1043 rospy.logerr(message)
1044 ah.set_failed(3, message)
1046 for param
in parameter:
1047 if not isinstance(param, (int, float)):
1048 message =
"Parameter " + str(parameter) +
" not formated correctly (not a list of numeric lists), aborting move_rel" 1049 rospy.logerr(message)
1050 ah.set_failed(3, message)
1056 joint_state_topic = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/joint_state_topic",
"/" + component_name +
"/joint_states")
1057 joint_state_message = rospy.wait_for_message(joint_state_topic, JointState, timeout = timeout)
1060 for name
in joint_names:
1061 idx = joint_state_message.name.index(name)
1062 start_pos.append(joint_state_message.position[idx])
1063 except rospy.ROSException:
1064 message =
"no joint states received from %s within timeout of %ssec."%(component_name, str(timeout))
1065 rospy.logerr(message)
1066 ah.set_failed(3, message)
1071 message =
"Failed to get joint limits from urdf structure - urdf structure is not initialized" 1072 rospy.logerr(message)
1073 ah.set_failed(3, message)
1076 for joint
in self.robot_urdf.joints:
1077 limits.update({joint.name : joint.limit})
1081 for move_rel_param
in parameter_name:
1083 if len(start_pos) == len(move_rel_param)
and len(joint_names) == len(move_rel_param):
1084 for i
in range(len(joint_names)):
1085 if (end_poses == []):
1086 pos_val = start_pos[i] + move_rel_param[i]
1089 pos_val = end_poses[-1][i] + move_rel_param[i]
1091 if limits[joint_names[i]].upper > pos_val
and limits[joint_names[i]].lower < pos_val:
1092 end_pos.append(pos_val)
1094 message =
"Relative motion wil exceed absolute limits! %s would go to %f but limits are: %f (upper) and %f (lower)"%(joint_names[i], pos_val, limits[joint_names[i]].upper, limits[joint_names[i]].lower)
1095 rospy.logerr(message)
1096 ah.set_failed(3, message)
1099 message =
"Parameters %s don't fit with joint states!"%str(move_rel_param)
1100 rospy.logerr(message)
1101 ah.set_failed(3, message)
1103 end_poses.append(end_pos)
1105 return self.
move_traj(component_name, end_poses, blocking, speed_factor=speed_factor, urdf_vel=urdf_vel, default_vel=default_vel, stop_at_waypoints=stop_at_waypoints)
1116 if type(parameter_name)
is str:
1117 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + parameter_name
1118 if not rospy.has_param(full_parameter_name):
1119 rospy.logerr(
"parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
1121 param = rospy.get_param(full_parameter_name)
1123 param = parameter_name
1126 if not type(param)
is list:
1127 rospy.logerr(
"no valid parameter for light: not a list, aborting...")
1128 print(
"parameter is:",param)
1131 if not len(param) == 4:
1132 rospy.logerr(
"no valid parameter for light: dimension should be 4 (r,g,b,a) and is %d, aborting...",len(param))
1133 print(
"parameter is:",param)
1138 if not ((type(i)
is float)
or (type(i)
is int)):
1140 rospy.logerr(
"no valid parameter for light: not a list of float or int, aborting...")
1141 print(
"parameter is:",param)
1144 rospy.logdebug(
"accepted parameter %f for light",i)
1154 def set_light(self,component_name,parameter_name,blocking=False):
1155 ah =
action_handle(
"set_light", component_name, parameter_name, blocking, self.
parse)
1160 rospy.loginfo(
"Set <<%s>> to <<%s>>", component_name, parameter_name)
1163 mode.mode = LightModes.STATIC
1165 (error,color) = self.
compose_color(component_name, parameter_name)
1167 message =
"Composing the color failed with error: " + str(error)
1168 ah.set_failed(error, message)
1171 mode.colors.append(color)
1174 action_server_name = component_name +
"/set_light" 1175 rospy.logdebug(
"calling %s action server",action_server_name)
1178 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1179 if not client.wait_for_server(rospy.Duration(1)):
1181 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1182 rospy.logerr(message)
1183 ah.set_failed(4, message)
1186 rospy.logdebug(
"%s action server ready",action_server_name)
1189 goal = SetLightModeGoal()
1191 client.send_goal(goal)
1192 ah.set_client(client)
1203 def set_mimic(self,component_name,parameter_name,blocking=False):
1204 ah =
action_handle(
"set_mimic", component_name, parameter_name, blocking, self.
parse)
1209 rospy.loginfo(
"Set <<%s>> to <<%s>>", component_name, parameter_name)
1212 mimic = SetMimicGoal()
1213 if not (type(parameter_name)
is str
or type(parameter_name)
is list):
1214 message =
"No valid parameter for mimic: not a string or list, aborting..." 1215 rospy.logerr(message)
1216 print(
"parameter is:",parameter_name)
1217 ah.set_failed(3, message)
1220 if type(parameter_name)
is str:
1221 mimic.mimic = parameter_name
1222 elif type(parameter_name)
is list:
1223 if len(parameter_name) != 3:
1224 message =
"No valid parameter for mimic: not a list with size 3, aborting..." 1225 rospy.logerr(message)
1226 print(
"parameter is:",parameter_name)
1227 ah.set_failed(3, message)
1229 if ((type(parameter_name[0])
is str)
and (type(parameter_name[1])
is float
or type(parameter_name[1])
is int)
and (type(parameter_name[2])
is float
or type(parameter_name[2])
is int)):
1230 mimic.mimic = parameter_name[0]
1231 mimic.speed = parameter_name[1]
1232 mimic.repeat = parameter_name[2]
1234 message =
"No valid parameter for mimic: not a list with [mode, speed, repeat], aborting..." 1235 rospy.logerr(message)
1236 print(
"parameter is:",parameter_name)
1237 ah.set_failed(3, message)
1240 rospy.logerr(
"you should never be here")
1241 rospy.logdebug(
"accepted parameter %s for mimic",parameter_name)
1244 action_server_name = component_name +
"/set_mimic" 1245 rospy.logdebug(
"calling %s action server",action_server_name)
1248 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1249 if not client.wait_for_server(rospy.Duration(1)):
1251 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1252 rospy.logerr(message)
1253 ah.set_failed(4, message)
1256 rospy.logdebug(
"%s action server ready",action_server_name)
1259 client.send_goal(mimic)
1260 ah.set_client(client)
1271 def say(self,component_name,parameter_name,blocking=True):
1280 language = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/language",
"en")
1281 if type(parameter_name)
is str:
1282 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + language +
"/" + parameter_name
1283 if not rospy.has_param(full_parameter_name):
1284 message =
"Parameter " + full_parameter_name +
" does not exist on ROS Parameter Server, aborting..." 1285 rospy.logerr(message)
1286 ah.set_failed(2, message)
1288 param = rospy.get_param(full_parameter_name)
1290 param = parameter_name
1293 if not type(param)
is list:
1294 message =
"No valid parameter for " + component_name +
": not a list, aborting..." 1295 rospy.logerr(message)
1296 print(
"parameter is:",param)
1297 ah.set_failed(3, message)
1302 if not type(i)
is str:
1303 message =
"No valid parameter for " + component_name +
": not a list of strings, aborting..." 1304 rospy.logerr(message)
1305 print(
"parameter is:",param)
1306 ah.set_failed(3, message)
1309 text = text + i +
" " 1310 rospy.logdebug(
"accepted parameter <<%s>> for <<%s>>",i,component_name)
1311 rospy.loginfo(
"Saying <<%s>>",text)
1314 action_server_name = component_name +
"/say" 1315 rospy.logdebug(
"calling %s action server",action_server_name)
1318 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1319 if not client.wait_for_server(rospy.Duration(1)):
1321 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1322 rospy.logerr(message)
1323 ah.set_failed(4, message)
1326 rospy.logdebug(
"%s action server ready",action_server_name)
1329 client_goal = SayGoal()
1330 client_goal.text = text
1332 client.send_goal(client_goal)
1333 ah.set_client(client)
1341 def play(self,component_name, parameter_name,blocking=True):
1348 if not (type(parameter_name)
is str
or type(parameter_name)
is list):
1349 message =
"No valid parameter for play: not a string or list, aborting..." 1350 rospy.logerr(message)
1351 print(
"parameter is:",parameter_name)
1352 ah.set_failed(3, message)
1355 if type(parameter_name)
is str:
1356 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" +
"audio_file_path" 1357 if not rospy.has_param(full_parameter_name):
1358 message =
"Parameter " + full_parameter_name +
" does not exist on ROS Parameter Server, aborting..." 1359 rospy.logerr(message)
1360 ah.set_failed(2, message)
1362 filename = rospy.get_param(full_parameter_name) +
"/" + parameter_name +
".wav" 1363 elif type(parameter_name)
is list:
1364 if len(parameter_name) != 3:
1365 message =
"No valid parameter for play: not a list with size 3, aborting..." 1366 rospy.logerr(message)
1367 print(
"parameter is:",parameter_name)
1368 ah.set_failed(3, message)
1370 if ((type(parameter_name[0])
is str)
and (type(parameter_name[1])
is str)
and (type(parameter_name[2])
is str)):
1371 filename = parameter_name[1] +
"/" + parameter_name[0] +
"." + parameter_name[2]
1373 message =
"No valid parameter for play: not a list with [filename, file_path, file_suffix], aborting..." 1374 rospy.logerr(message)
1375 print(
"parameter is:",parameter_name)
1376 ah.set_failed(3, message)
1379 rospy.logerr(
"you should never be here")
1380 rospy.logdebug(
"accepted parameter %s for play",parameter_name)
1382 action_server_name = component_name +
"/play" 1383 rospy.logdebug(
"calling %s action server",action_server_name)
1386 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1387 if not client.wait_for_server(rospy.Duration(1)):
1389 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1390 rospy.logerr(message)
1391 ah.set_failed(4, message)
1394 rospy.logdebug(
"%s action server ready",action_server_name)
1397 rospy.loginfo(
"Playing <<%s>>",filename)
1398 client_goal = PlayGoal()
1399 client_goal.filename = filename
1401 client.send_goal(client_goal)
1402 ah.set_client(client)
1408 ah =
action_handle(
"set_wav_path",
"set_wav_path", parameter_name, blocking, self.
parse)
1409 if type(parameter_name)
is str:
1412 message =
"Invalid wav_path parameter specified, aborting..." 1413 rospy.logerr(message)
1414 print(
"parameter is:", parameter_name)
1415 ah.set_failed(2, message)
1429 rospy.loginfo(
"Wait for %f sec",duration)
1430 rospy.sleep(duration)
1449 rospy.logerr(
"Wait with duration not implemented yet")
1451 rospy.loginfo(
"Wait for user input...")
1452 retVal = six.moves.input()
1453 rospy.loginfo(
"...got string <<%s>>",retVal)
1463 def __init__(self, function_name, component_name, parameter_name, blocking, parse):
1475 self.
level = int(rospy.get_param(
"/script_server/level",100))
1476 self.
state_pub = rospy.Publisher(
"/script_server/state", ScriptState, queue_size=1)
1492 self.
state = ScriptState.ACTIVE
1501 param_string =
"/script_server/pause" 1502 while bool(rospy.get_param(param_string,
False)):
1503 rospy.logwarn(
"Script is paused...")
1504 self.
state = ScriptState.PAUSED
1507 if self.
state == ScriptState.PAUSED:
1508 rospy.loginfo(
"...continuing script")
1514 self.
state = ScriptState.SUCCEEDED
1527 self.
state = ScriptState.FAILED
1540 elif self.
client ==
None:
1541 return GoalStatus.LOST
1543 return self.client.get_state()
1559 if (function_name ==
"move"):
1561 elif (function_name ==
"init"):
1563 elif (function_name ==
"stop"):
1565 elif (function_name ==
"sleep"):
1574 global graph_wait_list
1580 graph.add_edge(last_node, graphstring)
1581 for waiter
in graph_wait_list:
1582 graph.add_edge(waiter, graphstring)
1585 last_node = graphstring
1595 script_state = ScriptState()
1596 script_state.header.stamp = rospy.Time.now()
1603 script_state.parameter_name =
"" 1604 script_state.state = self.
state 1606 self.state_pub.publish(script_state)
1638 global graph_wait_list
1645 if duration
is None:
1648 self.client.wait_for_result()
1652 if not self.client.wait_for_result(rospy.Duration(duration)):
1655 rospy.logerr(message)
1660 if self.client.get_state() != GoalStatus.SUCCEEDED:
1663 rospy.logerr(message)
1670 rospy.logwarn(message)
1680 self.client.cancel_all_goals()
def string_action(self, component_name, data, blocking)
Allows to trigger actions of the type cob_actions/SetString.
def GetGraphstring(self)
Returns the graphstring.
def calculate_point_time(self, start_pos, end_pos, default_vel, default_acc)
def recover(self, component_name, blocking=True)
Recovers different components.
def say(self, component_name, parameter_name, blocking=True)
Say some text.
def halt(self, component_name, blocking=True)
Halts different components.
def get_error_code(self)
Gets the error code of an action handle.
def _determine_desired_velocity(self, default_vel, start_pos, component_name, joint_names, speed_factor, urdf_vel)
def publish_twist(self, pub, twist, end_time)
def Parse(self)
Function to generate graph view of script.
def wait_for_finished(self, duration, logging)
Waits for the action to be finished.
def move_traj(self, component_name, parameter_name, blocking, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False)
Deals with all kind of trajectory movements for different components.
def set_mimic(self, component_name, parameter_name, blocking=False)
Set the mimic of the cob_mimic component.
def AppendNode(self, blocking=True)
Appends a registered function to the graph.
def calculate_point_accelerations(self, prev, curr, post)
def cancel(self)
Cancel action.
def Start(self)
Function to start the script.
def trigger_action(self, component_name, action_name, blocking=True)
Allows to trigger actions of the type actionlib/TestAction.
def move_rel(self, component_name, parameter_name, blocking=True, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False)
Relative movement Deals with all kind of relative movements for different components.
def Run(self)
Dummy function for main run function.
def get_state(self)
Gets the state of an action handle.
def init(self, component_name, blocking=True)
Initializes different components.
def wait(self, duration=None)
Handles wait.
def set_active(self, mode="")
Sets the execution state to active, if not paused.
def play(self, component_name, parameter_name, blocking=True)
Play a sound file.
def stop(self, component_name, mode="omni", blocking=True)
Stops different components.
def wait_for_input(self, duration=0)
Waits for user input.
def calculate_point_velocities(self, prev, curr, post, stop_at_waypoints=False)
def move(self, component_name, parameter_name, blocking=True, mode=None, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False)
Deals with all kind of movements for different components.
Script class from which all script inherit.
def sleep(self, duration)
Sleep for a certain time.
def compose_color(self, component_name, parameter_name)
Set the color of the cob_light component.
def set_client(self, client)
Sets the actionlib client.
def Initialize(self)
Dummy function for initialization.
def __init__(self, parse=False)
Initializes simple_script_server class.
def move_base_rel(self, component_name, parameter_name=[0, blocking=True)
Relative movement of the base.
def set_wav_path(self, parameter_name, blocking=True)
def PublishState(self)
Publishs the state of the action handle.
def compose_trajectory(self, component_name, parameter_name, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False)
Parse and compose trajectory message.
def check_pause(self)
Checks for pause.
def set_failed(self, error_code, message="")
Sets the execution state to failed.
def trigger(self, component_name, service_name, blocking=True)
Deals with all kind of trigger services for different components.
Simple script server class.
def GetLevel(self, function_name)
Gets level of function name.
def wait_inside(self, duration=None)
Handles inside wait.
def __init__(self, function_name, component_name, parameter_name, blocking, parse)
Initializes the action handle.
def move_base(self, component_name, parameter_name, blocking, mode)
Deals with movements of the base.
def set_light(self, component_name, parameter_name, blocking=False)
def set_succeeded(self, message="")
Sets the execution state to succeeded.