def main(argv): """An example using the API demonstrating adding image coordinates to the world object service.""" parser = argparse.ArgumentParser() bosdyn.client.util.add_common_arguments(parser) options = parser.parse_args(argv) # Create robot object with a world object client. sdk = bosdyn.client.create_standard_sdk('WorldObjectClient') sdk.load_app_token(options.app_token) robot = sdk.create_robot(options.hostname) robot.authenticate(options.username, options.password) # Time sync is necessary so that time-based filter requests can be converted. robot.time_sync.wait_for_sync() # Create the world object client. world_object_client = robot.ensure_client( WorldObjectClient.default_service_name) # List all world objects in the scene before any mutation. world_objects = world_object_client.list_world_objects().world_objects print("Current World objects before mutations: " + str([obj for obj in world_objects])) # Set the detection time for the additional april tag. The client library will convert the time into robot time. # Uses a function to get google.protobuf.Timestamp of the current system time. timestamp = now_timestamp() # Create the image coordinate object. This type of object does not require a base frame for the world object. # Since we are not providing a transform to the object expressed by the image coordinates, than it is not necessary # to set the frame_name_image_properties, as this describes the frame used in a transform (such as world_tform_image_coords) img_coord = wo.ImageProperties( camera_source="back", coordinates=geom.Polygon(vertexes=[geom.Vec2(x=100, y=100)])) wo_obj = wo.WorldObject(id=2, name="img_coord_tester", acquisition_time=timestamp, image_properties=img_coord) # Request to add the image coordinates detection to the world object service. add_coords = make_add_world_object_req(wo_obj) resp = world_object_client.mutate_world_objects(mutation_req=add_coords) # List all world objects in the scene after the mutation was applied. world_objects = world_object_client.list_world_objects().world_objects print("Current World objects after adding coordinates: " + str([obj for obj in world_objects])) return True
def main(argv): """An example using the API to apply mutations to world objects.""" parser = argparse.ArgumentParser() bosdyn.client.util.add_common_arguments(parser) options = parser.parse_args(argv) # Create robot object with a world object client. sdk = bosdyn.client.create_standard_sdk('WorldObjectClient') robot = sdk.create_robot(options.hostname) robot.authenticate(options.username, options.password) # Time sync is necessary so that time-based filter requests can be converted. robot.time_sync.wait_for_sync() # Create the world object client. world_object_client = robot.ensure_client( WorldObjectClient.default_service_name) # List all world objects in the scene. world_objects = world_object_client.list_world_objects().world_objects print("Current World objects' ids " + str([obj.id for obj in world_objects])) # If there are any world objects in Spot's perception scene, then attempt to mutate one. # This should fail and return a STATUS_NO_PERMISSION since a client cannot mutate # objects that they did not add into the scene. if len(world_objects) > 0: obj_to_mutate = world_objects[0] # Attempt to delete the object. delete_req = make_delete_world_object_req(obj_to_mutate) status = world_object_client.mutate_world_objects(delete_req).status assert (status == world_object_pb2.MutateWorldObjectResponse. STATUS_NO_PERMISSION) # Attempt to change the object. for edge in obj_to_mutate.transforms_snapshot.child_to_parent_edge_map: obj_to_mutate.transforms_snapshot.child_to_parent_edge_map[ edge].parent_tform_child.position.x = 1.0 change_req = make_change_world_object_req(obj_to_mutate) status = world_object_client.mutate_world_objects(change_req).status assert (status == world_object_pb2.MutateWorldObjectResponse. STATUS_NO_PERMISSION) # Request to add the new april tag detection to the world object service. wo_obj_to_add = create_apriltag_object() add_apriltag = make_add_world_object_req(wo_obj_to_add) resp = world_object_client.mutate_world_objects(mutation_req=add_apriltag) # Get the world object ID set by the service, so that we can make additional changes to this object. added_apriltag_world_obj_id = resp.mutated_object_id # List all world objects in the scene after the mutation was applied. world_objects = world_object_client.list_world_objects().world_objects print("World object IDs after object addition: " + str([obj.apriltag_properties.tag_id for obj in world_objects])) for world_obj in world_objects: if world_obj.id == added_apriltag_world_obj_id: # Look for the custom frame that was included in the add-request, where the child frame name was "my_special_frame" full_snapshot = world_obj.transforms_snapshot for edge in full_snapshot.child_to_parent_edge_map: if edge == "my_special_frame": print( "The world object includes the custom frame vision_tform_my_special_frame!" ) # Request to change an existing apriltag's dimensions. This will succeed because it is changing # an object that was added by a client program. We are using the ID returned by the service to # change the correct apriltag. time_now = now_timestamp() tag_prop_modified = world_object_pb2.AprilTagProperties( tag_id=308, dimensions=geom.Vec2(x=.35, y=.35)) wo_obj_to_change = world_object_pb2.WorldObject( id=added_apriltag_world_obj_id, name="world_obj_apriltag", transforms_snapshot=wo_obj_to_add.transforms_snapshot, acquisition_time=time_now, apriltag_properties=tag_prop_modified) print("World object X dimension of apriltag size before change: " + str([obj.apriltag_properties.dimensions.x for obj in world_objects])) change_apriltag = make_change_world_object_req(wo_obj_to_change) resp = world_object_client.mutate_world_objects( mutation_req=change_apriltag) assert ( resp.status == world_object_pb2.MutateWorldObjectResponse.STATUS_OK) # List all world objects in the scene after the mutation was applied. world_objects = world_object_client.list_world_objects().world_objects print("World object X dimension of apriltag size after change: " + str([obj.apriltag_properties.dimensions.x for obj in world_objects])) # Add a apriltag and then delete it. This will succeed because it is deleting an object added by # a client program and not specific to Spot's perception add_apriltag = make_add_world_object_req(wo_obj_to_add) resp = world_object_client.mutate_world_objects(mutation_req=add_apriltag) assert ( resp.status == world_object_pb2.MutateWorldObjectResponse.STATUS_OK) apriltag_to_delete_id = resp.mutated_object_id # Update the list of world object's after adding a apriltag world_objects = world_object_client.list_world_objects().world_objects # Delete the april tag that was just added. This will succeed because it is changing an object that was # just added by a client program (and not an object Spot's perception system detected). The world object # can be identified by the ID returned from the service after the mutation request succeeded. wo_obj_to_delete = world_object_pb2.WorldObject(id=apriltag_to_delete_id) delete_apriltag = make_delete_world_object_req(wo_obj_to_delete) resp = world_object_client.mutate_world_objects( mutation_req=delete_apriltag) assert ( resp.status == world_object_pb2.MutateWorldObjectResponse.STATUS_OK) # List all world objects in the scene after the deletion was applied. world_objects = world_object_client.list_world_objects().world_objects print("World object IDs after object deletion: " + str([obj.apriltag_properties.tag_id for obj in world_objects])) # Add a drawable object into the perception scene with a custom frame and unique name. sphere_to_add = create_drawable_sphere_object() add_sphere = make_add_world_object_req(sphere_to_add) resp = world_object_client.mutate_world_objects(mutation_req=add_sphere) # Get the world object ID set by the service. sphere_id = resp.mutated_object_id # List all world objects in the scene after the mutation was applied. Find the sphere in the list # and see the transforms added into the frame tree snapshot by Spot in addition to the custom frame. world_objects = world_object_client.list_world_objects().world_objects for world_obj in world_objects: if world_obj.id == sphere_id: print("Found sphere named " + world_obj.name) full_snapshot = world_obj.transforms_snapshot for edge in full_snapshot.child_to_parent_edge_map: print("Child frame name: " + edge + ". Parent frame name: " + full_snapshot.child_to_parent_edge_map[edge]. parent_frame_name) return True