예제 #1
0
    def _param_tag(self, tag, context, ros_config, force_local=False, verbose=True):
        """
        @param force_local: if True, param must be added to context instead of ros_config
        @type  force_local: bool
        """
        try:
            self._check_attrs(tag, context, ros_config, XmlLoader.PARAM_ATTRS)

            # compute name and value
            ptype = (tag.getAttribute('type') or 'auto').lower().strip()
            
            vals = self.opt_attrs(tag, context, ('value', 'textfile', 'binfile', 'command'))
            if len([v for v in vals if v is not None]) != 1:
                raise XmlParseException(
                    "<param> tag must have one and only one of value/textfile/binfile.")

            # compute name. if name is a tilde name, it is placed in
            # the context. otherwise it is placed in the ros config.
            name = self.resolve_args(tag.attributes['name'].value.strip(), context)
            value = self.param_value(verbose, name, ptype, *vals)

            if is_private(name) or force_local:
                p = Param(name, value)
                context.add_param(p)
            else:
                p = Param(ns_join(context.ns, name), value)
                ros_config.add_param(Param(ns_join(context.ns, name), value), filename=context.filename, verbose=verbose)
            return p

        except KeyError as e:
            raise XmlParseException(
                "<param> tag is missing required attribute: %s. \n\nParam xml is %s"%(e, tag.toxml()))
        except ValueError as e:
            raise XmlParseException(
                "Invalid <param> tag: %s. \n\nParam xml is %s"%(e, tag.toxml()))
예제 #2
0
    def _param_tag(self, tag, context, ros_config, force_local=False, verbose=True):
        """
        @param force_local: if True, param must be added to context instead of ros_config
        @type  force_local: bool
        """
        try:
            self._check_attrs(tag, context, ros_config, XmlLoader.PARAM_ATTRS)

            # compute name and value
            ptype = (tag.getAttribute('type') or 'auto').lower().strip()
            
            vals = self.opt_attrs(tag, context, ('value', 'textfile', 'binfile', 'command'))
            if len([v for v in vals if v is not None]) != 1:
                raise XmlParseException(
                    "<param> tag must have one and only one of value/textfile/binfile.")

            # compute name. if name is a tilde name, it is placed in
            # the context. otherwise it is placed in the ros config.
            name = self.resolve_args(tag.attributes['name'].value.strip(), context)
            value = self.param_value(verbose, name, ptype, *vals)

            if is_private(name) or force_local:
                p = Param(name, value)
                context.add_param(p)
            else:
                p = Param(ns_join(context.ns, name), value)
                ros_config.add_param(Param(ns_join(context.ns, name), value), filename=context.filename, verbose=verbose)
            return p

        except KeyError as e:
            raise XmlParseException(
                "<param> tag is missing required attribute: %s. \n\nParam xml is %s"%(e, tag.toxml()))
        except ValueError as e:
            raise XmlParseException(
                "Invalid <param> tag: %s. \n\nParam xml is %s"%(e, tag.toxml()))
    def __init__(self, robot: DualArmRobot, controller_name: str):
        self.robot = robot
        self.action_name = ns_join(robot.robot_namespace, ns_join(controller_name, "follow_joint_trajectory"))
        self.server = actionlib.SimpleActionServer(self.action_name, FollowJointTrajectoryAction,
                                                   execute_cb=self.follow_trajectory_cb,
                                                   auto_start=False)

        self.client = actionlib.SimpleActionClient(self.action_name, FollowJointTrajectoryAction)
예제 #4
0
파일: __init__.py 프로젝트: Mygao/ros_comm
def print_params(params, ns):
    """
    Print contents of param dictionary to screen
    """
    if type(params) == dict:
        for k, v in params.items():
            if type(v) == dict:
                print_params(v, ns_join(ns, k))
            else:
                print("%s=%s"%(ns_join(ns, k), v))
    else:
        print(params)
예제 #5
0
def print_params(params, ns):
    """
    Print contents of param dictionary to screen
    """
    if type(params) == dict:
        for k, v in params.items():
            if type(v) == dict:
                print_params(v, ns_join(ns, k))
            else:
                print("%s=%s" % (ns_join(ns, k), v))
    else:
        print(params)
예제 #6
0
 def _set_param(self, ctx, my_state, test_vals, param_server):
     ctx = make_global_ns(ctx)
     for type, vals in test_vals:
         try:
             caller_id = ns_join(ctx, "node")
             count = 0
             for val in vals:
                 key = ns_join(caller_id, "%s-%s"%(type,count))
                 param_server.set_param(key, val)
                 self.assert_(param_server.has_param(key))
                 true_key = ns_join(ctx, key)
                 my_state[true_key] = val
                 count += 1
         except Exception:
             assert "getParam failed on type[%s], val[%s]"%(type,val)
예제 #7
0
    def __init__(self, ns='', synchronous=False, service_timeout=5.0):
        self._psi = _moveit_planning_scene_interface.PlanningSceneInterface(ns)

        self._pub_co = rospy.Publisher(ns_join(ns, 'collision_object'),
                                       CollisionObject,
                                       queue_size=100)
        self._pub_aco = rospy.Publisher(ns_join(ns,
                                                'attached_collision_object'),
                                        AttachedCollisionObject,
                                        queue_size=100)
        self.__synchronous = synchronous
        if self.__synchronous:
            self._apply_planning_scene_diff = rospy.ServiceProxy(
                ns_join(ns, 'apply_planning_scene'), ApplyPlanningScene)
            self._apply_planning_scene_diff.wait_for_service(service_timeout)
예제 #8
0
def resolve_name(name, caller_id=None):
    """
    Resolve a ROS name to its global, canonical form. Private ~names
    are resolved relative to the node name. 

    @param name: name to resolve.
    @type  name: str
    @param caller_id: node name to resolve relative to. To
    resolve to local namespace, omit this parameter (or use None)
    @type  caller_id: str
    @return: Resolved name. If name is empty/None, resolve_name
    returns parent namespace. If namespace is empty/None,
    @rtype: str
    """
    if not caller_id:
        caller_id = get_name()
    if not name: #empty string resolves to namespace
        return namespace(caller_id)

    name = str(name)  # enforce string conversion else struct.pack might raise UnicodeDecodeError (see #3998)
    name = canonicalize_name(name)
    if name[0] == SEP: #global name
        resolved_name = name
    elif is_private(name): #~name
        resolved_name = ns_join(caller_id, name[1:])
    else: #relative
        resolved_name = namespace(caller_id) + name

    #Mappings override general namespace-based resolution
    # - do this before canonicalization as remappings are meant to
    #   match the name as specified in the code
    if resolved_name in _resolved_mappings:
        return _resolved_mappings[resolved_name]
    else:
        return resolved_name
예제 #9
0
def resolve_name_without_node_name(name):
    """
    The need for this function is complicated -- Topics and Services can be created before init_node is called.
    In general, this is okay, unless the name is a ~name, in which
    case we have to raise an ValueError

    @param name: ROS name to resolve
    @type  name: str
    @raise ValueError: if name is a ~name
    @raise ROSInitException: if name is remapped to a ~name
    """
    if is_private(name):
        raise ValueError("~name topics cannot be created before init_node() has been called")

    # we use the underlying rosgraph.names.resolve_name to avoid dependencies on nodename/remappings
    fake_caller_id = ns_join(get_namespace(), 'node')
    fake_resolved = rosgraph.names.resolve_name(name, fake_caller_id)

    for m, v in _mappings.items():
        if rosgraph.names.resolve_name(m, fake_caller_id) == fake_resolved:
            if is_private(name):
                raise ROSInitException("due to the way this node is written, %s cannot be remapped to a ~name. \nThe declaration of topics/services must be moved after the call to init_node()"%name)
            else:
                return rosgraph.names.resolve_name(v, fake_caller_id)
    return fake_resolved
예제 #10
0
def set_param_raw(param, value, verbose=False):
    """
    Set param on the Parameter Server. Unlike L{set_param()}, this
    takes in a Python value to set instead of YAML.
    
    :param param: parameter name, ``str``
    :param value XmlRpcLegalValue: value to upload, ``XmlRpcLegalValue``
    """
    if type(value) == dict:
        # #1098 changing dictionary behavior to be an update, rather
        # than replace behavior.
        for k, v in value.items():
            # dictionary keys must be non-unicode strings
            if isinstance(k, str):
                set_param_raw(ns_join(param, k), v, verbose=verbose)
            else:
                raise RosParamException("YAML dictionaries must have string keys. Invalid dictionary is:\n%s"%value)
    else:
        try:
            expected_type = long
        except NameError :
            expected_type = int
      
        if type(value) == expected_type:
            if value > sys.maxsize:
                raise RosParamException("Overflow: Parameter Server integers must be 32-bit signed integers:\n\t-%s <= value <= %s"%(maxint - 1, maxint))
            
        try:
            get_param_server().setParam(param, value)
        except socket.error:
            raise RosParamIOException("Unable to communicate with master!")
        if verbose:
            print("set parameter [%s] to [%s]"%(param, value))
예제 #11
0
    def __init__(self, ns='', synchronous=False, service_timeout=5.0):
        """ Create a planning scene interface; it uses both C++ wrapped methods and scene manipulation topics. """
        self._psi = _moveit_planning_scene_interface.PlanningSceneInterface(ns)

        self._pub_co = rospy.Publisher(ns_join(ns, 'collision_object'),
                                       CollisionObject,
                                       queue_size=100)
        self._pub_aco = rospy.Publisher(ns_join(ns,
                                                'attached_collision_object'),
                                        AttachedCollisionObject,
                                        queue_size=100)
        self.__synchronous = synchronous
        if self.__synchronous:
            self._apply_planning_scene_diff = rospy.ServiceProxy(
                ns_join(ns, 'apply_planning_scene'), ApplyPlanningScene)
            self._apply_planning_scene_diff.wait_for_service(service_timeout)
예제 #12
0
파일: __init__.py 프로젝트: Mygao/ros_comm
def set_param_raw(param, value, verbose=False):
    """
    Set param on the Parameter Server. Unlike L{set_param()}, this
    takes in a Python value to set instead of YAML.
    
    :param param: parameter name, ``str``
    :param value XmlRpcLegalValue: value to upload, ``XmlRpcLegalValue``
    """
    if type(value) == dict:
        # #1098 changing dictionary behavior to be an update, rather
        # than replace behavior.
        for k, v in value.items():
            # dictionary keys must be non-unicode strings
            if isinstance(k, str):
                set_param_raw(ns_join(param, k), v, verbose=verbose)
            else:
                raise RosParamException("YAML dictionaries must have string keys. Invalid dictionary is:\n%s"%value)
    else:
        try:
            expected_type = long
        except NameError :
            expected_type = int
      
        if type(value) == expected_type:
            if value > sys.maxsize:
                raise RosParamException("Overflow: Parameter Server integers must be 32-bit signed integers:\n\t-%s <= value <= %s"%(maxint - 1, maxint))
            
        try:
            get_param_server().setParam(param, value)
        except socket.error:
            raise RosParamIOException("Unable to communicate with master!")
        if verbose:
            print("set parameter [%s] to [%s]"%(param, value))
예제 #13
0
 def process(self, loader, ros_launch_config):
     if self.namespace is None:
         param = '/'
     else:
         param = rn.ns_join('', self.namespace)
     loader.load_rosparam(loader.root_context, ros_launch_config,
                          self.command, param, self.param_file, '')
예제 #14
0
def resolve_name(name, caller_id=None):
    """
    Resolve a ROS name to its global, canonical form. Private ~names
    are resolved relative to the node name. 

    @param name: name to resolve.
    @type  name: str
    @param caller_id: node name to resolve relative to. To
    resolve to local namespace, omit this parameter (or use None)
    @type  caller_id: str
    @return: Resolved name. If name is empty/None, resolve_name
    returns parent namespace. If namespace is empty/None,
    @rtype: str
    """
    if not caller_id:
        caller_id = get_name()
    if not name: #empty string resolves to namespace
        return namespace(caller_id)

    name = canonicalize_name(name)
    if name[0] == SEP: #global name
        resolved_name = name
    elif is_private(name): #~name
        resolved_name = ns_join(caller_id, name[1:])
    else: #relative
        resolved_name = namespace(caller_id) + name

    #Mappings override general namespace-based resolution
    # - do this before canonicalization as remappings are meant to
    #   match the name as specified in the code
    if resolved_name in _resolved_mappings:
        return _resolved_mappings[resolved_name]
    else:
        return resolved_name
예제 #15
0
 def child(self, ns):
     """
     @param ns: sub-namespace of child context, or None if the
        child context shares the same namespace
     @type  ns: str
     @return: A child xml context that inherits from this context
     @rtype: L{LoaderContext}
     """
     if ns:
         if ns[0] == '/':  # global (discouraged)
             child_ns = ns
         elif ns == PRIV_NAME:  # ~name
             # private names can only be scoped privately or globally
             child_ns = PRIV_NAME
         else:
             child_ns = ns_join(self.ns, ns)
     else:
         child_ns = self.ns
     return LoaderContext(child_ns,
                          self.filename,
                          parent=self,
                          params=self.params,
                          env_args=self.env_args[:],
                          resolve_dict=deepcopy(self.resolve_dict),
                          arg_names=self.arg_names[:],
                          include_resolve_dict=self.include_resolve_dict)
예제 #16
0
    def add_param(self, ros_config, param_name, param_value, verbose=True):
        """
        Add L{Param} instances to launch config. Dictionary values are
        unrolled into individual parameters.

        @param ros_config: launch configuration
        @type  ros_config: L{ROSLaunchConfig}
        @param param_name: name of parameter namespace to load values
            into. If param_name is '/', param_value must be a dictionary
        @type  param_name: str
        @param param_value: value to assign to param_name. If
            param_value is a dictionary, it's values will be unrolled
            into individual parameters.
        @type  param_value: str
        @raise ValueError: if parameters cannot be processed into valid Params
        """

        # shouldn't ever happen
        if not param_name:
            raise ValueError("no parameter name specified")

        if param_name == '/' and type(param_value) != dict:
            raise ValueError(
                "Cannot load non-dictionary types into global namespace '/'")

        if type(param_value) == dict:
            # unroll params
            for k, v in param_value.items():
                self.add_param(ros_config,
                               ns_join(param_name, k),
                               v,
                               verbose=verbose)
        else:
            ros_config.add_param(Param(param_name, param_value),
                                 verbose=verbose)
    def __init__(self, robot_namespace: str = ''):
        """
        This class is designed around the needs of the trajectory_follower.TrajectoryFollower
        This class really only contains API that is needed by that class. The trajectory follower only needs to know about the
        basic ROS API -- how to send and get joint commands. However, because MoveIt trajectory execution relies (for now) on that
        TrajectoryFollower class, we do not want BaseRobot to use any MoveIt TrajectoryExeuction or rely on any trajectory
        execution services.
        """
        self.robot_namespace = robot_namespace
        # the robot namespace will be prepended by setting ROS_NAMESPACE environment variable or the ns="" in roslaunch
        joint_states_topic = ns_join(self.robot_namespace, 'joint_states')
        self.joint_state_listener = Listener(joint_states_topic, JointState)

        # NOTE: derived classes must set these values
        self.right_gripper_command_pub = None
        self.left_gripper_command_pub = None

        self.tf_wrapper = TF2Wrapper()

        try:
            self.robot_commander = moveit_commander.RobotCommander(
                ns=self.robot_namespace)
        except RuntimeError as e:
            rospy.logerr(
                "You may need to load the moveit planning context and robot description"
            )
            print(e)
예제 #18
0
def resolve_name_without_node_name(name):
    """
    The need for this function is complicated -- Topics and Services can be created before init_node is called.
    In general, this is okay, unless the name is a ~name, in which
    case we have to raise an ValueError

    @param name: ROS name to resolve
    @type  name: str
    @raise ValueError: if name is a ~name
    @raise ROSInitException: if name is remapped to a ~name
    """
    if is_private(name):
        raise ValueError("~name topics cannot be created before init_node() has been called")

    # we use the underlying rosgraph.names.resolve_name to avoid dependencies on nodename/remappings
    fake_caller_id = ns_join(get_namespace(), 'node')
    fake_resolved = rosgraph.names.resolve_name(name, fake_caller_id)

    for m, v in _mappings.items():
        if rosgraph.names.resolve_name(m, fake_caller_id) == fake_resolved:
            if is_private(name):
                raise ROSInitException("due to the way this node is written, %s cannot be remapped to a ~name. \nThe declaration of topics/services must be moved after the call to init_node()"%name)
            else:
                return rosgraph.names.resolve_name(v, fake_caller_id)
    return fake_resolved
예제 #19
0
    def _rosparam_tag(self, tag, context, ros_config, verbose=True):
        try:
            self._check_attrs(tag, context, ros_config,
                              XmlLoader.ROSPARAM_OPT_ATTRS)
            cmd, ns, file, param, subst_value = self.opt_attrs(
                tag, context, (XmlLoader.ROSPARAM_OPT_ATTRS))
            subst_value = _bool_attr(subst_value, False, 'subst_value')
            # ns atribute is a bit out-moded and is only left in for backwards compatibility
            param = ns_join(ns or '', param or '')

            # load is the default command
            cmd = cmd or 'load'
            value = _get_text(tag)
            if subst_value:
                value = self.resolve_args(value, context)
            self.load_rosparam(context,
                               ros_config,
                               cmd,
                               param,
                               file,
                               value,
                               verbose=verbose)

        except ValueError as e:
            raise loader.LoadException("error loading <rosparam> tag: \n\t" +
                                       str(e) + "\nXML is %s" % tag.toxml())
예제 #20
0
파일: loader.py 프로젝트: Aand1/ROSCH
    def add_param(self, ros_config, param_name, param_value, verbose=True):
        """
        Add L{Param} instances to launch config. Dictionary values are
        unrolled into individual parameters.

        @param ros_config: launch configuration
        @type  ros_config: L{ROSLaunchConfig}
        @param param_name: name of parameter namespace to load values
            into. If param_name is '/', param_value must be a dictionary
        @type  param_name: str
        @param param_value: value to assign to param_name. If
            param_value is a dictionary, it's values will be unrolled
            into individual parameters.
        @type  param_value: str
        @raise ValueError: if parameters cannot be processed into valid Params
        """

        # shouldn't ever happen
        if not param_name:
            raise ValueError("no parameter name specified")
        
        if param_name == '/' and type(param_value) != dict:
            raise ValueError("Cannot load non-dictionary types into global namespace '/'")

        if type(param_value) == dict:
            # unroll params
            for k, v in param_value.items():
                self.add_param(ros_config, ns_join(param_name, k), v, verbose=verbose)
        else:
            ros_config.add_param(Param(param_name, param_value), verbose=verbose)
    def __init__(self):
        super().__init__('victor')

        self.service_provider = GazeboServices()

        # register a new callback to stop when the rope is overstretched
        self.set_rope_end_points_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "set"), Position3DAction)
def _get_param_names(names, key, d):
    """
    helper recursive routine for getParamNames()
    @param names: list of param names to append to
    @type  names: [str]
    @param d: parameter tree node
    @type  d: dict
    @param key: parameter key for tree node d
    @type  key: str
    """
    
    #TODOXXX
    for k,v in d.iteritems():
        if type(v) == dict:
            _get_param_names(names, ns_join(key, k), v)
        else:
            names.append(ns_join(key, k))
예제 #23
0
    def __init__(self):
        super().__init__()
        self.color_image_listener = Listener(self.COLOR_IMAGE_TOPIC, Image)
        self.depth_image_listener = Listener(self.DEPTH_IMAGE_TOPIC, Image)
        self.state_color_viz_pub = rospy.Publisher("state_color_viz",
                                                   Image,
                                                   queue_size=10,
                                                   latch=True)
        self.state_depth_viz_pub = rospy.Publisher("state_depth_viz",
                                                   Image,
                                                   queue_size=10,
                                                   latch=True)
        self.last_action = None
        self.get_rope_end_points_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "get_dual_gripper_points"),
            GetDualGripperPoints)
        self.get_rope_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "get_rope_state"), GetRopeState)

        self.pos3d = Position3D()
        self.cdcpd_listener = Listener("cdcpd/output", PointCloud2)
        self.set_rope_state_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "set_rope_state"), SetRopeState)
        self.reset_srv = rospy.ServiceProxy("/gazebo/reset_simulation", Empty)

        try:
            self.left_gripper_bbox_pub = rospy.Publisher(
                '/left_gripper_bbox_pub',
                BoundingBox,
                queue_size=10,
                latch=True)
            self.right_gripper_bbox_pub = rospy.Publisher(
                '/right_gripper_bbox_pub',
                BoundingBox,
                queue_size=10,
                latch=True)
        except NameError:
            pass
        self.overstretching_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "rope_overstretched"),
            GetOverstretching)
        self.error_pub = rospy.Publisher("error", Float32, queue_size=10)

        self.max_action_attempts = 100

        self.robot_reset_rng = np.random.RandomState(0)
예제 #24
0
def test_script_resolve_name():
    from rosgraph.names import script_resolve_name, get_ros_namespace, ns_join

    assert '/global' == script_resolve_name('/myscript', '/global')
    val = script_resolve_name('/myscript', '')
    assert get_ros_namespace() == val, val
    val = script_resolve_name('/myscript', 'foo')
    assert ns_join(get_ros_namespace(), 'foo') == val, val
    assert '/myscript/private' == script_resolve_name('/myscript', '~private')
예제 #25
0
파일: test_names.py 프로젝트: Aand1/ROSCH
def test_script_resolve_name():
    from rosgraph.names import script_resolve_name, get_ros_namespace, ns_join

    assert '/global' == script_resolve_name('/myscript', '/global')
    val = script_resolve_name('/myscript', '')    
    assert get_ros_namespace() == val, val
    val = script_resolve_name('/myscript', 'foo')    
    assert ns_join(get_ros_namespace(), 'foo') == val, val
    assert '/myscript/private' == script_resolve_name('/myscript', '~private')    
    def __init__(self):
        super().__init__()
        self.service_provider = BaseServices()

        self.pos3d = Position3D()
        self.get_rope_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "get_rope_state"), GetRopeState)
        self.reset_sim_srv = rospy.ServiceProxy("/gazebo/reset_simulation",
                                                Empty)

        self.last_action = None
        self.max_action_attempts = 1000
예제 #27
0
 def _ns_clear_params_attr(self,
                           tag_name,
                           tag,
                           context,
                           ros_config,
                           node_name=None,
                           include_filename=None):
     """
     Common processing routine for xml tags with NS and CLEAR_PARAMS attributes
     
     @param tag: DOM Node
     @type  tag: Node
     @param context: current namespace context 
     @type  context: LoaderContext
     @param clear_params: list of params to clear
     @type  clear_params: [str]
     @param node_name: name of node (for use when tag_name == 'node')
     @type  node_name: str
     @param include_filename: <include> filename if this is an <include> tag. If specified, context will use include rules.
     @type  include_filename: str
     @return: loader context 
     @rtype:  L{LoaderContext}
     """
     if tag.hasAttribute(NS):
         ns = self.resolve_args(tag.getAttribute(NS), context)
         if not ns:
             raise XmlParseException(
                 "<%s> tag has an empty '%s' attribute" % (tag_name, NS))
     else:
         ns = None
     if include_filename is not None:
         child_ns = context.include_child(ns, include_filename)
     else:
         child_ns = context.child(ns)
     clear_p = self.resolve_args(tag.getAttribute(CLEAR_PARAMS), context)
     if clear_p:
         clear_p = _bool_attr(clear_p, False, 'clear_params')
         if clear_p:
             if tag_name == 'node':
                 if not node_name:
                     raise XmlParseException(
                         "<%s> tag must have a 'name' attribute to use '%s' attribute"
                         % (tag_name, CLEAR_PARAMS))
                 # use make_global_ns to give trailing slash in order to be consistent with XmlContext.ns
                 ros_config.add_clear_param(
                     make_global_ns(ns_join(child_ns.ns, node_name)))
             else:
                 if not ns:
                     raise XmlParseException(
                         "'ns' attribute must be set in order to use 'clear_params'"
                     )
                 ros_config.add_clear_param(child_ns.ns)
     return child_ns
    def __init__(self, robot_namespace):
        super().__init__()
        self.robot_namespace = robot_namespace
        self.service_provider = BaseServices()
        self.joint_state_viz_pub = rospy.Publisher(ns_join(
            self.robot_namespace, "joint_states_viz"),
                                                   JointState,
                                                   queue_size=10)
        self.goto_home_srv = rospy.ServiceProxy("goto_home", Empty)
        self.cdcpd_listener = Listener("cdcpd/output", PointCloud2)
        self.cdcpd_reset_srv = rospy.ServiceProxy("cdcpd/reset", Empty)
        self.attach_srv = rospy.ServiceProxy("/link_attacher_node/attach",
                                             Attach)
        self.detach_srv = rospy.ServiceProxy("/link_attacher_node/detach",
                                             Attach)

        exclude_srv_name = ns_join(self.robot_namespace,
                                   "exclude_models_from_planning_scene")
        self.exclude_from_planning_scene_srv = rospy.ServiceProxy(
            exclude_srv_name, ExcludeModels)
        # FIXME: this blocks until the robot is available, we need lazy construction
        self.robot = get_moveit_robot(self.robot_namespace)
예제 #29
0
    def _rosparam_tag(self, tag, context, ros_config, verbose=True):
        try:
            self._check_attrs(tag, context, ros_config, XmlLoader.ROSPARAM_OPT_ATTRS)
            cmd, ns, file, param = self.opt_attrs(tag, context, (XmlLoader.ROSPARAM_OPT_ATTRS))
            # ns atribute is a bit out-moded and is only left in for backwards compatibility
            param = ns_join(ns or '', param or '')
            
            # load is the default command            
            cmd = cmd or 'load'
            self.load_rosparam(context, ros_config, cmd, param, file, _get_text(tag), verbose=verbose)

        except ValueError as e:
            raise loader.LoadException("error loading <rosparam> tag: \n\t"+str(e)+"\nXML is %s"%tag.toxml())
def _compute_all_keys(param_key, param_value, all_keys=None):
    """
    Compute which subscribers should be notified based on the parameter update
    @param param_key: key of updated parameter
    @type  param_key: str
    @param param_value: value of updated parameter
    @param all_keys: (internal use only) list of parameter keys
        to append to for recursive calls.
    @type  all_keys: [str]
    @return: list of parameter keys. All keys will be canonicalized with trailing slash.
    @rtype: [str]
    """
    if all_keys is None:
        all_keys = []
    for k, v in param_value.iteritems():
        new_k = ns_join(param_key, k) + SEP 
        all_keys.append(new_k)
        if type(v) == dict:
            _compute_all_keys(new_k, v, all_keys)
    return all_keys
예제 #31
0
 def _ns_clear_params_attr(self, tag_name, tag, context, ros_config, node_name=None, include_filename=None):
     """
     Common processing routine for xml tags with NS and CLEAR_PARAMS attributes
     
     @param tag: DOM Node
     @type  tag: Node
     @param context: current namespace context 
     @type  context: LoaderContext
     @param clear_params: list of params to clear
     @type  clear_params: [str]
     @param node_name: name of node (for use when tag_name == 'node')
     @type  node_name: str
     @param include_filename: <include> filename if this is an <include> tag. If specified, context will use include rules.
     @type  include_filename: str
     @return: loader context 
     @rtype:  L{LoaderContext}
     """
     if tag.hasAttribute(NS):
         ns = self.resolve_args(tag.getAttribute(NS), context)
         if not ns:
             raise XmlParseException("<%s> tag has an empty '%s' attribute"%(tag_name, NS))
     else:
         ns = None
     if include_filename is not None:
         child_ns = context.include_child(ns, include_filename)
     else:
         child_ns = context.child(ns)
     clear_p = self.resolve_args(tag.getAttribute(CLEAR_PARAMS), context)
     if clear_p:
         clear_p = _bool_attr(clear_p, False, 'clear_params')
         if clear_p:
             if tag_name == 'node':
                 if not node_name:
                     raise XmlParseException("<%s> tag must have a 'name' attribute to use '%s' attribute"%(tag_name, CLEAR_PARAMS))
                 # use make_global_ns to give trailing slash in order to be consistent with XmlContext.ns
                 ros_config.add_clear_param(make_global_ns(ns_join(child_ns.ns, node_name)))
             else:
                 if not ns:
                     raise XmlParseException("'ns' attribute must be set in order to use 'clear_params'")                
                 ros_config.add_clear_param(child_ns.ns)
     return child_ns
예제 #32
0
파일: __init__.py 프로젝트: Mygao/ros_comm
def load_str(str, filename, default_namespace=None, verbose=False):
    """
    Load the YAML document as a string
    
    :param filename: name of filename, only used for debugging, ``str``
    :param default_namespace: namespace to load filename into, ``str``
    :param str: YAML text, ``str``
    :returns: list of parameter dictionary and
        corresponding namespaces for each YAML document in the file, ``[(dict, str)...]``
    """
    paramlist = []
    default_namespace = default_namespace or get_ros_namespace()
    for doc in yaml.load_all(str):
        if NS in doc:
            ns = ns_join(default_namespace, doc.get(NS, None))
            if verbose:
                print("reading parameters into namespace [%s]"%ns)
            del doc[NS]
        else:
            ns = default_namespace
        paramlist.append((doc, ns))
    return paramlist
예제 #33
0
def load_str(str, filename, default_namespace=None, verbose=False):
    """
    Load the YAML document as a string
    
    :param filename: name of filename, only used for debugging, ``str``
    :param default_namespace: namespace to load filename into, ``str``
    :param str: YAML text, ``str``
    :returns: list of parameter dictionary and
        corresponding namespaces for each YAML document in the file, ``[(dict, str)...]``
    """
    paramlist = []
    default_namespace = default_namespace or get_ros_namespace()
    for doc in yaml.load_all(str):
        if NS in doc:
            ns = ns_join(default_namespace, doc.get(NS, None))
            if verbose:
                print("reading parameters into namespace [%s]" % ns)
            del doc[NS]
        else:
            ns = default_namespace
        paramlist.append((doc, ns))
    return paramlist
예제 #34
0
파일: loader.py 프로젝트: Aand1/ROSCH
 def child(self, ns):
     """
     @param ns: sub-namespace of child context, or None if the
        child context shares the same namespace
     @type  ns: str
     @return: A child xml context that inherits from this context
     @rtype: L{LoaderContext}
     """
     if ns:
         if ns[0] == '/': # global (discouraged)
             child_ns = ns
         elif ns == PRIV_NAME: # ~name
             # private names can only be scoped privately or globally
             child_ns = PRIV_NAME
         else:
             child_ns = ns_join(self.ns, ns)
     else:
         child_ns = self.ns
     return LoaderContext(child_ns, self.filename, parent=self,
                          params=self.params, env_args=self.env_args[:],
                          resolve_dict=deepcopy(self.resolve_dict),
                          arg_names=self.arg_names[:], include_resolve_dict=self.include_resolve_dict)
예제 #35
0
    def process(self, loader, ros_launch_config):
        context = loader.root_context
        # Add all our params to the ROSLaunchConfig
        param_ns = context.child(self.node_name)
        for name, value in self.params.iteritems():
            loader_value = loader.param_value(self.verbose, name, 'auto',
                                              py_types_to_string(value), None,
                                              None, None)
            p = rr.Param(param_ns.ns + name, loader_value)
            ros_launch_config.add_param(p, verbose=self.verbose)

        for rp in self.rosparams:
            if rp.get_namespace() is None:
                rp.set_namespace(param_ns.ns)
            else:
                rp.set_namespace(rn.ns_join(param_ns.ns, rp.get_namespace()))
            rp.process(loader, ros_launch_config)

        # Add to a LoaderContext verify that names are legal
        remap_ns = context.child('')
        for r in self.remaps:
            remap_ns.add_remap(r)

        # Create our node
        self.node = rr.Node(
            self.package_name,
            self.node_type,
            self.node_name,
            remap_args=remap_ns.remap_args(),
            # Setting this pipes mutes the node's stdout.
            # namespace=param_ns.ns,
            namespace=self.namespace,
            args=self.args,
            respawn=self.respawn,
            respawn_delay=self.respawn_delay,
            output=self.output,
            launch_prefix=self.launch_prefix)
        ros_launch_config.add_node(self.node, self.verbose)
예제 #36
0
파일: loader.py 프로젝트: Aand1/ROSCH
    def load_rosparam(self, context, ros_config, cmd, param, file_, text, verbose=True):
        """
        Load rosparam setting
        
        @param context: Loader context
        @type  context: L{LoaderContext}
        @param ros_config: launch configuration
        @type  ros_config: L{ROSLaunchConfig}
        @param cmd: 'load', 'dump', or 'delete'
        @type  cmd: str
        @param file_: filename for rosparam to use or None
        @type  file_: str
        @param text: text for rosparam to load. Ignored if file_ is set.
        @type  text: str
        @raise ValueError: if parameters cannot be processed into valid rosparam setting
        """
        if not cmd in ('load', 'dump', 'delete'):
            raise ValueError("command must be 'load', 'dump', or 'delete'")
        if file_ is not None:
            if cmd == 'load' and not os.path.isfile(file_):
                raise ValueError("file does not exist [%s]"%file_)
            if cmd == 'delete':
                raise ValueError("'file' attribute is invalid with 'delete' command.")

        full_param = ns_join(context.ns, param) if param else context.ns

        if cmd == 'dump':
            ros_config.add_executable(RosbinExecutable('rosparam', (cmd, file_, full_param), PHASE_SETUP))
        elif cmd == 'delete':
            ros_config.add_executable(RosbinExecutable('rosparam', (cmd, full_param), PHASE_SETUP))
        elif cmd == 'load':
            # load YAML text
            if file_:
                with open(file_, 'r') as f:
                    text = f.read()
                    
            # parse YAML text
            # - lazy import
            global yaml
            if yaml is None:
                import yaml
            # - lazy import: we have to import rosparam in oder to to configure the YAML constructors
            global rosparam
            if rosparam is None:
                import rosparam
            try:
                data = yaml.load(text)
                # #3162: if there is no YAML, load() will return an
                # empty string.  We want an empty dictionary instead
                # for our representation of empty.
                if data is None:
                    data = {}
            except yaml.MarkedYAMLError as e:
                if not file_: 
                    raise ValueError("Error within YAML block:\n\t%s\n\nYAML is:\n%s"%(str(e), text))
                else:
                    raise ValueError("file %s contains invalid YAML:\n%s"%(file_, str(e)))
            except Exception as e:
                if not file_:
                    raise ValueError("invalid YAML: %s\n\nYAML is:\n%s"%(str(e), text))
                else:
                    raise ValueError("file %s contains invalid YAML:\n%s"%(file_, str(e)))

            # 'param' attribute is required for non-dictionary types
            if not param and type(data) != dict:
                raise ValueError("'param' attribute must be set for non-dictionary values")

            self.add_param(ros_config, full_param, data, verbose=verbose)

        else:
            raise ValueError("unknown command %s"%cmd)
    def search_param(self, ns, key):
        """
        Search for matching parameter key for search param
        key. Search for key starts at ns and proceeds upwards to
        the root. As such, search_param should only be called with a
        relative parameter name.

        search_param's behavior is to search for the first partial match.
        For example, imagine that there are two 'robot_description' parameters:

         - /robot_description
         -   /robot_description/arm
         -   /robot_description/base

         - /pr2/robot_description
         -   /pr2/robot_description/base

        If I start in the namespace /pr2/foo and search for
        'robot_description', search_param will match
        /pr2/robot_description. If I search for 'robot_description/arm'
        it will return /pr2/robot_description/arm, even though that
        parameter does not exist (yet).

        @param ns: namespace to begin search from.
        @type  ns: str
        @param key: Parameter key. 
        @type  key: str
        @return: key of matching parameter or None if no matching
        parameter.
        @rtype: str
        """
        if not key or is_private(key):
            raise ValueError("invalid key")
        if not is_global(ns):
            raise ValueError("namespace must be global")            
        if is_global(key):
            if self.has_param(key):
                return key
            else:
                return None

        # there are more efficient implementations, but our hiearchy
        # is not very deep and this is fairly clean code to read.

        # - we only search for the first namespace in the key to check for a match
        key_namespaces = [x for x in key.split(SEP) if x]
        key_ns = key_namespaces[0]

        #  - corner case: have to test initial namespace first as
        #    negative indices won't work with 0
        search_key = ns_join(ns, key_ns)
        if self.has_param(search_key):
            # resolve to full key
            return ns_join(ns, key) 
        
        namespaces = [x for x in ns.split(SEP) if x]
        for i in xrange(1, len(namespaces)+1):
            search_key = SEP + SEP.join(namespaces[0:-i] + [key_ns])
            if self.has_param(search_key):
                # we have a match on the namespace of the key, so
                # compose the full key and return it
                full_key = SEP + SEP.join(namespaces[0:-i] + [key]) 
                return full_key
        return None
예제 #38
0
#     aco.link_name = link
#     if len(touch_links) > 0:
#         aco.touch_links = touch_links
#     else:
#         aco.touch_links = [link]
#     self.__submit(aco, attach=True)

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Two argument required:")
        print("<setup_name> <work_name>:\tpublish urdf file <work_name>.urdf.")
        exit()
    else:
        package_name = sys.argv[1] + "_support"
        work_name = sys.argv[2]

    rospy.init_node("publish_work")
    aco_pub = rospy.Publisher(ns_join('', 'attached_collision_object'),
                              AttachedCollisionObject,
                              queue_size=100)

    scene = moveit_commander.PlanningSceneInterface()
    rospy.sleep(1.0)  # wait for the above things to setup

    remove_all_objects(scene)

    work = parse_urdf_file(package_name, work_name)
    publish_parsed_urdf(work, scene, aco_pub, attach=False)

    print("Done!")
 def ns(self, name: str):
     return ns_join(self.robot_namespace, name)
예제 #40
0
def get_camera_params(camera_name: str):
    camera_params_topic_name = ns_join(ns_join(camera_name, 'qhd'),
                                       "camera_info")
    camera_params_listener = Listener(camera_params_topic_name, CameraInfo)
    camera_params: CameraInfo = camera_params_listener.get()
    return camera_params
예제 #41
0
class FloatingRopeScenario(Base3DScenario):
    IMAGE_H = 90
    IMAGE_W = 160
    n_links = 25
    KINECT_NAME = "kinect2"
    COLOR_IMAGE_TOPIC = ns_join(KINECT_NAME, "qhd/image_color_rect")
    DEPTH_IMAGE_TOPIC = ns_join(KINECT_NAME, "qhd/image_depth_rect")
    crop_region = {
        'min_y': 0,
        'min_x': 0,
        'max_y': 540,
        'max_x': 960,
    }
    ROPE_NAMESPACE = 'rope_3d'

    # TODO: break out the different pieces of get_state to make them composable,
    #  since there are just a few shared amongst all the scenarios
    # TODO: about this... maybe they should all be pure functions? do we really need "self" at all?
    #  the one reason we have classes at all is so that we can describe interfaces via type hints
    def __init__(self):
        super().__init__()
        self.color_image_listener = Listener(self.COLOR_IMAGE_TOPIC, Image)
        self.depth_image_listener = Listener(self.DEPTH_IMAGE_TOPIC, Image)
        self.state_color_viz_pub = rospy.Publisher("state_color_viz",
                                                   Image,
                                                   queue_size=10,
                                                   latch=True)
        self.state_depth_viz_pub = rospy.Publisher("state_depth_viz",
                                                   Image,
                                                   queue_size=10,
                                                   latch=True)
        self.last_action = None
        self.get_rope_end_points_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "get_dual_gripper_points"),
            GetDualGripperPoints)
        self.get_rope_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "get_rope_state"), GetRopeState)

        self.pos3d = Position3D()
        self.cdcpd_listener = Listener("cdcpd/output", PointCloud2)
        self.set_rope_state_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "set_rope_state"), SetRopeState)
        self.reset_srv = rospy.ServiceProxy("/gazebo/reset_simulation", Empty)

        try:
            self.left_gripper_bbox_pub = rospy.Publisher(
                '/left_gripper_bbox_pub',
                BoundingBox,
                queue_size=10,
                latch=True)
            self.right_gripper_bbox_pub = rospy.Publisher(
                '/right_gripper_bbox_pub',
                BoundingBox,
                queue_size=10,
                latch=True)
        except NameError:
            pass
        self.overstretching_srv = rospy.ServiceProxy(
            ns_join(self.ROPE_NAMESPACE, "rope_overstretched"),
            GetOverstretching)
        self.error_pub = rospy.Publisher("error", Float32, queue_size=10)

        self.max_action_attempts = 100

        self.robot_reset_rng = np.random.RandomState(0)

    def needs_reset(self):
        res: GetOverstretchingResponse = self.overstretching_srv(
            GetOverstretchingRequest())
        return res.magnitude > 1.30

    def trajopt_distance_to_goal_differentiable(self, final_state,
                                                goal_state: Dict):
        return self.cfm_distance(final_state['z'], goal_state['z'])

    def trajopt_distance_differentiable(self, s1, s2):
        return self.cfm_distance(s1['z'], s2['z'])

    def cfm_distance(self, z1, z2):
        return tf.math.reduce_sum(tf.math.square(z1 - z2),
                                  axis=-1,
                                  keepdims=True)

    def get_environment(self, params: Dict, **kwargs):
        return {}

    def hard_reset(self):
        self.reset_srv(EmptyRequest())

    def randomization_initialization(self):
        pass

    def on_before_action(self):
        self.register_fake_grasping()

    def on_before_data_collection(self, params: Dict):
        self.on_before_action()

        left_gripper_position = np.array([1.0, 0.2, 1.0])
        right_gripper_position = np.array([1.0, -0.2, 1.0])
        init_action = {
            'left_gripper_position': left_gripper_position,
            'right_gripper_position': right_gripper_position,
        }
        self.execute_action(init_action)

    def execute_action(self, action: Dict):
        speed_mps = action.get('speed', 0.1)
        left_req = Position3DActionRequest(
            speed_mps=speed_mps,
            scoped_link_name=gz_scope(self.ROPE_NAMESPACE, 'left_gripper'),
            position=ros_numpy.msgify(Point, action['left_gripper_position']))
        right_req = Position3DActionRequest(
            speed_mps=speed_mps,
            scoped_link_name=gz_scope(self.ROPE_NAMESPACE, 'right_gripper'),
            position=ros_numpy.msgify(Point, action['right_gripper_position']))
        self.pos3d.set(left_req)
        self.pos3d.set(right_req)

        wait_req = Position3DWaitRequest()
        wait_req.timeout_s = 10.0
        wait_req.scoped_link_names.append(
            gz_scope(self.ROPE_NAMESPACE, 'left_gripper'))
        wait_req.scoped_link_names.append(
            gz_scope(self.ROPE_NAMESPACE, 'right_gripper'))
        self.pos3d.wait(wait_req)

        rope_settling_time = action.get('settling_time', 1.0)
        rospy.sleep(rope_settling_time)

    def reset_rope(self, action_params: Dict):
        reset = SetRopeStateRequest()

        # TODO: rename this to rope endpoints reset positions or something
        reset.left_gripper.x = numpify(
            action_params['left_gripper_reset_position'][0])
        reset.left_gripper.y = numpify(
            action_params['left_gripper_reset_position'][1])
        reset.left_gripper.z = numpify(
            action_params['left_gripper_reset_position'][2])
        reset.right_gripper.x = numpify(
            action_params['right_gripper_reset_position'][0])
        reset.right_gripper.y = numpify(
            action_params['right_gripper_reset_position'][1])
        reset.right_gripper.z = numpify(
            action_params['right_gripper_reset_position'][2])

        self.set_rope_state_srv(reset)

    def sample_action(self,
                      action_rng: np.random.RandomState,
                      environment: Dict,
                      state: Dict,
                      action_params: Dict,
                      validate: bool,
                      stateless: Optional[bool] = False):
        self.viz_action_sample_bbox(
            self.left_gripper_bbox_pub,
            self.get_action_sample_extent(action_params, 'left'))
        self.viz_action_sample_bbox(
            self.right_gripper_bbox_pub,
            self.get_action_sample_extent(action_params, 'right'))

        action = None
        for _ in range(self.max_action_attempts):
            # move in the same direction as the previous action with some probability
            repeat_probability = action_params[
                'repeat_delta_gripper_motion_probability']
            if not stateless and self.last_action is not None and action_rng.uniform(
                    0, 1) < repeat_probability:
                left_gripper_delta_position = self.last_action[
                    'left_gripper_delta_position']
                right_gripper_delta_position = self.last_action[
                    'right_gripper_delta_position']
            else:
                # Sample a new random action
                left_gripper_delta_position = self.sample_delta_position(
                    action_params, action_rng)
                right_gripper_delta_position = self.sample_delta_position(
                    action_params, action_rng)

            # Apply delta and check for out of bounds
            left_gripper_position = state[
                'left_gripper'] + left_gripper_delta_position
            right_gripper_position = state[
                'right_gripper'] + right_gripper_delta_position

            action = {
                'left_gripper_position': left_gripper_position,
                'right_gripper_position': right_gripper_position,
                'left_gripper_delta_position': left_gripper_delta_position,
                'right_gripper_delta_position': right_gripper_delta_position,
            }

            if not validate or self.is_action_valid(action, action_params):
                self.last_action = action
                return action

        rospy.logwarn(
            "Could not find a valid action, executing an invalid one")
        return action

    def is_action_valid(self, action: Dict, action_params: Dict):
        out_of_bounds = FloatingRopeScenario.grippers_out_of_bounds(
            action['left_gripper_position'], action['right_gripper_position'],
            action_params)

        max_gripper_d = default_if_none(
            action_params['max_distance_between_grippers'], 1000)
        gripper_d = np.linalg.norm(action['left_gripper_position'] -
                                   action['right_gripper_position'])
        too_far = gripper_d > max_gripper_d

        return not out_of_bounds and not too_far

    def get_action_sample_extent(self, action_params: Dict, prefix: str):
        k = prefix + 'gripper_action_sample_extent'
        if k in action_params:
            gripper_extent = np.array(action_params[k]).reshape([3, 2])
        else:
            gripper_extent = np.array(action_params['extent']).reshape([3, 2])
        return gripper_extent

    def viz_action_sample_bbox(self, gripper_bbox_pub: rospy.Publisher,
                               gripper_extent):
        gripper_bbox_msg = extent_array_to_bbox(gripper_extent)
        gripper_bbox_msg.header.frame_id = 'world'
        gripper_bbox_pub.publish(gripper_bbox_msg)

    def sample_delta_position(self, action_params, action_rng):
        pitch = action_rng.uniform(-np.pi, np.pi)
        yaw = action_rng.uniform(-np.pi, np.pi)
        displacement = action_rng.uniform(
            0, action_params['max_distance_gripper_can_move'])
        rotation_matrix = transformations.euler_matrix(0, pitch, yaw)
        gripper_delta_position_homo = rotation_matrix @ np.array(
            [1, 0, 0, 1]) * displacement
        gripper_delta_position = gripper_delta_position_homo[:3]
        return gripper_delta_position

    @staticmethod
    def grippers_out_of_bounds(left_gripper, right_gripper,
                               action_params: Dict):
        left_gripper_extent = action_params[
            'left_gripper_action_sample_extent']
        right_gripper_extent = action_params[
            'right_gripper_action_sample_extent']
        return FloatingRopeScenario.is_out_of_bounds(left_gripper, left_gripper_extent) \
               or FloatingRopeScenario.is_out_of_bounds(right_gripper, right_gripper_extent)

    @staticmethod
    def is_out_of_bounds(p, extent):
        x, y, z = p
        x_min, x_max, y_min, y_max, z_min, z_max = extent
        return x < x_min or x > x_max \
               or y < y_min or y > y_max \
               or z < z_min or z > z_max

    @staticmethod
    def interpolate(start_state, end_state, step_size=0.05):
        left_gripper_start = np.array(start_state['left_gripper'])
        left_gripper_end = np.array(end_state['left_gripper'])

        right_gripper_start = np.array(start_state['right_gripper'])
        right_gripper_end = np.array(end_state['right_gripper'])

        left_gripper_delta = left_gripper_end - left_gripper_start
        right_gripper_delta = right_gripper_end - right_gripper_start

        left_gripper_steps = np.round(
            np.linalg.norm(left_gripper_delta) / step_size).astype(np.int64)
        right_gripper_steps = np.round(
            np.linalg.norm(right_gripper_delta) / step_size).astype(np.int64)
        steps = max(left_gripper_steps, right_gripper_steps)

        interpolated_actions = []
        for t in np.linspace(step_size, 1, steps):
            left_gripper_i = left_gripper_start + left_gripper_delta * t
            right_gripper_i = right_gripper_start + right_gripper_delta * t
            action = {
                'left_gripper_position': left_gripper_i,
                'right_gripper_position': right_gripper_i,
            }
            interpolated_actions.append(action)

        return interpolated_actions

    @staticmethod
    def robot_name():
        return "rope_3d"

    def randomize_environment(self, env_rng, params: Dict):
        pass

    @staticmethod
    def put_state_robot_frame(state: Dict):
        rope = state[rope_key_name]
        rope_points_shape = rope.shape[:-1].as_list() + [-1, 3]
        rope_points = tf.reshape(rope, rope_points_shape)

        # This assumes robot is at 0 0 0
        robot_position = tf.constant([[0, 0, 0]], tf.float32)
        left_gripper_robot = state['left_gripper']
        right_gripper_robot = state['right_gripper']

        rope_points_robot = rope_points - tf.expand_dims(robot_position,
                                                         axis=-2)
        rope_robot = tf.reshape(rope_points_robot, rope.shape)

        return {
            'left_gripper': left_gripper_robot,
            'right_gripper': right_gripper_robot,
            rope_key_name: rope_robot,
        }

    @staticmethod
    def put_state_local_frame(state: Dict):
        rope = state[rope_key_name]
        rope_points_shape = rope.shape[:-1].as_list() + [-1, 3]
        rope_points = tf.reshape(rope, rope_points_shape)

        center = tf.reduce_mean(rope_points, axis=-2)

        left_gripper_local = state['left_gripper'] - center
        right_gripper_local = state['right_gripper'] - center

        rope_points_local = rope_points - tf.expand_dims(center, axis=-2)
        rope_local = tf.reshape(rope_points_local, rope.shape)

        return {
            'left_gripper': left_gripper_local,
            'right_gripper': right_gripper_local,
            rope_key_name: rope_local,
        }

    @staticmethod
    def local_environment_center_differentiable(state):
        rope_vector = state[rope_key_name]
        rope_points = tf.reshape(rope_vector, [rope_vector.shape[0], -1, 3])
        center = tf.reduce_mean(rope_points, axis=1)
        return center

    @staticmethod
    def apply_local_action_at_state(state, local_action):
        return {
            'left_gripper_position':
            state['left_gripper'] + local_action['left_gripper_delta'],
            'right_gripper_position':
            state['right_gripper'] + local_action['right_gripper_delta']
        }

    @staticmethod
    def add_noise(action: Dict, noise_rng: np.random.RandomState):
        left_gripper_noise = noise_rng.normal(scale=0.01, size=[3])
        right_gripper_noise = noise_rng.normal(scale=0.01, size=[3])
        return {
            'left_gripper_position':
            action['left_gripper_position'] + left_gripper_noise,
            'right_gripper_position':
            action['right_gripper_position'] + right_gripper_noise
        }

    @staticmethod
    def integrate_dynamics(s_t: Dict, delta_s_t: Dict):
        return {k: s_t[k] + delta_s_t[k] for k in s_t.keys()}

    @staticmethod
    def put_action_local_frame(state: Dict, action: Dict):
        target_left_gripper_position = action['left_gripper_position']
        target_right_gripper_position = action['right_gripper_position']
        n_action = target_left_gripper_position.shape[1]

        current_left_gripper_point = state['left_gripper']
        current_right_gripper_point = state['right_gripper']

        left_gripper_delta = target_left_gripper_position - current_left_gripper_point[:, :
                                                                                       n_action]
        right_gripper_delta = target_right_gripper_position - current_right_gripper_point[:, :
                                                                                          n_action]

        return {
            'left_gripper_delta': left_gripper_delta,
            'right_gripper_delta': right_gripper_delta,
        }

    @staticmethod
    def state_to_gripper_position(state: Dict):
        gripper_position1 = np.reshape(state['left_gripper'], [3])
        gripper_position2 = np.reshape(state['right_gripper'], [3])
        return gripper_position1, gripper_position2

    def get_cdcpd_state(self):
        cdcpd_msg: PointCloud2 = self.cdcpd_listener.get()

        # transform into robot-frame
        transform = self.tf.get_transform_msg("robot_root",
                                              "kinect2_rgb_optical_frame")
        cdcpd_points_robot_frame = tf2_sensor_msgs.do_transform_cloud(
            cdcpd_msg, transform)

        cdcpd_points_array = ros_numpy.numpify(cdcpd_points_robot_frame)
        x = cdcpd_points_array['x']
        y = cdcpd_points_array['y']
        z = cdcpd_points_array['z']
        points = np.stack([x, y, z], axis=-1)

        cdcpd_vector = points.flatten()
        return cdcpd_vector

    def get_rope_state(self):
        rope_res = self.get_rope_srv(GetRopeStateRequest())
        rope_state_vector = []
        for p in rope_res.positions:
            rope_state_vector.append(p.x)
            rope_state_vector.append(p.y)
            rope_state_vector.append(p.z)
        rope_velocity_vector = []
        for v in rope_res.velocities:
            rope_velocity_vector.append(v.x)
            rope_velocity_vector.append(v.y)
            rope_velocity_vector.append(v.z)
        return rope_state_vector

    def get_rope_point_positions(self):
        # NOTE: consider getting rid of this message type/service just use rope state [0] and rope state [-1]
        #  although that looses semantic meaning and means hard-coding indices a lot...
        left_res: GetPosition3DResponse = self.pos3d.get(
            scoped_link_name=gz_scope(self.ROPE_NAMESPACE, 'left_gripper'))
        left_rope_point_position = ros_numpy.numpify(left_res.pos)
        right_res: GetPosition3DResponse = self.pos3d.get(
            scoped_link_name=gz_scope(self.ROPE_NAMESPACE, 'right_gripper'))
        right_rope_point_position = ros_numpy.numpify(right_res.pos)
        return left_rope_point_position, right_rope_point_position

    def get_state(self):
        color_depth_cropped = self.get_rgbd()

        rope_state_vector = self.get_rope_state()
        cdcpd_vector = self.get_cdcpd_state()
        left_rope_point_position, right_rope_point_position = self.get_rope_point_positions(
        )

        return {
            'left_gripper': left_rope_point_position,
            'right_gripper': right_rope_point_position,
            'gt_rope': np.array(rope_state_vector, np.float32),
            rope_key_name: np.array(cdcpd_vector, np.float32),
            'rgbd': color_depth_cropped,
        }

    def get_rgbd(self):
        color_msg: Image = self.color_image_listener.get()
        depth_msg = self.depth_image_listener.get()

        depth = np.expand_dims(ros_numpy.numpify(depth_msg), axis=-1)
        bgr = ros_numpy.numpify(color_msg)
        rgb = np.flip(bgr, axis=2)

        # NaN Depths means out of range, so clip to the max range
        depth = np.clip(np.nan_to_num(depth, nan=KINECT_MAX_DEPTH), 0,
                        KINECT_MAX_DEPTH)
        rgbd = np.concatenate([rgb, depth], axis=2)
        box = tf.convert_to_tensor([
            self.crop_region['min_y'] / rgb.shape[0],
            self.crop_region['min_x'] / rgb.shape[1],
            self.crop_region['max_y'] / rgb.shape[0],
            self.crop_region['max_x'] / rgb.shape[1]
        ],
                                   dtype=tf.float32)
        # this operates on a batch
        rgbd_cropped = tf.image.crop_and_resize(
            image=tf.expand_dims(rgbd, axis=0),
            boxes=tf.expand_dims(box, axis=0),
            box_indices=[0],
            crop_size=[self.IMAGE_H, self.IMAGE_W])
        rgbd_cropped = remove_batch(rgbd_cropped)

        def _debug_show_image(_rgb_depth_cropped):
            import matplotlib.pyplot as plt
            plt.imshow(tf.cast(_rgb_depth_cropped[:, :, :3], tf.int32))
            plt.show()

        # BEGIN DEBUG
        # _debug_show_image(rgbd_cropped)
        # END DEBUG
        return rgbd_cropped.numpy()

    def observations_description(self) -> Dict:
        return {
            'left_gripper': 3,
            'right_gripper': 3,
            'rgbd': [self.IMAGE_H, self.IMAGE_W, 4],
        }

    @staticmethod
    def states_description() -> Dict:
        return {}

    @staticmethod
    def observation_features_description() -> Dict:
        return {
            rope_key_name: FloatingRopeScenario.n_links * 3,
            'cdcpd': FloatingRopeScenario.n_links * 3,
        }

    @staticmethod
    def actions_description() -> Dict:
        # should match the keys of the dict return from action_to_dataset_action
        return {
            'left_gripper_position': 3,
            'right_gripper_position': 3,
        }

    @staticmethod
    def state_to_points_for_cc(state: Dict):
        return state[rope_key_name].reshape(-1, 3)

    def __repr__(self):
        return "DualFloatingGripperRope"

    def simple_name(self):
        return "dual_floating"

    @staticmethod
    def sample_gripper_goal(environment: Dict, rng: np.random.RandomState,
                            planner_params: Dict):
        env_inflated = inflate_tf_3d(
            env=environment['env'],
            radius_m=planner_params['goal_params']['threshold'],
            res=environment['res'])
        goal_extent = planner_params['goal_params']['extent']

        while True:
            extent = np.array(goal_extent).reshape(3, 2)
            left_gripper = rng.uniform(extent[:, 0], extent[:, 1])
            right_gripper = rng.uniform(extent[:, 0], extent[:, 1])
            goal = {
                'left_gripper': left_gripper,
                'right_gripper': right_gripper,
            }
            row1, col1, channel1 = grid_utils.point_to_idx_3d_in_env(
                left_gripper[0], left_gripper[1], left_gripper[2], environment)
            row2, col2, channel2 = grid_utils.point_to_idx_3d_in_env(
                right_gripper[0], right_gripper[1], right_gripper[2],
                environment)
            collision1 = env_inflated[row1, col1, channel1] > 0.5
            collision2 = env_inflated[row2, col2, channel2] > 0.5
            if not collision1 and not collision2:
                return goal

    def sample_goal(self, environment: Dict, rng: np.random.RandomState,
                    planner_params: Dict):
        goal_type = planner_params['goal_params']['goal_type']
        if goal_type == 'midpoint':
            return self.sample_midpoint_goal(environment, rng, planner_params)
        else:
            raise NotImplementedError(
                planner_params['goal_params']['goal_type'])

    @staticmethod
    def distance_to_gripper_goal(state: Dict, goal: Dict):
        left_gripper = state['left_gripper']
        right_gripper = state['right_gripper']
        distance1 = np.linalg.norm(goal['left_gripper'] - left_gripper)
        distance2 = np.linalg.norm(goal['right_gripper'] - right_gripper)
        return max(distance1, distance2)

    def sample_midpoint_goal(self, environment: Dict,
                             rng: np.random.RandomState, planner_params: Dict):
        goal_extent = planner_params['goal_params']['extent']

        if environment == {}:
            rospy.loginfo("Assuming no obstacles in the environment")
            extent = np.array(goal_extent).reshape(3, 2)
            p = rng.uniform(extent[:, 0], extent[:, 1])
            goal = {'midpoint': p}
            return goal

        env_inflated = inflate_tf_3d(
            env=environment['env'],
            radius_m=planner_params['goal_params']['threshold'],
            res=environment['res'])
        # DEBUG visualize the inflated env
        # from copy import deepcopy
        # environment_ = deepcopy(environment)
        # environment_['env'] = env_inflated
        # self.plot_environment_rviz(environment_)
        # END DEBUG

        while True:
            extent = np.array(goal_extent).reshape(3, 2)
            p = rng.uniform(extent[:, 0], extent[:, 1])
            goal = {'midpoint': p}
            row, col, channel = grid_utils.point_to_idx_3d_in_env(
                p[0], p[1], p[2], environment)
            collision = env_inflated[row, col, channel] > 0.5
            if not collision:
                return goal

    @staticmethod
    def distance_grippers_and_any_point_goal(state: Dict, goal: Dict):
        rope_points = np.reshape(state[rope_key_name], [-1, 3])
        # well ok not _any_ node, but ones near the middle
        n_from_ends = 5
        distances = np.linalg.norm(np.expand_dims(goal['point'], axis=0) -
                                   rope_points,
                                   axis=1)[n_from_ends:-n_from_ends]
        rope_distance = np.min(distances)

        left_gripper = state['left_gripper']
        right_gripper = state['right_gripper']
        distance1 = np.linalg.norm(goal['left_gripper'] - left_gripper)
        distance2 = np.linalg.norm(goal['right_gripper'] - right_gripper)
        return max(max(distance1, distance2), rope_distance)

    @staticmethod
    def distance_to_any_point_goal(state: Dict, goal: Dict):
        rope_points = np.reshape(state[rope_key_name], [-1, 3])
        # well ok not _any_ node, but ones near the middle
        n_from_ends = 7
        distances = np.linalg.norm(np.expand_dims(goal['point'], axis=0) -
                                   rope_points,
                                   axis=1)[n_from_ends:-n_from_ends]
        min_distance = np.min(distances)
        return min_distance

    @staticmethod
    def distance_to_midpoint_goal(state: Dict, goal: Dict):
        rope_points = np.reshape(state[rope_key_name], [-1, 3])
        rope_midpoint = rope_points[int(FloatingRopeScenario.n_links / 2)]
        distance = np.linalg.norm(goal['midpoint'] - rope_midpoint)
        return distance

    def classifier_distance(self, s1: Dict, s2: Dict):
        model_error = np.linalg.norm(s1[rope_key_name] - s2[rope_key_name],
                                     axis=-1)
        # labeling_states = s1['rope']
        # labeling_predicted_states = s2['rope']
        # points_shape = labeling_states.shape.as_list()[:2] + [-1, 3]
        # labeling_points = tf.reshape(labeling_states, points_shape)
        # labeling_predicted_points = tf.reshape(labeling_predicted_states, points_shape)
        # model_error = tf.reduce_mean(tf.linalg.norm(labeling_points - labeling_predicted_points, axis=-1), axis=-1)
        return model_error

    def compute_label(self, actual: Dict, predicted: Dict,
                      labeling_params: Dict):
        # NOTE: this should be using the same distance metric as the planning, which should also be the same as the labeling
        # done when making the classifier dataset
        actual_rope = np.array(actual["rope"])
        predicted_rope = np.array(predicted["rope"])
        model_error = np.linalg.norm(actual_rope - predicted_rope)
        threshold = labeling_params['threshold']
        is_close = model_error < threshold
        return is_close

    def distance_to_goal(self, state, goal):
        if 'type' not in goal or goal['type'] == 'midpoint':
            return self.distance_to_midpoint_goal(state, goal)
        elif goal['type'] == 'any_point':
            return self.distance_to_any_point_goal(state, goal)
        elif goal['type'] == 'grippers':
            return self.distance_to_gripper_goal(state, goal)
        elif goal['type'] == 'grippers_and_point':
            return self.distance_grippers_and_any_point_goal(state, goal)
        else:
            raise NotImplementedError()

    def plot_goal_rviz(self,
                       goal: Dict,
                       goal_threshold: float,
                       actually_at_goal: Optional[bool] = None):
        if actually_at_goal:
            r = 0.4
            g = 0.8
            b = 0.4
            a = 0.6
        else:
            r = 0.5
            g = 0.3
            b = 0.8
            a = 0.6

        goal_marker_msg = MarkerArray()

        if 'midpoint' in goal:
            midpoint_marker = Marker()
            midpoint_marker.scale.x = goal_threshold * 2
            midpoint_marker.scale.y = goal_threshold * 2
            midpoint_marker.scale.z = goal_threshold * 2
            midpoint_marker.action = Marker.ADD
            midpoint_marker.type = Marker.SPHERE
            midpoint_marker.header.frame_id = "world"
            midpoint_marker.header.stamp = rospy.Time.now()
            midpoint_marker.ns = 'goal'
            midpoint_marker.id = 0
            midpoint_marker.color.r = r
            midpoint_marker.color.g = g
            midpoint_marker.color.b = b
            midpoint_marker.color.a = a
            midpoint_marker.pose.position.x = goal['midpoint'][0]
            midpoint_marker.pose.position.y = goal['midpoint'][1]
            midpoint_marker.pose.position.z = goal['midpoint'][2]
            midpoint_marker.pose.orientation.w = 1
            goal_marker_msg.markers.append(midpoint_marker)

        if 'point' in goal:
            point_marker = Marker()
            point_marker.scale.x = goal_threshold * 2
            point_marker.scale.y = goal_threshold * 2
            point_marker.scale.z = goal_threshold * 2
            point_marker.action = Marker.ADD
            point_marker.type = Marker.SPHERE
            point_marker.header.frame_id = "world"
            point_marker.header.stamp = rospy.Time.now()
            point_marker.ns = 'goal'
            point_marker.id = 0
            point_marker.color.r = r
            point_marker.color.g = g
            point_marker.color.b = b
            point_marker.color.a = a
            point_marker.pose.position.x = goal['point'][0]
            point_marker.pose.position.y = goal['point'][1]
            point_marker.pose.position.z = goal['point'][2]
            point_marker.pose.orientation.w = 1
            goal_marker_msg.markers.append(point_marker)

        if 'left_gripper' in goal:
            left_gripper_marker = Marker()
            left_gripper_marker.scale.x = goal_threshold * 2
            left_gripper_marker.scale.y = goal_threshold * 2
            left_gripper_marker.scale.z = goal_threshold * 2
            left_gripper_marker.action = Marker.ADD
            left_gripper_marker.type = Marker.SPHERE
            left_gripper_marker.header.frame_id = "world"
            left_gripper_marker.header.stamp = rospy.Time.now()
            left_gripper_marker.ns = 'goal'
            left_gripper_marker.id = 1
            left_gripper_marker.color.r = r
            left_gripper_marker.color.g = g
            left_gripper_marker.color.b = b
            left_gripper_marker.color.a = a
            left_gripper_marker.pose.position.x = goal['left_gripper'][0]
            left_gripper_marker.pose.position.y = goal['left_gripper'][1]
            left_gripper_marker.pose.position.z = goal['left_gripper'][2]
            left_gripper_marker.pose.orientation.w = 1
            goal_marker_msg.markers.append(left_gripper_marker)

        if 'right_gripper' in goal:
            right_gripper_marker = Marker()
            right_gripper_marker.scale.x = goal_threshold * 2
            right_gripper_marker.scale.y = goal_threshold * 2
            right_gripper_marker.scale.z = goal_threshold * 2
            right_gripper_marker.action = Marker.ADD
            right_gripper_marker.type = Marker.SPHERE
            right_gripper_marker.header.frame_id = "world"
            right_gripper_marker.header.stamp = rospy.Time.now()
            right_gripper_marker.ns = 'goal'
            right_gripper_marker.id = 2
            right_gripper_marker.color.r = r
            right_gripper_marker.color.g = g
            right_gripper_marker.color.b = b
            right_gripper_marker.color.a = a
            right_gripper_marker.pose.position.x = goal['right_gripper'][0]
            right_gripper_marker.pose.position.y = goal['right_gripper'][1]
            right_gripper_marker.pose.position.z = goal['right_gripper'][2]
            right_gripper_marker.pose.orientation.w = 1
            goal_marker_msg.markers.append(right_gripper_marker)

        self.state_viz_pub.publish(goal_marker_msg)

    def plot_goal_boxes(self,
                        goal: Dict,
                        goal_threshold: float,
                        actually_at_goal: Optional[bool] = None):
        if actually_at_goal:
            r = 0.4
            g = 0.8
            b = 0.4
            a = 0.6
        else:
            r = 0.5
            g = 0.3
            b = 0.8
            a = 0.6

        goal_marker_msg = MarkerArray()

        if 'point_box' in goal:
            point_marker = make_box_marker_from_extents(goal['point_box'])
            point_marker.header.frame_id = "world"
            point_marker.header.stamp = rospy.Time.now()
            point_marker.ns = 'goal'
            point_marker.id = 0
            point_marker.color.r = r
            point_marker.color.g = g
            point_marker.color.b = b
            point_marker.color.a = a
            goal_marker_msg.markers.append(point_marker)

        if 'left_gripper_box' in goal:
            left_gripper_marker = make_box_marker_from_extents(
                goal['left_gripper_box'])
            left_gripper_marker.header.frame_id = "world"
            left_gripper_marker.header.stamp = rospy.Time.now()
            left_gripper_marker.ns = 'goal'
            left_gripper_marker.id = 1
            left_gripper_marker.color.r = r
            left_gripper_marker.color.g = g
            left_gripper_marker.color.b = b
            left_gripper_marker.color.a = a
            goal_marker_msg.markers.append(left_gripper_marker)

        if 'right_gripper_box' in goal:
            right_gripper_marker = make_box_marker_from_extents(
                goal['right_gripper_box'])
            right_gripper_marker.header.frame_id = "world"
            right_gripper_marker.header.stamp = rospy.Time.now()
            right_gripper_marker.ns = 'goal'
            right_gripper_marker.id = 2
            right_gripper_marker.color.r = r
            right_gripper_marker.color.g = g
            right_gripper_marker.color.b = b
            right_gripper_marker.color.a = a
            goal_marker_msg.markers.append(right_gripper_marker)

        self.state_viz_pub.publish(goal_marker_msg)

    @staticmethod
    def dynamics_loss_function(dataset_element, predictions):
        return dynamics_loss_function(dataset_element, predictions)

    @staticmethod
    def dynamics_metrics_function(dataset_element, predictions):
        return dynamics_points_metrics_function(dataset_element, predictions)

    def plot_tree_action(self, state: Dict, action: Dict, **kwargs):
        r = kwargs.pop("r", 0.2)
        g = kwargs.pop("g", 0.2)
        b = kwargs.pop("b", 0.8)
        a = kwargs.pop("a", 1.0)
        ig = marker_index_generator(self.tree_action_idx)
        idx1 = next(ig)
        idx2 = next(ig)
        self.plot_action_rviz(state,
                              action,
                              label='tree',
                              color=[r, g, b, a],
                              idx1=idx1,
                              idx2=idx2,
                              **kwargs)
        self.tree_action_idx += 1

    def plot_state_rviz(self, state: Dict, label: str, **kwargs):
        r, g, b, a = colors.to_rgba(kwargs.get("color", "r"))
        idx = kwargs.get("idx", 0)

        msg = MarkerArray()

        ig = marker_index_generator(idx)

        if 'gt_rope' in state:
            rope_points = np.reshape(state['gt_rope'], [-1, 3])
            markers = make_rope_marker(rope_points, 'world',
                                       label + "_gt_rope", next(ig), r, g, b,
                                       a)
            msg.markers.extend(markers)

        if 'rope' in state:
            rope_points = np.reshape(state['rope'], [-1, 3])
            markers = make_rope_marker(rope_points, 'world', label + "_rope",
                                       next(ig), r, g, b, a)
            msg.markers.extend(markers)

        if add_predicted('rope') in state:
            rope_points = np.reshape(state[add_predicted('rope')], [-1, 3])
            markers = make_rope_marker(rope_points, 'world',
                                       label + "_pred_rope", next(ig), r, g, b,
                                       a, Marker.CUBE_LIST)
            msg.markers.extend(markers)

        if 'left_gripper' in state:
            r = 0.2
            g = 0.2
            b = 0.8
            left_gripper_sphere = make_gripper_marker(state['left_gripper'],
                                                      next(ig), r, g, b, a,
                                                      label + '_l',
                                                      Marker.SPHERE)
            msg.markers.append(left_gripper_sphere)

        if 'right_gripper' in state:
            r = 0.8
            g = 0.8
            b = 0.2
            right_gripper_sphere = make_gripper_marker(state['right_gripper'],
                                                       next(ig), r, g, b, a,
                                                       label + "_r",
                                                       Marker.SPHERE)
            msg.markers.append(right_gripper_sphere)

        if add_predicted('left_gripper') in state:
            r = 0.2
            g = 0.2
            b = 0.8
            lgpp = state[add_predicted('left_gripper')]
            left_gripper_sphere = make_gripper_marker(lgpp, next(ig), r, g, b,
                                                      a, label + "_lp",
                                                      Marker.CUBE)
            msg.markers.append(left_gripper_sphere)

        if add_predicted('right_gripper') in state:
            r = 0.8
            g = 0.8
            b = 0.2
            rgpp = state[add_predicted('right_gripper')]
            right_gripper_sphere = make_gripper_marker(rgpp, next(ig), r, g, b,
                                                       a, label + "_rp",
                                                       Marker.CUBE)
            msg.markers.append(right_gripper_sphere)

        s = kwargs.get("scale", 1.0)
        msg = scale_marker_array(msg, s)

        self.state_viz_pub.publish(msg)

        if in_maybe_predicted('rgbd', state):
            publish_color_image(self.state_color_viz_pub,
                                state['rgbd'][:, :, :3])
            publish_depth_image(self.state_depth_viz_pub, state['rgbd'][:, :,
                                                                        3])

        if add_predicted('stdev') in state:
            stdev_t = state[add_predicted('stdev')][0]
            self.plot_stdev(stdev_t)

        if 'error' in state:
            error_msg = Float32()
            error_t = state['error']
            error_msg.data = error_t
            self.error_pub.publish(error_msg)

    def plot_action_rviz(self,
                         state: Dict,
                         action: Dict,
                         label: str = 'action',
                         **kwargs):
        state_action = {}
        state_action.update(state)
        state_action.update(action)
        self.plot_action_rviz_internal(state_action, label=label, **kwargs)

    def plot_action_rviz_internal(self, data: Dict, label: str, **kwargs):
        r, g, b, a = colors.to_rgba(kwargs.get("color", "b"))
        s1 = np.reshape(get_maybe_predicted(data, 'left_gripper'), [3])
        s2 = np.reshape(get_maybe_predicted(data, 'right_gripper'), [3])
        a1 = np.reshape(get_maybe_predicted(data, 'left_gripper_position'),
                        [3])
        a2 = np.reshape(get_maybe_predicted(data, 'right_gripper_position'),
                        [3])

        idx = kwargs.pop("idx", None)
        ig = marker_index_generator(idx)
        if idx is not None:
            idx1 = next(ig)
            idx2 = next(ig)
        else:
            idx1 = kwargs.pop("idx1", 0)
            idx2 = kwargs.pop("idx2", 1)

        msg = MarkerArray()
        msg.markers.append(
            rviz_arrow(s1, a1, r, g, b, a, idx=idx1, label=label, **kwargs))
        msg.markers.append(
            rviz_arrow(s2, a2, r, g, b, a, idx=idx2, label=label, **kwargs))

        self.action_viz_pub.publish(msg)

    def register_fake_grasping(self):
        register_left_req = RegisterPosition3DControllerRequest()
        register_left_req.scoped_link_name = gz_scope(self.ROPE_NAMESPACE,
                                                      "left_gripper")
        register_left_req.controller_type = "kinematic"
        self.pos3d.register(register_left_req)
        register_right_req = RegisterPosition3DControllerRequest()
        register_right_req.scoped_link_name = gz_scope(self.ROPE_NAMESPACE,
                                                       "right_gripper")
        register_right_req.controller_type = "kinematic"
        self.pos3d.register(register_right_req)

    def make_rope_endpoints_follow_gripper(self):
        left_follow_req = Position3DFollowRequest()
        left_follow_req.scoped_link_name = gz_scope(self.ROPE_NAMESPACE,
                                                    "left_gripper")
        left_follow_req.frame_id = "left_tool"
        self.pos3d.follow(left_follow_req)

        right_follow_req = Position3DFollowRequest()
        right_follow_req.scoped_link_name = gz_scope(self.ROPE_NAMESPACE,
                                                     "right_gripper")
        right_follow_req.frame_id = "right_tool"
        self.pos3d.follow(right_follow_req)
예제 #42
0
    def load_rosparam(self,
                      context,
                      ros_config,
                      cmd,
                      param,
                      file_,
                      text,
                      verbose=True):
        """
        Load rosparam setting
        
        @param context: Loader context
        @type  context: L{LoaderContext}
        @param ros_config: launch configuration
        @type  ros_config: L{ROSLaunchConfig}
        @param cmd: 'load', 'dump', or 'delete'
        @type  cmd: str
        @param file_: filename for rosparam to use or None
        @type  file_: str
        @param text: text for rosparam to load. Ignored if file_ is set.
        @type  text: str
        @raise ValueError: if parameters cannot be processed into valid rosparam setting
        """
        if not cmd in ('load', 'dump', 'delete'):
            raise ValueError("command must be 'load', 'dump', or 'delete'")
        if file_ is not None:
            if cmd == 'load' and not os.path.isfile(file_):
                raise ValueError("file does not exist [%s]" % file_)
            if cmd == 'delete':
                raise ValueError(
                    "'file' attribute is invalid with 'delete' command.")

        full_param = ns_join(context.ns, param) if param else context.ns

        if cmd == 'dump':
            ros_config.add_executable(
                RosbinExecutable('rosparam', (cmd, file_, full_param),
                                 PHASE_SETUP))
        elif cmd == 'delete':
            ros_config.add_executable(
                RosbinExecutable('rosparam', (cmd, full_param), PHASE_SETUP))
        elif cmd == 'load':
            # load YAML text
            if file_:
                with open(file_, 'r') as f:
                    text = f.read()

            # parse YAML text
            # - lazy import
            global yaml
            if yaml is None:
                import yaml
            # - lazy import: we have to import rosparam in oder to to configure the YAML constructors
            global rosparam
            if rosparam is None:
                import rosparam
            try:
                data = yaml.load(text)
                # #3162: if there is no YAML, load() will return an
                # empty string.  We want an empty dictionary instead
                # for our representation of empty.
                if data is None:
                    data = {}
            except yaml.MarkedYAMLError as e:
                if not file_:
                    raise ValueError(
                        "Error within YAML block:\n\t%s\n\nYAML is:\n%s" %
                        (str(e), text))
                else:
                    raise ValueError("file %s contains invalid YAML:\n%s" %
                                     (file_, str(e)))
            except Exception as e:
                if not file_:
                    raise ValueError("invalid YAML: %s\n\nYAML is:\n%s" %
                                     (str(e), text))
                else:
                    raise ValueError("file %s contains invalid YAML:\n%s" %
                                     (file_, str(e)))

            # 'param' attribute is required for non-dictionary types
            if not param and type(data) != dict:
                raise ValueError(
                    "'param' attribute must be set for non-dictionary values")

            self.add_param(ros_config, full_param, data, verbose=verbose)

        else:
            raise ValueError("unknown command %s" % cmd)
예제 #43
0
파일: test_names.py 프로젝트: Aand1/ROSCH
def test_nsjoin():
    from rosgraph.names import ns_join

    # private and global names cannot be joined
    assert '~name' == ns_join('/foo', '~name')
    assert '/name' == ns_join('/foo', '/name')
    assert '~name' == ns_join('~', '~name')
    assert '/name' == ns_join('/', '/name')

    # ns can be '~' or '/'
    assert '~name' == ns_join('~', 'name')
    assert '/name' == ns_join('/', 'name')

    assert '/ns/name' == ns_join('/ns', 'name')
    assert '/ns/name' == ns_join('/ns/', 'name')
    assert '/ns/ns2/name' == ns_join('/ns', 'ns2/name')
    assert '/ns/ns2/name' == ns_join('/ns/', 'ns2/name')

    # allow ns to be empty
    assert 'name' == ns_join('', 'name')