Beispiel #1
0
def run_gui_controller(hostname, image):
    client = check_docker_environment()
    container_name = "joystick_gui_%s" % hostname
    remove_if_running(client, container_name)
    duckiebot_ip = get_duckiebot_ip(hostname)
    env = {
        'HOSTNAME': hostname,
        'ROS_MASTER': hostname,
        'DUCKIEBOT_NAME': hostname,
        'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip
    }

    env['QT_X11_NO_MITSHM'] = 1

    volumes = {}

    subprocess.call(["xhost", "+"])

    p = platform.system().lower()
    if 'darwin' in p:
        dtslogger.warn(
            "We can try but running the joystick gui on MacOSx is not expected to work..."
        )
        env['DISPLAY'] = 'host.docker.internal:0'
        volumes = {'/tmp/.X11-unix': {'bind': '/tmp/.X11-unix', 'mode': 'rw'}}
    else:
        env['DISPLAY'] = os.environ['DISPLAY']

    dtslogger.info("Running %s on localhost with environment vars: %s" %
                   (container_name, env))

    if 'master19' in image:
        image = "duckietown/rpi-duckiebot-base:master19-no-arm"
        cmd = "python misc/virtualJoy/virtualJoy.py %s" % hostname
    elif 'daffy' in image:
        image = "duckietown/dt-core:daffy-amd64"
        cmd = "roslaunch virtual_joystick virtual_joystick_gui.launch veh:=%s" % hostname

    params = {
        'image': image,
        'name': container_name,
        'network_mode': 'host',
        'environment': env,
        'privileged': True,
        'stdin_open': True,
        'tty': True,
        'command': cmd,
        'detach': True,
        'volumes': volumes
    }

    container = client.containers.run(**params)
    cmd = 'docker attach %s' % container_name
    start_command_in_subprocess(cmd)
def run_cli_controller(hostname, image, duckiebot_ip, network_mode, sim):
    if sim:
        duckiebot_client = check_docker_environment()
    else:
        duckiebot_client = docker.DockerClient('tcp://' + duckiebot_ip +
                                               ':2375')
    container_name = "joystick_cli_%s" % hostname
    remove_if_running(duckiebot_client, container_name)
    env = {
        'HOSTNAME': hostname,
        'ROS_MASTER': hostname,
        'VEHICLE_NAME': hostname,
        'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip
    }

    dtslogger.info("Running %s on localhost with environment vars: %s" %
                   (container_name, env))

    if 'master19' in image:
        image = "duckietown/rpi-duckiebot-base:master19"  # run on robot
        cmd = "python misc/virtualJoy/joy_cli.py %s" % hostname
    elif 'daffy' in image:
        if sim:
            image = "duckietown/dt-core:daffy-amd64"
        else:
            image = "duckietown/dt-core:daffy"
        cmd = "roslaunch virtual_joystick virtual_joystick_cli.launch veh:=%s" % hostname

    params = {
        'image': image,
        'name': container_name,
        'network_mode': network_mode,
        'environment': env,
        'privileged': True,
        'stdin_open': True,
        'tty': True,
        'command': cmd,
        'detach': True
    }

    container = duckiebot_client.containers.run(**params)

    if sim:
        cmd = 'docker attach %s' % container_name
    else:
        cmd = 'docker -H %s.local attach %s' % (hostname, container_name)
    start_command_in_subprocess(cmd)
Beispiel #3
0
    def command(shell, args):

        prog = 'dts duckiebot calibrate_extrinsics DUCKIEBOT_NAME'
        usage = """
Calibrate: 

    %(prog)s
"""

        parser = argparse.ArgumentParser(prog=prog, usage=usage)
        parser.add_argument('hostname',
                            default=None,
                            help='Name of the Duckiebot to calibrate')
        parser.add_argument('--base_image',
                            dest='image',
                            default="duckietown/rpi-duckiebot-base:master19")
        parser.add_argument(
            '--no_verification',
            action='store_true',
            default=False,
            help="If you don't have a lane you can skip the verificaiton step")

        parsed_args = parser.parse_args(args)
        hostname = parsed_args.hostname
        duckiebot_ip = get_duckiebot_ip(hostname)
        duckiebot_client = get_remote_client(duckiebot_ip)

        calibration_container_name = "extrinsic_calibration"
        validation_container_name = "extrinsic_calibration_validation"
        remove_if_running(duckiebot_client, calibration_container_name)
        remove_if_running(duckiebot_client, validation_container_name)

        # need to temporarily pause the image streaming from the robot
        try:
            duckiebot_containers = duckiebot_client.containers.list()
            interface_container_found = False
            for c in duckiebot_containers:
                if 'duckiebot-interface' in c.name:
                    interface_container_found = True
                    interface_container = c
                    dtslogger.info("Temporarily stopping image streaming...")
                    interface_container.stop()
        except Exception as e:
            dtslogger.warn(
                "Not sure if the duckiebot-interface is running because we got and exception when trying: %s"
                % e)

        image = parsed_args.image

        timestamp = datetime.date.today().strftime('%Y%m%d%H%M%S')

        raw_input(
            "{}\nPlace the Duckiebot on the calibration patterns and press ENTER."
            .format('*' * 20))
        log_file = 'out-calibrate-extrinsics-%s-%s' % (hostname, timestamp)
        rosrun_params = '-o /data/{0} > /data/{0}.log'.format(log_file)
        ros_pkg = 'complete_image_pipeline calibrate_extrinsics'
        start_command = 'rosrun {0} {1}'.format(ros_pkg, rosrun_params)
        dtslogger.info('Running command: {}'.format(start_command))

        env = default_env(hostname, duckiebot_ip)

        duckiebot_client.containers.run(image=image,
                                        name=calibration_container_name,
                                        privileged=True,
                                        network_mode='host',
                                        volumes=bind_duckiebot_data_dir(),
                                        command="/bin/bash -c '%s'" %
                                        start_command,
                                        environment=env)

        if not parsed_args.no_verification:
            raw_input(
                "{}\nPlace the Duckiebot in a lane and press ENTER.".format(
                    '*' * 20))
            log_file = 'out-pipeline-%s-%s' % (hostname, timestamp)
            rosrun_params = '-o /data/{0} > /data/{0}.log'.format(log_file)
            ros_pkg = 'complete_image_pipeline single_image_pipeline'
            start_command = 'rosrun {0} {1}'.format(ros_pkg, rosrun_params)
            dtslogger.info('Running command: {}'.format(start_command))

            duckiebot_client.containers.run(image=image,
                                            name=validation_container_name,
                                            privileged=True,
                                            network_mode='host',
                                            volumes=bind_duckiebot_data_dir(),
                                            command="/bin/bash -c '%s'" %
                                            start_command,
                                            environment=env)

        # restart the camera streaming
        try:
            all_duckiebot_containers = duckiebot_client.containers.list(
                all=True)
            found = False
            for c in all_duckiebot_containers:
                if 'duckiebot-interface' in c.name:
                    found = True
                    dtslogger.info("Restarting image streaming...")
                    c.start()
        except Exception as e:
            dtslogger.warn(
                "Not sure if the duckiebot-interface is running because we got and exception when trying: %s"
                % e)
    def command(shell, args):
        prog = 'dts duckiebot demo'
        parser = argparse.ArgumentParser(prog=prog, usage=usage)

        parser.add_argument('--demo_name',
                            dest="demo_name",
                            default=None,
                            help="Name of the demo to run")

        parser.add_argument(
            '--duckiebot_name',
            dest="duckiebot_name",
            default=None,
            help="Name of the Duckiebot on which to run the demo")

        parser.add_argument(
            '--package_name',
            dest="package_name",
            default="duckietown",
            help=
            "You can specify the package that you want to use to look for launch files"
        )

        parser.add_argument(
            '--image',
            dest="image_to_run",
            default="duckietown/rpi-duckiebot-base:master19",
            help="Docker image to use, you probably don't need to change ",
        )

        parser.add_argument('--debug',
                            action='store_true',
                            default=False,
                            help="will enter you into the running container")

        parsed = parser.parse_args(args)

        check_docker_environment()
        demo_name = parsed.demo_name
        if demo_name is None:
            msg = 'You must specify a demo_name'
            raise InvalidUserInput(msg)

        duckiebot_name = parsed.duckiebot_name
        if duckiebot_name is None:
            msg = 'You must specify a duckiebot_name'
            raise InvalidUserInput(msg)

        package_name = parsed.package_name
        dtslogger.info("Using package %s" % package_name)

        duckiebot_ip = get_duckiebot_ip(duckiebot_name)
        duckiebot_client = docker.DockerClient('tcp://' + duckiebot_ip +
                                               ':2375')

        container_name = 'demo_%s' % demo_name
        remove_if_running(duckiebot_client, container_name)
        image_base = parsed.image_to_run
        env_vars = default_env(duckiebot_name, duckiebot_ip)
        env_vars.update({'VEHICLE_NAME': duckiebot_name})

        if demo_name == 'base':
            cmd = '/bin/bash'
        else:
            cmd = 'roslaunch %s %s.launch veh:=%s' % (package_name, demo_name,
                                                      duckiebot_name)

        dtslogger.info("Running command %s" % cmd)
        demo_container = duckiebot_client.containers.run(
            image=image_base,
            command=cmd,
            network_mode='host',
            volumes=bind_duckiebot_data_dir(),
            privileged=True,
            name=container_name,
            mem_limit='800m',
            memswap_limit='2800m',
            stdin_open=True,
            tty=True,
            detach=True,
            environment=env_vars)

        if demo_name == 'base' or parsed.debug:
            attach_cmd = 'docker -H %s.local attach %s' % (duckiebot_name,
                                                           container_name)
            start_command_in_subprocess(attach_cmd)
Beispiel #5
0
    def command(shell, args):

        prog = 'dts duckiebot calibrate_intrinsics DUCKIEBOT_NAME'
        usage = """
Calibrate: 

    %(prog)s
"""

        parser = argparse.ArgumentParser(prog=prog, usage=usage)
        parser.add_argument('hostname', default=None, help='Name of the Duckiebot to calibrate')
        parser.add_argument('--base_image', dest='image',
                            default="duckietown/rpi-duckiebot-base:master19-no-arm")
        parser.add_argument('--debug', action='store_true', default=False,
                            help="will enter you into the running container")


        parsed_args = parser.parse_args(args)
        hostname = parsed_args.hostname
        duckiebot_ip = get_duckiebot_ip(hostname)
        duckiebot_client = get_remote_client(duckiebot_ip)

        # is the interface running?
        try:
            duckiebot_containers = duckiebot_client.containers.list()
            interface_container_found = False
            for c in duckiebot_containers:
                if 'duckiebot-interface' in c.name:
                    interface_container_found = True
            if not interface_container_found:
                dtslogger.error("The  duckiebot-interface is not running on the duckiebot")
                exit()
        except Exception as e:
            dtslogger.warn(
                "Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e)

        # is the raw imagery being published?
        try:
            duckiebot_containers = duckiebot_client.containers.list()
            raw_imagery_found = False
            for c in duckiebot_containers:
                if 'demo_camera' in c.name:
                    raw_imagery_found = True
            if not raw_imagery_found:
                dtslogger.error("The  demo_camera is not running on the duckiebot - please run `dts duckiebot demo --demo_name camera --duckiebot_name %s" % hostname)
                exit()

        except Exception as e:
            dtslogger.warn("%s" % e)


        image = parsed_args.image


        client = check_docker_environment()
        container_name = "intrinsic_calibration_%s" % hostname
        remove_if_running(client,container_name)
        env = {'HOSTNAME': hostname,
               'ROS_MASTER': hostname,
               'DUCKIEBOT_NAME': hostname,
               'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip,
               'QT_X11_NO_MITSHM': 1}

        volumes = {}
        subprocess.call(["xhost", "+"])

        p = platform.system().lower()
        if 'darwin' in p:
            env['DISPLAY'] = 'host.docker.internal:0' 
            volumes = {
                '/tmp/.X11-unix': {'bind': '/tmp/.X11-unix', 'mode': 'rw'}
            }
        else:
            env['DISPLAY'] = os.environ['DISPLAY']

        dtslogger.info("Running %s on localhost with environment vars: %s" %
                       (container_name, env))

        dtslogger.info("When the window opens you will need to move the checkerboard around in front of the Duckiebot camera")
        cmd = "roslaunch pi_camera intrinsic_calibration.launch veh:=%s" % hostname

        params = {'image': image,
                  'name': container_name,
                  'network_mode': 'host',
                  'environment': env,
                  'privileged': True,
                  'stdin_open': True,
                  'tty': True,
                  'detach': True,
                  'command': cmd,
                  'volumes': volumes
                  }

        container = client.containers.run(**params)

        if parsed_args.debug:
            attach_cmd = 'docker attach %s' % (container_name)
            start_command_in_subprocess(attach_cmd)
    def command(shell, args):
        prog = 'dts duckiebot evaluate'
        parser = argparse.ArgumentParser(prog=prog, usage=usage)
        group = parser.add_argument_group('Basic')
        group.add_argument('--duckiebot_name', default=None,
                            help="Name of the Duckiebot on which to perform evaluation")
        group.add_argument('--duckiebot_username', default="duckie",
                           help="The duckiebot username")
        group.add_argument('--image', dest='image_name',
                           help="Image to evaluate, if none specified then we will build your current context",
                           default=None)
        group.add_argument('--glue_node_image', default="duckietown/challenge-aido_lf-duckiebot:aido2",
                           help="The node that glues your submission with ROS on the duckiebot. Probably don't change")
        group.add_argument('--duration', help="Number of seconds to run evaluation", default=15)
        group.add_argument('--remotely', action='store_true', default=True,
                           help="If true run the image over network without pushing to Duckiebot")
        group.add_argument('--no_cache', help="disable cache on docker build",
                           action="store_true", default=False)
        group.add_argument('--record_bag', action='store_true', default=False,
                           help="If true record a rosbag")
        group.add_argument("--debug", action='store_true', default=False,
                           help="If true you will get a shell instead of executing")
        group.add_argument('--max_vel', help="the max velocity for the duckiebot", default=0.7)
        group.add_argument('--challenge', help="Specific challenge to evaluate")
        parsed = parser.parse_args(args)

        tmpdir = '/tmp'
        USERNAME = getpass.getuser()
        dir_home_guest = os.path.expanduser('~')
        dir_fake_home = os.path.join(tmpdir, 'fake-%s-home' % USERNAME)
        if not os.path.exists(dir_fake_home):
            os.makedirs(dir_fake_home)
        get_calibration_files(dir_fake_home, parsed.duckiebot_username, parsed.duckiebot_name)

        client = check_docker_environment()
        agent_container_name = "agent"
        glue_container_name = "aido_glue"

        # remove the containers if they are already running
        remove_if_running(client, agent_container_name)
        remove_if_running(client, glue_container_name)

        # setup the fifos2 volume (requires pruning it if it's still hanging around from last time)
        try:
            client.volumes.prune()
            fifo2_volume=client.volumes.create(name='fifos2')
        except Exception as e:
            dtslogger.warn("error creating volume: %s" % e)


        duckiebot_ip = get_duckiebot_ip(parsed.duckiebot_name)

        duckiebot_client = get_remote_client(duckiebot_ip)
        try:
            duckiebot_containers = duckiebot_client.containers.list()
            interface_container_found=False
            for c in duckiebot_containers:
                if 'duckiebot-interface' in c.name:
                    interface_container_found=True
            if not interface_container_found:
                dtslogger.error("The  duckiebot-interface is not running on the duckiebot")
        except Exception as e:
            dtslogger.warn("Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e)
            

        # let's start building stuff for the "glue" node
        glue_volumes =  {fifo2_volume.name: {'bind': '/fifos', 'mode': 'rw'}}
        glue_env = {'HOSTNAME':parsed.duckiebot_name,
                    'DUCKIEBOT_NAME':parsed.duckiebot_name,
                    'ROS_MASTER_URI':'http://%s:11311' % duckiebot_ip}

        dtslogger.info("Running %s on localhost with environment vars: %s" %
                       (parsed.glue_node_image, glue_env))
        params = {'image': parsed.glue_node_image,
                  'name': glue_container_name,
                  'network_mode': 'host',
                  'privileged': True,
                  'environment': glue_env,
                  'detach': True,
                  'tty': True,
                  'volumes': glue_volumes}

        # run the glue container
        glue_container = client.containers.run(**params)

        if not parsed.debug:
            monitor_thread = threading.Thread(target=continuously_monitor, args=(client, glue_container.name))
            monitor_thread.start()

        if parsed.image_name is None:
            # if we didn't get an `image_name` we try need to build the local container
            path = '.'
            dockerfile = os.path.join(path, 'Dockerfile')
            if not os.path.exists(dockerfile):
                msg = 'No Dockerfile'
                raise Exception(msg)
            tag='myimage'
            if parsed.no_cache:
                cmd = ['docker', 'build', '--no-cache', '-t', tag, '-f', dockerfile]
            else:
                cmd = ['docker', 'build', '-t', tag, '-f', dockerfile]
            dtslogger.info("Running command: %s" % cmd)
            cmd.append(path)
            subprocess.check_call(cmd)
            image_name = tag
        else:
            image_name = parsed.image_name


        # start to build the agent stuff
        agent_env = {'AIDONODE_DATA_IN':'/fifos/agent-in',
                    'AIDONODE_DATA_OUT':'fifo:/fifos/agent-out'}

        agent_volumes = {fifo2_volume.name: {'bind': '/fifos', 'mode': 'rw'},
                         dir_fake_home: {'bind': '/data/config', 'mode': 'rw'}
                         }


        params = {'image': image_name,
                  'remove': True,
                  'name': agent_container_name,
                  'environment': agent_env,
                  'detach': True,
                  'tty': True,
                  'volumes': agent_volumes}

        if parsed.debug:
            params['command'] = '/bin/bash'
            params['stdin_open'] = True


        
        dtslogger.info("Running %s on localhost with environment vars: %s" % (image_name, agent_env))
        agent_container = client.containers.run(**params)

        if parsed.debug:
            attach_cmd = 'docker attach %s' % agent_container_name
            start_command_in_subprocess(attach_cmd)

        else:
            monitor_thread = threading.Thread(target=continuously_monitor,args=(client, agent_container_name))
            monitor_thread.start()

        duration = int(parsed.duration)
        # should we record a bag?
        if parsed.record_bag:
            bag_container = record_bag(parsed.hostname, duration)

        dtslogger.info("Running for %d s" % duration)
        time.sleep(duration)
        stop_container(glue_container)
        stop_container(agent_container)

        if parsed.record_bag:
            stop_container(bag_container)
    def command(shell, args):
        prog = 'dts start_gui_tools DUCKIEBOT_NAME'
        usage = """
Keyboard control: 

    %(prog)s
"""

        parser = argparse.ArgumentParser(prog=prog, usage=usage)
        parser.add_argument('hostname',
                            default=None,
                            help='Name of the Duckiebot to calibrate')
        parser.add_argument('--network',
                            default='host',
                            help='Name of the network which to connect')
        parser.add_argument('--sim',
                            action='store_true',
                            default=False,
                            help='are we running in simulator?')
        parser.add_argument(
            '--base_image',
            dest='image',
            default="duckietown/rpi-duckiebot-base:master19-no-arm",
            help="The base image, probably don't change the default")
        parsed_args = parser.parse_args(args)

        if parsed_args.sim:
            duckiebot_ip = "localhost"
        else:
            duckiebot_ip = get_duckiebot_ip(
                duckiebot_name=parsed_args.hostname)

        hostname = parsed_args.hostname
        image = parsed_args.image

        client = check_docker_environment()
        container_name = "interactive_gui_tools_%s" % hostname
        remove_if_running(client, container_name)

        if parsed_args.sim:
            env = {
                'HOSTNAME': 'default',
                'ROS_MASTER': hostname,
                'DUCKIEBOT_NAME': hostname,
                'ROS_MASTER_URI': 'http://%s:11311' % hostname
            }
        else:
            env = {
                'HOSTNAME': hostname,
                'ROS_MASTER': hostname,
                'DUCKIEBOT_NAME': hostname,
                'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip
            }

        env['QT_X11_NO_MITSHM'] = 1

        p = platform.system().lower()
        volumes = {'/tmp/.X11-unix': {'bind': '/tmp/.X11-unix', 'mode': 'rw'}}

        if 'darwin' in p:
            subprocess.call(["xhost", "+", '127.0.0.1'])
            env['DISPLAY'] = 'host.docker.internal:0'
        else:
            subprocess.call(["xhost", "+"])
            env['DISPLAY'] = os.environ['DISPLAY']

        dtslogger.info("Running %s on localhost with environment vars: %s" %
                       (container_name, env))

        cmd = "/bin/bash"

        params = {
            'image': image,
            'name': container_name,
            'network_mode': parsed_args.network,
            'environment': env,
            'privileged': True,
            'stdin_open': True,
            'tty': True,
            'detach': True,
            'command': cmd,
            'volumes': volumes
        }

        container = client.containers.run(**params)
        attach_cmd = 'docker attach %s' % container_name
        start_command_in_subprocess(attach_cmd)