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())
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]")
813 if stop_at_waypoints:
815 point_velocities = numpy.zeros(len(curr.positions))
818 point_velocities = numpy.zeros(len(curr.positions))
821 point_velocities = numpy.zeros(len(curr.positions))
825 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)))
830 curr_prev_diff = numpy.subtract(numpy.array(curr.positions), numpy.array(prev.positions))
831 post_curr_diff = numpy.subtract(numpy.array(post.positions), numpy.array(curr.positions))
834 same_sign = numpy.equal(numpy.sign(curr_prev_diff), numpy.sign(post_curr_diff))
835 prev_close = numpy.isclose(curr_prev_diff, numpy.zeros_like(curr_prev_diff), atol=0.0001)
836 post_close = numpy.isclose(post_curr_diff, numpy.zeros_like(post_curr_diff), atol=0.0001)
841 for idx, vel
in enumerate(point_velocities):
844 point_velocities[idx] = 0.0
847 point_velocities[idx] = 0.0
848 if not same_sign[idx]:
850 point_velocities[idx] = 0.0
853 return list(point_velocities)
856 return [0]*len(curr.positions)
865 def move_traj(self,component_name,parameter_name,blocking, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
872 rospy.loginfo(
"Move <<%s>> to <<%s>>",component_name,parameter_name)
873 (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)
875 message =
"Composing the trajectory failed with error: " + str(error_code)
876 ah.set_failed(error_code, message)
880 parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/action_name" 881 if not rospy.has_param(parameter_name):
882 message =
"Parameter " + parameter_name +
" does not exist on ROS Parameter Server, aborting..." 883 rospy.logerr(message)
884 ah.set_failed(2, message)
886 action_server_name = rospy.get_param(parameter_name)
887 rospy.logdebug(
"calling %s action server",action_server_name)
890 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
891 if not client.wait_for_server(rospy.Duration(1)):
893 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 894 rospy.logerr(message)
895 ah.set_failed(4, message)
898 rospy.logdebug(
"%s action server ready",action_server_name)
901 client_goal = FollowJointTrajectoryGoal()
902 client_goal.trajectory = traj_msg
904 client.send_goal(client_goal)
905 ah.set_client(client)
916 def move_base_rel(self, component_name, parameter_name=[0,0,0], blocking=True):
917 ah =
action_handle(
"move_base_rel", component_name, parameter_name, blocking, self.
parse)
921 ah.set_active(mode=
"topic")
923 parameter_topic_name = self.
ns_global_prefix +
"/" + component_name +
"/topic_name" 924 if not rospy.has_param(parameter_topic_name):
925 message =
"Parameter " + parameter_topic_name +
" does not exist on ROS Parameter Server, aborting..." 926 rospy.logerr(message)
927 ah.set_failed(3, message)
929 topic_name = rospy.get_param(parameter_topic_name)
930 rospy.loginfo(
"Move base relatively by <<%s>>", parameter_name)
933 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)):
934 message =
"Parameter " + parameter_name +
" not formated correctly (non-numeric list), aborting move_base_rel" 935 rospy.logerr(message)
936 print(
"parameter_name must be numeric list of length 3; (relative x and y transl [m], relative rotation [rad])")
937 ah.set_failed(3, message)
939 max_rel_trans_step = 1.0
940 max_rel_rot_step = math.pi/2
941 if math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) > max_rel_trans_step:
942 message =
"Parameter " + str(parameter_name) +
" exceeds maximal relative translation step (" + str(max_rel_trans_step) +
"), aborting move_base_rel" 943 rospy.logerr(message)
944 ah.set_failed(3, message)
946 if abs(parameter_name[2]) > max_rel_rot_step:
947 message =
"Parameter " + str(parameter_name) +
" exceeds maximal relative rotation step (" + str(max_rel_rot_step) +
"), aborting move_base_rel" 948 rospy.logerr(message)
949 ah.set_failed(3, message)
955 duration_trans_sec = math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) / max_trans_vel
956 duration_rot_sec = abs(parameter_name[2] / max_rot_vel)
957 duration_sec = max(duration_trans_sec, duration_rot_sec)
958 duration_ros = rospy.Duration.from_sec(duration_sec)
961 x_vel = parameter_name[0] / duration_sec
962 y_vel = parameter_name[1] / duration_sec
963 rot_vel = parameter_name[2] / duration_sec
966 pub = rospy.Publisher(topic_name, Twist, queue_size=1)
968 twist.linear.x = x_vel
969 twist.linear.y = y_vel
970 twist.angular.z = rot_vel
971 end_time = rospy.Time.now() + duration_ros
974 rospy.loginfo(
"Wait for <<%s>> to finish move_base_rel...", component_name)
977 Thread(target=self.
publish_twist, args=(pub, twist, end_time)).start()
984 while not rospy.is_shutdown()
and rospy.Time.now() < end_time:
998 def move_rel(self, component_name, parameter_name, blocking=True, speed_factor=1.0, urdf_vel=False, default_vel=None, stop_at_waypoints=False):
1003 ah.set_active(mode=
"topic")
1005 rospy.loginfo(
"Move <<%s>> relatively by <<%s>>", component_name, parameter_name)
1008 param_string = self.
ns_global_prefix +
"/" + component_name +
"/joint_names" 1009 if not rospy.has_param(param_string):
1010 message =
"parameter " + str(param_string) +
" does not exist on ROS Parameter Server, aborting move_rel" 1011 rospy.logerr(message)
1012 ah.set_failed(3, message)
1014 joint_names = rospy.get_param(param_string)
1017 if not type(joint_names)
is list:
1018 message =
"no valid joint_names for " + str(component_name) +
": not a list, aborting move_rel" 1019 rospy.logerr(message)
1020 print(
"joint_names are:",joint_names)
1021 ah.set_failed(3, message)
1024 for i
in joint_names:
1026 if not type(i)
is str:
1027 message =
"no valid joint_names for " + str(component_name) +
": not a list of strings, aborting move_rel" 1028 rospy.logerr(message)
1029 print(
"joint_names are:", joint_names)
1030 ah.set_failed(3, message)
1033 rospy.logdebug(
"accepted joint_names for component %s",component_name)
1036 if not isinstance(parameter_name, list):
1037 message =
"Parameter " + str(parameter_name) +
" not formated correctly (not a list), aborting move_rel" 1038 rospy.logerr(message)
1039 ah.set_failed(3, message)
1041 for parameter
in parameter_name:
1042 if not isinstance(parameter, list):
1043 message =
"Parameter " + str(parameter_name) +
" not formated correctly (not a list of lists), aborting move_rel" 1044 rospy.logerr(message)
1045 ah.set_failed(3, message)
1047 for param
in parameter:
1048 if not isinstance(param, (int, float)):
1049 message =
"Parameter " + str(parameter) +
" not formated correctly (not a list of numeric lists), aborting move_rel" 1050 rospy.logerr(message)
1051 ah.set_failed(3, message)
1057 joint_state_topic = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/joint_state_topic",
"/" + component_name +
"/joint_states")
1058 joint_state_message = rospy.wait_for_message(joint_state_topic, JointState, timeout = timeout)
1061 for name
in joint_names:
1062 idx = joint_state_message.name.index(name)
1063 start_pos.append(joint_state_message.position[idx])
1064 except rospy.ROSException:
1065 message =
"no joint states received from %s within timeout of %ssec."%(component_name, str(timeout))
1066 rospy.logerr(message)
1067 ah.set_failed(3, message)
1072 message =
"Failed to get joint limits from urdf structure - urdf structure is not initialized" 1073 rospy.logerr(message)
1074 ah.set_failed(3, message)
1078 limits.update({joint.name : joint.limit})
1082 for move_rel_param
in parameter_name:
1084 if len(start_pos) == len(move_rel_param)
and len(joint_names) == len(move_rel_param):
1085 for i
in range(len(joint_names)):
1086 if (end_poses == []):
1087 pos_val = start_pos[i] + move_rel_param[i]
1090 pos_val = end_poses[-1][i] + move_rel_param[i]
1092 if limits[joint_names[i]].upper > pos_val
and limits[joint_names[i]].lower < pos_val:
1093 end_pos.append(pos_val)
1095 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)
1096 rospy.logerr(message)
1097 ah.set_failed(3, message)
1100 message =
"Parameters %s don't fit with joint states!"%str(move_rel_param)
1101 rospy.logerr(message)
1102 ah.set_failed(3, message)
1104 end_poses.append(end_pos)
1106 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)
1117 if type(parameter_name)
is str:
1118 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + parameter_name
1119 if not rospy.has_param(full_parameter_name):
1120 rospy.logerr(
"parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
1122 param = rospy.get_param(full_parameter_name)
1124 param = parameter_name
1127 if not type(param)
is list:
1128 rospy.logerr(
"no valid parameter for light: not a list, aborting...")
1129 print(
"parameter is:",param)
1132 if not len(param) == 4:
1133 rospy.logerr(
"no valid parameter for light: dimension should be 4 (r,g,b,a) and is %d, aborting...",len(param))
1134 print(
"parameter is:",param)
1139 if not ((type(i)
is float)
or (type(i)
is int)):
1141 rospy.logerr(
"no valid parameter for light: not a list of float or int, aborting...")
1142 print(
"parameter is:",param)
1145 rospy.logdebug(
"accepted parameter %f for light",i)
1155 def set_light(self,component_name,parameter_name,blocking=False):
1156 ah =
action_handle(
"set_light", component_name, parameter_name, blocking, self.
parse)
1161 rospy.loginfo(
"Set <<%s>> to <<%s>>", component_name, parameter_name)
1164 mode.mode = LightModes.STATIC
1166 (error,color) = self.
compose_color(component_name, parameter_name)
1168 message =
"Composing the color failed with error: " + str(error)
1169 ah.set_failed(error, message)
1172 mode.colors.append(color)
1175 action_server_name = component_name +
"/set_light" 1176 rospy.logdebug(
"calling %s action server",action_server_name)
1179 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1180 if not client.wait_for_server(rospy.Duration(1)):
1182 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1183 rospy.logerr(message)
1184 ah.set_failed(4, message)
1187 rospy.logdebug(
"%s action server ready",action_server_name)
1190 goal = SetLightModeGoal()
1192 client.send_goal(goal)
1193 ah.set_client(client)
1204 def set_mimic(self,component_name,parameter_name,blocking=False):
1205 ah =
action_handle(
"set_mimic", component_name, parameter_name, blocking, self.
parse)
1210 rospy.loginfo(
"Set <<%s>> to <<%s>>", component_name, parameter_name)
1213 mimic = SetMimicGoal()
1214 if not (type(parameter_name)
is str
or type(parameter_name)
is list):
1215 message =
"No valid parameter for mimic: not a string or list, aborting..." 1216 rospy.logerr(message)
1217 print(
"parameter is:",parameter_name)
1218 ah.set_failed(3, message)
1221 if type(parameter_name)
is str:
1222 mimic.mimic = parameter_name
1223 elif type(parameter_name)
is list:
1224 if len(parameter_name) != 3:
1225 message =
"No valid parameter for mimic: not a list with size 3, aborting..." 1226 rospy.logerr(message)
1227 print(
"parameter is:",parameter_name)
1228 ah.set_failed(3, message)
1230 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)):
1231 mimic.mimic = parameter_name[0]
1232 mimic.speed = parameter_name[1]
1233 mimic.repeat = parameter_name[2]
1235 message =
"No valid parameter for mimic: not a list with [mode, speed, repeat], aborting..." 1236 rospy.logerr(message)
1237 print(
"parameter is:",parameter_name)
1238 ah.set_failed(3, message)
1241 rospy.logerr(
"you should never be here")
1242 rospy.logdebug(
"accepted parameter %s for mimic",parameter_name)
1245 action_server_name = component_name +
"/set_mimic" 1246 rospy.logdebug(
"calling %s action server",action_server_name)
1249 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1250 if not client.wait_for_server(rospy.Duration(1)):
1252 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1253 rospy.logerr(message)
1254 ah.set_failed(4, message)
1257 rospy.logdebug(
"%s action server ready",action_server_name)
1260 client.send_goal(mimic)
1261 ah.set_client(client)
1272 def say(self,component_name,parameter_name,blocking=True):
1281 language = rospy.get_param(self.
ns_global_prefix +
"/" + component_name +
"/language",
"en")
1282 if type(parameter_name)
is str:
1283 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" + language +
"/" + parameter_name
1284 if not rospy.has_param(full_parameter_name):
1285 message =
"Parameter " + full_parameter_name +
" does not exist on ROS Parameter Server, aborting..." 1286 rospy.logerr(message)
1287 ah.set_failed(2, message)
1289 param = rospy.get_param(full_parameter_name)
1291 param = parameter_name
1294 if not type(param)
is list:
1295 message =
"No valid parameter for " + component_name +
": not a list, aborting..." 1296 rospy.logerr(message)
1297 print(
"parameter is:",param)
1298 ah.set_failed(3, message)
1303 if not type(i)
is str:
1304 message =
"No valid parameter for " + component_name +
": not a list of strings, aborting..." 1305 rospy.logerr(message)
1306 print(
"parameter is:",param)
1307 ah.set_failed(3, message)
1310 text = text + i +
" " 1311 rospy.logdebug(
"accepted parameter <<%s>> for <<%s>>",i,component_name)
1312 rospy.loginfo(
"Saying <<%s>>",text)
1315 action_server_name = component_name +
"/say" 1316 rospy.logdebug(
"calling %s action server",action_server_name)
1319 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1320 if not client.wait_for_server(rospy.Duration(1)):
1322 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1323 rospy.logerr(message)
1324 ah.set_failed(4, message)
1327 rospy.logdebug(
"%s action server ready",action_server_name)
1330 client_goal = SayGoal()
1331 client_goal.text = text
1333 client.send_goal(client_goal)
1334 ah.set_client(client)
1342 def play(self,component_name, parameter_name,blocking=True):
1349 if not (type(parameter_name)
is str
or type(parameter_name)
is list):
1350 message =
"No valid parameter for play: not a string or list, aborting..." 1351 rospy.logerr(message)
1352 print(
"parameter is:",parameter_name)
1353 ah.set_failed(3, message)
1356 if type(parameter_name)
is str:
1357 full_parameter_name = self.
ns_global_prefix +
"/" + component_name +
"/" +
"audio_file_path" 1358 if not rospy.has_param(full_parameter_name):
1359 message =
"Parameter " + full_parameter_name +
" does not exist on ROS Parameter Server, aborting..." 1360 rospy.logerr(message)
1361 ah.set_failed(2, message)
1363 filename = rospy.get_param(full_parameter_name) +
"/" + parameter_name +
".wav" 1364 elif type(parameter_name)
is list:
1365 if len(parameter_name) != 3:
1366 message =
"No valid parameter for play: not a list with size 3, aborting..." 1367 rospy.logerr(message)
1368 print(
"parameter is:",parameter_name)
1369 ah.set_failed(3, message)
1371 if ((type(parameter_name[0])
is str)
and (type(parameter_name[1])
is str)
and (type(parameter_name[2])
is str)):
1372 filename = parameter_name[1] +
"/" + parameter_name[0] +
"." + parameter_name[2]
1374 message =
"No valid parameter for play: not a list with [filename, file_path, file_suffix], aborting..." 1375 rospy.logerr(message)
1376 print(
"parameter is:",parameter_name)
1377 ah.set_failed(3, message)
1380 rospy.logerr(
"you should never be here")
1381 rospy.logdebug(
"accepted parameter %s for play",parameter_name)
1383 action_server_name = component_name +
"/play" 1384 rospy.logdebug(
"calling %s action server",action_server_name)
1387 rospy.logdebug(
"waiting for %s action server to start",action_server_name)
1388 if not client.wait_for_server(rospy.Duration(1)):
1390 message =
"ActionServer " + action_server_name +
" not ready within timeout, aborting..." 1391 rospy.logerr(message)
1392 ah.set_failed(4, message)
1395 rospy.logdebug(
"%s action server ready",action_server_name)
1398 rospy.loginfo(
"Playing <<%s>>",filename)
1399 client_goal = PlayGoal()
1400 client_goal.filename = filename
1402 client.send_goal(client_goal)
1403 ah.set_client(client)
1409 ah =
action_handle(
"set_wav_path",
"set_wav_path", parameter_name, blocking, self.
parse)
1410 if type(parameter_name)
is str:
1413 message =
"Invalid wav_path parameter specified, aborting..." 1414 rospy.logerr(message)
1415 print(
"parameter is:", parameter_name)
1416 ah.set_failed(2, message)
1430 rospy.loginfo(
"Wait for %f sec",duration)
1431 rospy.sleep(duration)
1450 rospy.logerr(
"Wait with duration not implemented yet")
1452 rospy.loginfo(
"Wait for user input...")
1453 retVal = six.moves.input()
1454 rospy.loginfo(
"...got string <<%s>>",retVal)
1464 def __init__(self, function_name, component_name, parameter_name, blocking, parse):
1476 self.
level = int(rospy.get_param(
"/script_server/level",100))
1477 self.
state_pub = rospy.Publisher(
"/script_server/state", ScriptState, queue_size=1)
1493 self.
state = ScriptState.ACTIVE
1502 param_string =
"/script_server/pause" 1503 while bool(rospy.get_param(param_string,
False)):
1504 rospy.logwarn(
"Script is paused...")
1505 self.
state = ScriptState.PAUSED
1508 if self.
state == ScriptState.PAUSED:
1509 rospy.loginfo(
"...continuing script")
1515 self.
state = ScriptState.SUCCEEDED
1528 self.
state = ScriptState.FAILED
1541 elif self.
client ==
None:
1542 return GoalStatus.LOST
1560 if (function_name ==
"move"):
1562 elif (function_name ==
"init"):
1564 elif (function_name ==
"stop"):
1566 elif (function_name ==
"sleep"):
1575 global graph_wait_list
1581 graph.add_edge(last_node, graphstring)
1582 for waiter
in graph_wait_list:
1583 graph.add_edge(waiter, graphstring)
1586 last_node = graphstring
1596 script_state = ScriptState()
1597 script_state.header.stamp = rospy.Time.now()
1604 script_state.parameter_name =
"" 1605 script_state.state = self.
state 1639 global graph_wait_list
1646 if duration
is None:
1649 self.
client.wait_for_result()
1653 if not self.
client.wait_for_result(rospy.Duration(duration)):
1656 rospy.logerr(message)
1664 rospy.logerr(message)
1671 rospy.logwarn(message)
1681 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.