// Copyright (c) 2022 Boston Dynamics, Inc.  All rights reserved.
//
// Downloading, reproducing, distributing or otherwise using the SDK Software
// is subject to the terms and conditions of the Boston Dynamics Software
// Development Kit License (20191101-BDSDK-SL).

syntax = "proto3";

package bosdyn.api;
option java_outer_classname = "PayloadProto";

import "bosdyn/api/geometry.proto";
import "bosdyn/api/header.proto";
import "bosdyn/api/robot_id.proto";

// A Payload describes a single payload installed on the Spot platform.
// It includes all external information necessary to represent
// the payload to the user as a single record.
message Payload {
    // A unique id provided by the payload or auto-generated by the website.
    string GUID = 1;
    // A human readable name describing this payload. It is provided by the
    // payload as part of the payload announcement system.
    string name = 2;
    // A human-readable description string providing more context as to the
    // function of this payload. It is displayed in UIs.
    string description = 3;
    // A list of labels used to indicate what type of payload this is.
    repeated string label_prefix = 9;
    // Set true once the payload is authorized by the administrator in the payload webpage.
    // Must be set to false at registration time.
    bool is_authorized = 4;
    // Set true if the payload is attached to the robot.
    // Must be set to false at registration time.
    bool is_enabled = 5;
    // Set true for payloads registered without their own computers. These records
    // are all manually entered.
    bool is_noncompute_payload = 6;
    // Payload version details.
    SoftwareVersion version = 12;
    // The pose of the payload relative to the body frame.
    SE3Pose body_tform_payload = 7;
    // The pose of the payload relative to the mount frame.
    SE3Pose mount_tform_payload = 8;
    // Optional - mount frame_name (if not included, payload is assumed to be in the body mount frame)
    MountFrameName mount_frame_name = 13;
    // The mass and volume properties of the payload.
    PayloadMassVolumeProperties mass_volume_properties = 10;
    // A list of possible physical configurations for the payload.
    repeated PayloadPreset preset_configurations = 11;
}

// The physical configurations for the payload.
message PayloadPreset {
    // A human readable name describing this configuration. It is displayed in
    // the admin console, but will not overwrite the top level payload name.
    string preset_name = 1;
    // A human-readable description providing context on this configuration. It is
    // displayed in the admin console.
    string description = 2;
    // The pose of the payload relative to the body frame.
    SE3Pose mount_tform_payload = 3;
    // Optional - mount frame_name (if not included, payload is assumed to be in the body mount frame)
    MountFrameName mount_frame_name = 6;
    // The mass and volume properties of the payload.
    PayloadMassVolumeProperties mass_volume_properties = 4;
    // A list of labels used to indicate what type of payload this is.
    repeated string label_prefix = 5;
}

// PayloadMassVolumeProperties contain mass and volume information for the payload
// in the format that the user interacts with it. It is transmitted to the control
// and perception systems and processed there to inform those systems.
message PayloadMassVolumeProperties {
    // Total mass of payload in kg.
    float total_mass = 2;
    // Position of the center of mass of the payload in the payload frame. Meters.
    Vec3 com_pos_rt_payload = 3;
    // The moment of inertia of the payload, represented about the payload
    // center of mass, in the payload frame. Units in [kg*m^2].
    MomentOfIntertia moi_tensor = 4;
    // Zero or more bounding boxes indicating the occupied volume of the payload.
    // These boxes must be represented in the payload frame by specifying
    // Must have Box3WithFrame.frame_name == "payload".
    repeated Box3WithFrame bounding_box = 5;
    // Joint limits defining limits to range of motion of the hips of the robot,
    // in order to prevent collisions with the payload.
    // This field is optional and is only recommended for advanced development
    // purposes.
    repeated JointLimits joint_limits = 6;
}

// Structure describing the moment of intertia of a body. The xx, yy, zz fields
// are the diagonal of the MOI tensor, and the xy, xz, and yz fields are the
// off diagonal terms.
message MomentOfIntertia {
    float xx = 2;
    float yy = 3;
    float zz = 4;
    float xy = 5;
    float xz = 6;
    float yz = 7;
}

// JointLimits contain hip joint angles where limb to payload collisions occur.
message JointLimits {
    // Label identifying the respective limb to which these apply [fr,fl,hr,hl]
    string label = 2;
    // (hy, hx) coordinates outlining the hip joint limits where collisions occur
    // between robot hip and payload. Paired vectors must be of equal length.
    // Angles are measured with actual contact. Appropriate margin will be provided
    // in software. Radians.
    // Left legs must have hx > 0. Right legs must have hx < 0.
    repeated float hy = 3;
    // All legs must have hy > 1.3.
    repeated float hx = 4;
}

// The ListPayloads request message sent to the robot to get all known payloads.
message ListPayloadsRequest {
    // Common request header.
    RequestHeader header = 1;
}

// The ListPayloads response message returns all payloads registered in the robot's directory.
message ListPayloadsResponse {
    // Common response header.
    ResponseHeader header = 1;
    // The returned list of payloads registered in the directory.
    repeated Payload payloads = 2;
}

// Payloads are defined relative to a frame on the robot. These are the possible frames. 
enum MountFrameName {
    // The is the default. For backwards compatibility, we assume unknown means body mount frame. 
    MOUNT_FRAME_UNKNOWN = 0;
    // The body payload mount frame, as defined in documentation. 
    MOUNT_FRAME_BODY_PAYLOAD = 1;
    // The gripper payload mount frame, as defined in documentation. 
    MOUNT_FRAME_GRIPPER_PAYLOAD = 2;
    // The wrist link frame, as defined in the gripper CAD and documentation. 
    MOUNT_FRAME_WR1 = 3;
}
