示例#1
0
    def __init__(self, robot, obs_nuisance=[], cmd_nuisance=[]):
        self.inner_robot_name = robot 

        boot_config = get_boot_config()
        id_robot, self.robot = boot_config.robots.instance_smarter(robot)

        if not isinstance(self.robot, RobotInterface):
            msg = 'Expected RobotInterface, got %s' % describe_type(self.robot)
            raise ValueError(msg)
        
        warnings.warn('handle the case better')
        self.desc = ('EquivRobot(%s,obs:%s,cmd:%s)'
                    % (id_robot, obs_nuisance, cmd_nuisance))

        # convert to (possibly empty) list of strings
        if isinstance(obs_nuisance, str):
            obs_nuisance = [obs_nuisance]
        if isinstance(cmd_nuisance, str):
            cmd_nuisance = [cmd_nuisance]

        instance = lambda y: boot_config.nuisances.instance_smarter(y)[1]
        
        self.obs_nuisances = [instance(x) for x in obs_nuisance]
        self.cmd_nuisances = [instance(x) for x in cmd_nuisance]
        # No - we should not call inverse() before transform_spec()

        obs_spec = self.robot.get_spec().get_observations()
        for n in self.obs_nuisances:
            obs_spec = n.transform_spec(obs_spec)

        cmd_spec = self.robot.get_spec().get_commands()
        for n in self.cmd_nuisances:
            cmd_spec = n.transform_spec(cmd_spec)

        # We don't really need to compute this...
        try:
            self.cmd_nuisances_inv = [x.inverse() for x in self.cmd_nuisances]
    
            # now initialize in reverse
            cmd_spec_i = cmd_spec
            for n in reversed(self.cmd_nuisances_inv):
                cmd_spec_i = n.transform_spec(cmd_spec_i)
    
            StreamSpec.check_same_spec(cmd_spec_i,
                                   self.robot.get_spec().get_commands())
            # TODO: why do we do this for commands, not for osbservations?
        except Exception as e:
            logger.warning('It seems that this chain of nuisances is not '
                           'exact, but it could be OK to continue. '
                           ' The chain is %s; the error is:\n%s' % 
                           (cmd_nuisance, indent(str(e).strip(), '> ')))

        self.spec = BootSpec(obs_spec=obs_spec, cmd_spec=cmd_spec)
        self.obs_nuisances_id = obs_nuisance
        self.cmd_nuisances_id = cmd_nuisance
def check_conversions(stream_spec1, nuisance):
    # print('Checking %s / %s ' % (stream_spec1, nuisance))
    nuisance_inv = None
    try:
        try:
            stream_spec2 = nuisance.transform_spec(stream_spec1)
        except UnsupportedSpec as e:
            logger.info('Skipping %s/%s because incompatible: %s' % 
                        (stream_spec1, nuisance, e))
            return

        value1 = stream_spec1.get_random_value()
        stream_spec1.check_valid_value(value1)


        value2 = nuisance.transform_value(value1)
        stream_spec2.check_valid_value(value2)

        try:
            nuisance_inv = nuisance.inverse()
        except NuisanceNotInvertible as e:
            logger.info('Skipping some tests %s/%s because not invertible:'
                        ' %s' % (stream_spec1, nuisance, e))
            return

        try:
            stream_spec1b = nuisance_inv.transform_spec(stream_spec2)
        except UnsupportedSpec as e:
            msg = ('The inverse of the nuisance does not seem to be able '
                   'to handle the result:\n%s\n\n'
                   '  stream_spec1: %s\n'
                   '      nuisance: %s\n'
                   '  stream_spec2: %s\n'
                   '  nuisance_inv: %s\n' % 
                   (indent(str(e), '>'),
                    stream_spec1.to_yaml(), nuisance,
                    stream_spec2.to_yaml(), nuisance_inv))
            raise ValueError(msg)

        try:
            StreamSpec.check_same_spec(stream_spec1, stream_spec1b)
        except Exception as e:
            msg = ('The inverse of the nuisance does not recreate the '
                   'initial spec:\n%s\n\n'
                   '  stream_spec1: %s\n'
                   '      nuisance: %s\n'
                   '  stream_spec2: %s\n'
                   '  nuisance_inv: %s\n'
                   ' stream_spec1b: %s\n' % 
                   (indent(str(e), '>'),
                    stream_spec1.to_yaml(), nuisance,
                    stream_spec2.to_yaml(), nuisance_inv,
                    stream_spec1b.to_yaml()))
            raise ValueError(msg)

        value1b = nuisance_inv.transform_value(value2)
        stream_spec1.check_valid_value(value1b)

        # TODO: if exact
        assert_allclose(value1, value1b, rtol=1e-5)

    except:
        logger.error('Error while testing:')
        logger.error(' stream_spec:  %s ' % stream_spec1.to_yaml())
        logger.error(' nuisance:     %s' % nuisance)
        logger.error(' nuisance_inv: %s' % nuisance_inv)
        raise