예제 #1
0
def test_synthetic_phi(actual_map_name, template, robot_name, line_detector_name,
                   image_prep_name, lane_filter_name, d, phi, outd,
                   max_phi_err=max_phi_err,
                   max_d_err=max_d_err):

    # important to have deterministic results
    # The randomness is in the line extraction
    np.random.seed(42)
    location = np.zeros((), dtype=TemplateStraight.DATATYPE_COORDS)
    location['phi'] = phi
    location['d'] = d
    _res, stats = test_synthetic(actual_map_name, template, robot_name, line_detector_name,
                                image_prep_name, lane_filter_name, location, outd)
    error = stats['error']
    estimate = stats['estimate']
    fail = False
    msg = 'location: %s  estimate: %s error: %s ' % (location, estimate, error)
    dtu.logger.info(msg)

    if np.abs(error['phi']) > max_phi_err:
        msg += '\nError in phi too big (%s > %s) ' % (np.abs(error['phi']), max_phi_err)
        fail = True
    if np.abs(error['d']) > max_d_err:
        msg += '\nError in d too big (%s > %s)' % (np.abs(error['d']), max_d_err)
        fail = True
    if fail:
        dtu.logger.error(msg)

        if raise_if_error_too_large:
            if not dtu.on_duckiebot():
                raise Exception(msg)
    return not fail
예제 #2
0
def get_local_keys():
    username = getpass.getuser()
    hostname = socket.gethostname()
    d = {}

    if dtu.on_duckiebot():
        stype = 'duckiebot'
    elif dtu.on_laptop():
        stype = 'laptop'
    elif dtu.on_circle():
        stype = 'cloud'
    else:
        stype = 'unknown'
        
    d['type'] = stype
    d['what_the_duck_version'] = what_the_duck_version
    d['username'] = username
    d['hostname'] = hostname
    now = datetime.datetime.now()
    date_s = now.isoformat('_')
    upload_event_id = hostname + '-' + date_s 
    d['upload_event_id'] = upload_event_id
    d['upload_event_date'] = now
    location = get_geolocation_data()
    d.update(location)
    return d
예제 #3
0
    def go(self):
        vehicle_name = dtu.get_current_robot_name() if dtu.on_duckiebot(
        ) else "default"

        output = self.options.output
        if output is None:
            output = 'out-pipeline'  #  + dtu.get_md5(self.options.image)[:6]
            self.info('No --output given, using %s' % output)

        if self.options.image is not None:
            image_filename = self.options.image
            if image_filename.startswith('http'):
                image_filename = dtu.get_file_from_url(image_filename)

            bgr = dtu.bgr_from_jpg_fn(image_filename)
        else:
            print("Validating using the ROS image stream...")
            import rospy
            from sensor_msgs.msg import CompressedImage

            topic_name = os.path.join('/', vehicle_name,
                                      'camera_node/image/compressed')

            print('Let\'s wait for an image. Say cheese!')

            # Dummy to get ROS message
            rospy.init_node('single_image')
            img_msg = None
            try:
                img_msg = rospy.wait_for_message(topic_name,
                                                 CompressedImage,
                                                 timeout=10)
                print('Image captured!')
            except rospy.ROSException as e:
                print(
                    '\n\n\nDidn\'t get any message!: %s\n MAKE SURE YOU USE DT SHELL COMMANDS OF VERSION 4.1.9 OR HIGHER!\n\n\n'
                    % (e, ))

            bgr = dtu.bgr_from_rgb(dtu.rgb_from_ros(img_msg))
            self.info('Picture taken: %s ' % str(bgr.shape))

        gp = GroundProjection(vehicle_name)

        dtu.DuckietownConstants.show_timeit_benchmarks = True
        res, _stats = run_pipeline(
            bgr,
            gp,
            line_detector_name=self.options.line_detector,
            image_prep_name=self.options.image_prep,
            anti_instagram_name=self.options.anti_instagram,
            lane_filter_name=self.options.lane_filter)

        self.info('Resizing images..')
        res = dtu.resize_small_images(res)
        self.info('Writing images..')
        dtu.write_bgr_images_as_jpgs(res, output)
예제 #4
0
def good_ssh_configuration(manager):
    add = manager.add
    ssh_is_there = add(None,\
        "%s exists" % SSH_DIR,
        DirExists(SSH_DIR),
        Diagnosis("SSH config dir does not exist."))

    add(ssh_is_there, SSH_DIR + " permissions",
        CheckPermissions(SSH_DIR, '0700'),
        Diagnosis("SSH directory has wrong permissions."))

    ssh_config_exists = add(ssh_is_there, "%s exists" % SSH_CONFIG,
                            FileExists(SSH_CONFIG),
                            Diagnosis("SSH config does not exist."))

    add(
        ssh_config_exists, "SSH option HostKeyAlgorithms is set",
        FileContains(SSH_CONFIG, "HostKeyAlgorithms ssh-rsa"),
        Diagnosis("""
        You did not follow the SSH instructions.

        The option "HostKeyAlgorithms ssh-rsa" is necessary for remote
        roslaunch to work. Otherwise it fails because of a limitation
        of the Paramiko library.

        See the discussion here:

            https://answers.ros.org/question/41446/a-is-not-in-your-ssh-known_hosts-file/

        """),
        Suggestion("""
        You will need to add the option, and also remove the "~/.ssh/known_hosts" file.
        (See discussion above for the why.)

        """))

    identity_file = add(ssh_config_exists, "Configured at least one SSH key.",
                        FileContains(SSH_CONFIG, 'IdentityFile'),
                        Diagnosis('You have not enabled any SSH key.'))

    if dtu.on_duckiebot():
        add(ssh_is_there, "Existence of " + AUTHORIZED_KEYS,
            FileExists(AUTHORIZED_KEYS),
            Diagnosis("You did not setup the SSH authorized keys."))

    # check if we have internet access, and if so try github
    internet_access = add(identity_file, "Working internet connection",
                          InternetConnected(),
                          Diagnosis('You are not connected to internet.'))

    add(internet_access, "Github configured", GithubLogin(),
        Diagnosis('You have not successfully setup the Github access.'))
예제 #5
0
def get_checks():
    """ Returns a list of Entry """

    manager = Manager()
    add = manager.add

    
    JOY_DEVICE = '/dev/input/js0'

    this_is_a_duckiebot = dtu.on_duckiebot()
    this_is_a_laptop = dtu.on_laptop() 
    this_is_circle = dtu.on_circle()
    
    username = getpass.getuser()

    
    if this_is_a_duckiebot:
        add(None,
            "Camera is detected",
            CommandOutputContains('sudo vcgencmd get_camera', 'detected=1'),
            Diagnosis("The camera is not connected."))

    add(None,
        "Scipy is installed",
        CanImportPackages(['scipy', 'scipy.io']),
        Diagnosis("Scipy is not installed correctly."))

    add(None,
        "sklearn is installed",
        CanImportPackages(['sklearn']),
        Diagnosis("sklearn is not installed correctly."))
    
    python_packages = [
#         'ros_node_utils',
        'procgraph',
        'comptests',
        'compmake',
        'contracts',
    ]
    for p in python_packages:
        add(None,
        "%s is installed" % p,
        CanImportPackages([p]),
        Diagnosis("Dependency %r is not installed correctly." % p),
        Suggestion(" pip install --user %s" % p))

    add(None,
        "Date is set correctly",
        CheckDate(),
        Diagnosis("The date is not set correctly."))

    not_root=add(None,
        "Not running as root",
        YouAreNotUser('root'),
        Diagnosis("You should not run the code as root."))


    if this_is_a_duckiebot:
        not_ubuntu = add(not_root,
            "Not running as ubuntu",
            YouAreNotUser('ubuntu'),
            Diagnosis("You should not run the code as ubuntu."))

        add(not_ubuntu,
            "Member of group sudo",
            UserBelongsToGroup(username, "sudo"),
            Diagnosis("You are not authorized to run sudo."))

        add(not_ubuntu,
            "Member of group input",
            UserBelongsToGroup(username, "input"),
            Diagnosis("You are not authorized to use the joystick."))

        add(not_ubuntu,
            "Member of group video",
            UserBelongsToGroup(username, "video"),
            Diagnosis("You are not authorized to read from the camera device."))

        add(not_ubuntu,
            "Member of group i2c",
            UserBelongsToGroup(username, "input"),
            Diagnosis("You are not authorized to use the motor shield."))

        for g in ['sudo','input','video','i2c']:
            add(None,
                "User ubuntu member of group `%s`" % g,
                UserBelongsToGroup("ubuntu", g),
                Diagnosis("Image not created properly."))

    if this_is_a_laptop or this_is_a_duckiebot:
        good_ssh_configuration(manager)
        
    required_packages = set()

    if this_is_a_duckiebot or this_is_a_laptop or this_is_circle:
        required_packages.update(make_list("""
            vim byobu
            git git-extras
            htop atop iftop
            aptitude apt-file
            build-essential libblas-dev liblapack-dev libatlas-base-dev gfortran libyaml-cpp-dev
            python-dev ipython python-sklearn
            python-termcolor
            ros-kinetic-desktop-full
            ntpdate

            python-pip
            ipython
            
            virtualenv
            libxml2-dev
            libxslt1-dev
            
            python-frozendict
             python-tables
            
        """))

    if this_is_a_duckiebot:
        required_packages.update(make_list("""
            i2c-tools
            python-smbus
            libffi-dev
            
            
             mplayer
             mencoder

            """))

    if this_is_a_laptop or this_is_circle:
        required_packages.update(make_list("""
            git-lfs
            pdftk
            bibtex2html
        """))

    # TODO
#     suggested = ['emacs', 'zsh', 'nethogs']

    for p in required_packages:
        add(None, "Installed APT package " + p, CheckPackageInstalled(p), Diagnosis('Package %r not installed.' % p))

    forbidden_packages = [
        "python-roslaunch", 
        "rosbash",
        'python-ruamel.yaml',
        'python-ruamel.ordereddict',
    ]

    for p in forbidden_packages:
        add(None, "You should not have installed APT package " + p, 
            CheckPackageNotInstalled(p), Diagnosis('Forbidden package %r is installed.' % p))
        
    if not this_is_circle:
        add_suite_git(manager)

    if this_is_a_duckiebot:
        add(None,
            "Edimax detected",
            CommandOutputContains('iwconfig', 'rtl8822bu'),
            Diagnosis("It seems that the Edimax is not detected."))

    add(None,
        'The hostname is configured',
        CheckHostnameConfigured(),
        Diagnosis('You have not completed a proper setup.'))

    add(None,
        '/etc/hosts is sane',
        CheckGoodHostsFile(),
        Diagnosis('The contents of /etc/hosts will cause problems later on.'))

    if this_is_a_duckiebot:
        add(None,
            'Correct kernel version',
            GoodKernel(),
            Diagnosis('You have been messing with the kernel.'),
        Suggestion('You probably need to start with a pristine SD card.'))

        add(None,
            'Wifi name configured',
            WifiNameConfigured(),
            Diagnosis('You have not completed the Wifi configuration.'))

    add(None,
        "Messages are compiled",
        CheckImportMessages(),
        Diagnosis("The messages are not compiling correctly."))

#     if not this_is_circle:
#         add(None,
#             'Shell is bash',
#             EnvironmentVariableIsEqualTo('SHELL', '/bin/bash'),
#             Diagnosis('You have not set the shell to /bin/bash'),
#             Suggestion('You can change the shell using `chsh`.'))


    if this_is_a_duckiebot:
        add(None,
            "Joystick detected",
            DeviceExists(JOY_DEVICE),
            Diagnosis("The joystick is not found at %s" % JOY_DEVICE))

    DUCKIETOWN_ROOT = dtu.DuckietownConstants.DUCKIETOWN_ROOT_variable
    DUCKIEFLEET_ROOT = dtu.DuckietownConstants.DUCKIEFLEET_ROOT_variable
    DUCKIETOWN_CONFIG_SEQUENCE = dtu.DuckietownConstants.DUCKIETOWN_CONFIG_SEQUENCE_variable


    if False:
        v = DUCKIETOWN_CONFIG_SEQUENCE
        add(None,
            'Provided environment variable %s.' % v,
            EnvironmentVariableExists(v),
            Diagnosis("%s is not set." % v),
            Suggestion('You have to set %r in your environment (e.g. .bashrc)' % v))


    variables_to_check = [DUCKIETOWN_ROOT, DUCKIEFLEET_ROOT, #DUCKIETOWN_CONFIG_SEQUENCE
                          ]

    existence = {}

    for v in variables_to_check:

        var_exists = add(None,
            'Provided environment variable %s.' % v,
            EnvironmentVariableExists(v),
            Diagnosis("%s is not set." % v),
            Suggestion('You have to set %r in your environment (e.g. .bashrc)' % v))

        existence[v] = add(var_exists,
            'Existence of path ${%s}' % v,
            DirExists('${%s}' % v),
            Diagnosis("%s is set but it points to a non-existing directory." % v)
            )


    add(existence[DUCKIETOWN_ROOT],
        'Software repo downloaded with SSH scheme.',
        GitCorrectRemote('${%s}' % DUCKIETOWN_ROOT),
        Diagnosis("You downloaded the repo using https."),
        SeeDocs('clone-software-repo')
        )
 
    # recent update
    add(existence[DUCKIETOWN_ROOT],
        'You pulled the Software repo in the last 24 hours',
        RecentlyPulled('${%s}' % DUCKIETOWN_ROOT, 24),
        Diagnosis("You did not recently pull the Software repository."),
        )

    add(existence[DUCKIEFLEET_ROOT],
        'You pulled the Duckiefleet root in the last 24 hours',
        RecentlyPulled('${%s}' % DUCKIEFLEET_ROOT, 24),
        Diagnosis("You did not recently pull the Duckiefleet repository."),
        )
 

    if not this_is_a_duckiebot:
        _git_lfs_installed = add(None,  # @UnusedVariable
                            'Git LFS installed',
                            GitLFSInstalled(),
                            Diagnosis('You have not installed Git LFS'),
                            SeeDocs('git-lfs'))

    if this_is_a_duckiebot:
        add(None,
            'This robot is mentioned in scuderia.',
            ThisRobotInScuderiaFile(),
            Diagnosis('You have not added the robot to the scuderia.'),
            SeeDocs('scuderia'))

    progs = ['roslaunch', 'rosrun']
    for prog in progs:
        add(None,
            'Good path for "%s"' % prog,
            CommandOutputContains('which %s' % prog, '/opt/ros/kinetic'),
            Diagnosis('The program `%s` is not resolved to the one in /opt/ros' % prog))

    add(None,
        'Good path for python',
        CommandOutputContains('which python', '/usr/bin/python'),
        Diagnosis('The program `python` is not resolved to the one in /usr/bin. '))
    
 

    machines_exists = add(None,
        'Existence of machines file',
        MachinesExists(),
        Diagnosis('You have an invalid or missing machines file.'),
        SeeDocs('machines'),
        )

    if this_is_a_duckiebot:
        add(machines_exists,
            'Machines file contains this robot',
            MachinesValid(),
            Diagnosis('You have an invalid  machines file.'),
            )

    found_duckiefleet = add(None, 
                            'Possible to get duckiefleet in some way',
                            FindingDuckiefleet(),
                            Diagnosis('Cannot find duckiefleet root'),
        )
    
    add(found_duckiefleet, 
        'The duckiefleet repo is up to date',
        UptodateDuckiefleet(), 
        Diagnosis('The duckiefleet repo is not up to date') )
 

    if False: # TODO

        if this_is_a_laptop:

            existence = add(None,
                'Environment variable DUCKIETOWN_DATA',
                EnvironmentVariableExists('DUCKIETOWN_DATA'),
                Diagnosis("DUCKIETOWN_DATA is not set."
    """
    The environment variable DUCKIETOWN_DATA must either:
    1) be set to "n/a"
    2) point to an existing path corresponding to Dropbox/duckietown-data.
       (containing a subdirectory 'logs')
    """
                      ))

            logs = [
                "${DUCKIETOWN_DATA}/logs/20160400-phase3-logs/dp45/20160406/20160406-226-All_red_lights_followTheLeader1-2cv.bag",
            ]
            for l in logs:
                add(existence,
                    'Log %r exists in DUCKIETOWN_DATA' % os.path.basename(l),
                    FileExists(l),
                    Diagnosis("The DUCKIETOWN_DATA folder does not contain the logs it should.")
                    )

    if False:
        # TODO: not sure if this is needed
        if this_is_a_duckiebot:
            add(None,
                'Environment variable VEHICLE_NAME',
                EnvironmentVariableExists('VEHICLE_NAME'),
                Diagnosis("""
    The environment variable VEHICLE_NAME must be the name of your robot
    (if you are on the robot)."""),
                Suggestion("""
    Add this line to ~/.bashrc:

        export VEHICLE_NAME= (your vehicle name)
    """))

    try:
        packagename2dir = dtu.get_list_of_packages_in_catkin_ws()
    except dtu.DTConfigException:
        pass
    else:
        for package_name, dirname in packagename2dir.items():
            add_python_package_checks(add, package_name, dirname)

    # TODO: DISPLAY is not set
    # files in src/ or scripts/ are executable
    # There is no file "util.py" copied from pkg_name

#     add(None,
#         'Passwordless sudo',
#         FileContains('/etc/'))

    # TODO: date
    return manager.entries
예제 #6
0
    def go(self):
        robot_name = dtu.get_current_robot_name() if dtu.on_duckiebot(
        ) else "default"
        try:
            output = self.options.output
            if output is None:
                output = 'out-calibrate-extrinsics'  #  + dtu.get_md5(self.options.image)[:6]
                self.info('No --output given, using %s' % output)

            if self.options.input is None:

                print("{}\nCalibrating using the ROS image stream...\n".format(
                    "*" * 20))
                import rospy
                from sensor_msgs.msg import CompressedImage

                topic_name = os.path.join('/', robot_name,
                                          'camera_node/image/compressed')
                print('Topic to listen to is: %s' % topic_name)

                print('Let\'s wait for an image. Say cheese!')

                # Dummy for getting a ROS message
                rospy.init_node('calibrate_extrinsics')
                img_msg = None
                try:
                    img_msg = rospy.wait_for_message(topic_name,
                                                     CompressedImage,
                                                     timeout=10)
                    print('Image captured!')
                except rospy.ROSException as e:
                    print(
                        '\n\n\nDidn\'t get any message!: %s\n MAKE SURE YOU USE DT SHELL COMMANDS OF VERSION 4.1.9 OR HIGHER!\n\n\n'
                        % (e, ))

                bgr = dtu.bgr_from_rgb(dtu.rgb_from_ros(img_msg))
                self.info('Picture taken: %s ' % str(bgr.shape))

            else:
                self.info('Loading input image %s' % self.options.input)
                bgr = dtu.bgr_from_jpg_fn(self.options.input)

            if bgr.shape[1] != 640:
                interpolation = cv2.INTER_CUBIC
                bgr = dtu.d8_image_resize_fit(bgr, 640, interpolation)
                self.info('Resized to: %s ' % str(bgr.shape))

            # Disable the old calibration file
            disable_old_homography(robot_name)

            camera_info = get_camera_info_for_robot(robot_name)
            homography_dummy = get_homography_default()
            gpg = GroundProjectionGeometry(camera_info, homography_dummy)

            res = OrderedDict()
            try:
                bgr_rectified = gpg.rectify(bgr, interpolation=cv2.INTER_CUBIC)
                cv2.imwrite("img.jpg", bgr_rectified)
                res['bgr'] = bgr
                res['bgr_rectified'] = bgr_rectified

                _new_matrix, res[
                    'rectified_full_ratio_auto'] = gpg.rectify_full(bgr,
                                                                    ratio=1.65)
                result = estimate_homography(bgr_rectified)
                dtu.check_isinstance(result, HomographyEstimationResult)

                if result.bgr_detected_refined is not None:
                    res['bgr_detected_refined'] = result.bgr_detected_refined

                if not result.success:
                    raise Exception(result.error)

                print "H:", result.H.tolist()
                save_homography(result.H, robot_name)

                msg = '''

    To check that this worked well, place the robot on the road, and run:

        rosrun complete_image_pipeline single_image

    Look at the produced jpgs.

    '''
                self.info(msg)
            except:
                print(traceback.format_exc())
            finally:
                dtu.write_bgr_images_as_jpgs(res, output)
        except:
            print(traceback.format_exc())