Beispiel #1
0
def main(args=None):
    """Command-line interface for interacting with Spot CAM"""
    parser = argparse.ArgumentParser(prog='bosdyn.api.spot_cam',
                                     description=main.__doc__)
    add_common_arguments(parser)

    command_dict = {}  # command name to fn which takes parsed options
    subparsers = parser.add_subparsers(title='commands', dest='command')
    subparsers.required = True

    register_all_commands(subparsers, command_dict)

    options = parser.parse_args(args=args)

    setup_logging(verbose=options.verbose)

    # Create robot object and authenticate.
    sdk = bosdyn.client.create_standard_sdk('Spot CAM Client')
    spot_cam.register_all_service_clients(sdk)

    robot = sdk.create_robot(options.hostname)

    result = command_dict[options.command].run(robot, options)
    if args is None and result:
        # Invoked as a CLI, so print result
        print(result)

    return result
    def __init__(self, bosdyn_sdk_robot, service_name, image_sources, logger=None,
                 use_background_capture_thread=True):
        super(CameraBaseImageServicer, self).__init__()
        if logger is None:
            # Setup the logger to remove duplicated messages and use a specific logging format.
            setup_logging(include_dedup_filter=True)
            self.logger = _LOGGER
        else:
            self.logger = logger

        self.bosdyn_sdk_robot = bosdyn_sdk_robot

        # Service name this servicer is associated with in the robot directory.
        self.service_name = service_name

        # Fault client to report service faults
        self.fault_client = self.bosdyn_sdk_robot.ensure_client(FaultClient.default_service_name)

        # Get a timesync endpoint from the robot instance such that the image timestamps can be
        # reported in the robot's time.
        self.bosdyn_sdk_robot.time_sync.wait_for_sync()

        # A list of all the image sources available by this service. List[VisualImageSource]
        self.image_sources_mapped = dict()  # Key: source name (string), Value: VisualImageSource
        for source in image_sources:
            # Set the logger for each visual image source to be the logger of the camera service class.
            source.set_logger(self.logger)
            # Setup the fault client so service faults can be created.
            source.initialize_faults(self.fault_client, self.service_name)
            # Potentially start the capture threads in the background.
            if use_background_capture_thread:
                source.create_capture_thread()
            # Save the visual image source class associated with the image source name.
            self.image_sources_mapped[source.image_source_name] = source
Beispiel #3
0
def open_door_main(options):
    """Main function for opening door."""
    setup_logging(options.verbose)

    robot = initialize_robot(options)
    assert robot.has_arm(), "Robot requires an arm to open door."

    # Verify the robot is not estopped.
    check_estop(robot)

    # A lease is required to drive the robot.
    lease_client = robot.ensure_client(LeaseClient.default_service_name)
    # Note that the take lease API is used, rather than acquire. Using acquire is typically a
    # better practice, but in this example, a user might want to switch back and forth between
    # using the tablet and using this script. Using take make this a bit less painful.
    lease = lease_client.take()
    try:
        with LeaseKeepAlive(lease_client):
            # Execute open door command sequence.
            execute_open_door(robot, options)
            comment = "Opened door successfully."
            robot.operator_comment(comment)
            robot.logger.info(comment)
    except Exception:
        comment = "Failed to open door."
        robot.operator_comment(comment)
        robot.logger.info(comment)
        raise
    finally:
        lease_client.return_lease(lease)
    return True
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_service_hosting_arguments(parser)
    options = parser.parse_args()

    setup_logging()

    # Create & initialize python service server
    announce_service_servicer = AnnounceServicer()
    service_runner = GrpcServiceRunner(
        announce_service_servicer,
        announce_service_protos_grpc.add_AnnounceServiceServicer_to_server,
        options.port)

    # Keep service alive until a keyboard interrupt.
    service_runner.run_until_interrupt()

    return True
                                         help='Run this example locally.')
    bosdyn.client.util.add_service_hosting_arguments(local_parser)

    # Create the parser for the "robot" command.
    robot_parser = subparsers.add_parser(
        'robot', help='Run this example with a robot in the loop.')
    bosdyn.client.util.add_common_arguments(robot_parser)
    bosdyn.client.util.add_service_endpoint_arguments(robot_parser)

    options = parser.parse_args()

    # If using the example without a robot in the loop, start up the service, which can be
    # be accessed directly at localhost:options.port.
    if options.host_type == 'local':
        # Setup logging to use INFO level.
        setup_logging()
        service_runner = run_service(options.port, logger=_LOGGER)
        print('{} service running.\nCtrl + C to shutdown.'.format(
            DIRECTORY_NAME))
        service_runner.run_until_interrupt()
        sys.exit('Shutting down {} service'.format(DIRECTORY_NAME))

    # Else if a robot is available, register the service with the robot so that all clients can
    # access it through the robot directory without knowledge of the service IP or port.

    # Setup logging to use either INFO level or DEBUG level.
    setup_logging(options.verbose)

    # Create and authenticate a bosdyn robot object.
    sdk = bosdyn.client.create_standard_sdk("HelloWorldMissionServiceSDK")
    robot = sdk.create_robot(options.hostname)
Beispiel #6
0
            help="Only request images from the Ricoh Theta when a GetImage RPC is received. Otherwise, use "
            "a background thread to request images continuously.")
    parser.set_defaults(capture_continuously=False)

if __name__ == '__main__':
    # Define all arguments used by this service.
    import argparse
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_base_arguments(parser)
    bosdyn.client.util.add_payload_credentials_arguments(parser)
    bosdyn.client.util.add_service_endpoint_arguments(parser)
    add_ricoh_theta_arguments(parser)
    options = parser.parse_args()

    # Setup logging to use either INFO level or DEBUG level.
    setup_logging(options.verbose, include_dedup_filter=True)

    # Create and authenticate a bosdyn robot object.
    sdk = bosdyn.client.create_standard_sdk("RicohThetaImageServiceSDK")
    robot = sdk.create_robot(options.hostname)
    PLACEHOLDER_PAYLOAD.GUID = options.guid
    robot.register_payload_and_authenticate(PLACEHOLDER_PAYLOAD, options.secret)

    # Create a service runner to start and maintain the service on background thread. This helper function
    # also returns the servicer associated with the service runner, such that the initialize_camera function
    # can be called after directory registration.
    camera_initialization_success, service_runner = run_service(robot, options, logger=_LOGGER)

    if not camera_initialization_success:
        _LOGGER.error("Ricoh Theta camera did not initialize successfully. The service will NOT be "
                      "registered with the directory.")
Beispiel #7
0
def main(argv):
    """Main testing interface."""
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_common_arguments(parser)
    parser.add_argument(
        "--service-name",
        required=True,
        type=str,
        help=
        "Unique service name for the data acquisition plugin service being tested."
    )
    parser.add_argument(
        '--destination-folder',
        help=('The folder where the data should be downloaded to.'),
        required=False,
        default='.')
    options = parser.parse_args(argv)

    # Setup logger specific for this test program.
    streamlog = logging.StreamHandler()
    streamlog.setLevel(logging.INFO)
    streamlog.setFormatter(logging.Formatter('%(levelname)s - %(message)s'))
    _LOGGER.addHandler(streamlog)
    _LOGGER.setLevel(logging.INFO)
    setup_logging()

    sdk = bosdyn.client.create_standard_sdk('TestDAQPlugin')
    sdk.register_service_client(DataAcquisitionPluginClient)
    robot = sdk.create_robot(options.hostname)
    robot.authenticate(options.username, options.password)
    robot.time_sync.wait_for_sync()
    robot.sync_with_directory()

    # Create a group name for all data collected during this test of the plugin service
    group_name = "Plugin [%s] Test %s" % (
        options.service_name,
        datetime.datetime.today().strftime("%b %d %Y %H:%M:%S"))

    # Create a client for the data-acquisition service on robot.
    main_daq_client = robot.ensure_client(
        DataAcquisitionClient.default_service_name)

    # Create a client for the data store.
    data_store_client = robot.ensure_client(
        DataAcquisitionStoreClient.default_service_name)

    # Test the directory registration of the plugin.
    run_test(test_directory_registration,
             "DAQ Plugin is registered in the robot's directory.", robot,
             options.service_name, DataAcquisitionPluginClient.service_type)

    # Now create a data acquisition plugin client for the plugin service since we know it is
    # registered in the directory.
    robot.sync_with_directory()
    plugin_daq_client = robot.ensure_client(options.service_name)

    # Test that the gRPC communications go through to the plugin service.
    run_test(test_if_service_is_reachable,
             ("Plugin's directory registration networking information "
              "is correct and the plugin can be communicated with via gRPC."),
             plugin_daq_client.get_service_info)

    # Test if there are any active service faults thrown by the plugin service in the current
    # robot state proto.
    run_test(
        test_if_service_has_active_service_faults,
        "The plugin service has no active service "
        "faults in the current robot state.", robot, options.service_name)

    # Test that the data-acquisition plugin service is detected by the data acquisition service
    # on robot and that the plugin's data sources are listed as well.
    _LOGGER.info(
        "TEST: Plugin is recognized by the data acquisition service and its data sources are present."
    )
    success, data_sources = test_if_data_sources_are_available(
        plugin_daq_client, main_daq_client, options.verbose)
    if success:
        _LOGGER.info("SUCCESS!\n")
    else:
        return False

    # Test that each data capability successfully gets acquired and saved to the data store by monitoring
    # the GetStatus request and then checking if the action id is in the data store afterwards.
    run_test(test_capabilities_acquires_and_saves, (
        "All data sources are successfully acquired, respond "
        "with 'status complete' to the GetStatus RPC, and are saved to the data store."
    ), data_sources, main_daq_client, data_store_client, group_name,
             options.verbose)

    # Test that each data capability can successfully be cancelled with no errors.
    run_test(
        test_cancelling,
        "All data sources can be cancelled with the CancelAcquisition RPC.",
        data_sources, main_daq_client, group_name, options.verbose)

    # Test that after running multiple different tests that send each RPC to the plugin service, check
    # that there are still no service faults in the robot state.
    run_test(test_if_service_has_active_service_faults, (
        "The plugin service has no active service "
        "faults after running multiple tests sending RPCs to the plugin service."
    ), robot, options.service_name)

    # Test downloading all of the capture data via the REST endpoint and save the captured data to a
    # specific location.
    run_test(
        test_downloading_all_data_via_REST,
        "All of the captured data can be downloaded via the "
        "REST endpoint.", data_store_client, group_name, options.hostname,
        robot, options.destination_folder)

    _LOGGER.info("Data is downloaded to: %s", options.destination_folder)
    _LOGGER.info("All tests passed for plugin service %s",
                 options.service_name)
    return True