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
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
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)
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.")
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