syntax = "proto2";

import "dccl/option_extensions.proto";
import "jaiabot/messages/mission.proto";

package jaiabot.protobuf;

message IMUCommand
{
    enum IMUCommandType
    {
        CONFIGURE = 0;
        START_WAVE_HEIGHT_SAMPLING = 1;
        STOP_WAVE_HEIGHT_SAMPLING = 2;
        START_BOTTOM_TYPE_SAMPLING = 3;
        STOP_BOTTOM_TYPE_SAMPLING = 4;
        START_CALIBRATION = 5;
    }

    required IMUCommandType type = 1;

    /// Sample rate for data collection in Hz
    optional double sample_rate = 2
        [(dccl.field) = {units {
            derived_dimensions: "frequency"
            system: "si"
            }, min: 0.1 max: 60 precision: 1},
            default = 10
        ];
}

enum IMUCalibrationState
{
        IN_PROGRESS = 1;
        COMPLETE = 2;
}

message IMUData
{
    message EulerAngles {
        optional double heading = 1 
            [(dccl.field) = {units {
                derived_dimensions: "plane_angle"
                system: "angle::degree"
                }}
            ];
            
        optional double pitch = 2
            [(dccl.field) = {units {
                derived_dimensions: "plane_angle"
                system: "angle::degree"
                }}
            ];

        optional double roll = 3
            [(dccl.field) = {units {
                derived_dimensions: "plane_angle"
                system: "angle::degree"
                }}
            ];

    }
    optional EulerAngles euler_angles = 1;

    message Acceleration {
        optional double x = 1;
        optional double y = 2;
        optional double z = 3;
    }

    optional Acceleration linear_acceleration = 2;
    optional Acceleration gravity = 3;

    message Accuracies {
        optional int32 accelerometer = 1 [(dccl.field) = { min: 0 max: 3 }];
        optional int32 gyroscope = 2 [(dccl.field) = { min: 0 max: 3 }];
        optional int32 magnetometer = 3 [(dccl.field) = { min: 0 max: 3 }];
    }

    optional Accuracies accuracies = 4;

    optional IMUCalibrationState calibration_state = 5;

    optional bool bot_rolled_over = 6 [default = false];

    optional double significant_wave_height = 7 [(dccl.field) = {units {
            derived_dimensions: "length"
            system: "si"
            }}
        ];

    // For bottom characterization
    optional double max_acceleration = 8
        [(dccl.field) = {units {
            derived_dimensions: "acceleration"
            system: "si"
            }}
        ];
    
    message AngularVelocity {
        optional double x = 1
            [(dccl.field) = {
                units {
                    derived_dimensions: "angular_velocity"
                    system: "si"
                }
            }];
        optional double y = 2
            [(dccl.field) = {
                units {
                    derived_dimensions: "angular_velocity"
                    system: "si"
                }
            }];
        optional double z = 3
            [(dccl.field) = {
                units {
                    derived_dimensions: "angular_velocity"
                    system: "si"
                }
            }];
    }

    optional AngularVelocity angular_velocity = 9;

    message Quaternion {
        optional double w = 1;
        optional double x = 2;
        optional double y = 3;
        optional double z = 4;
    }

    optional Quaternion quaternion = 10;

    optional string imu_type = 11;

    optional Acceleration acceleration = 12;

    message MagneticField {
        optional double x = 1
            [(dccl.field) = {
                units {
                    prefix: "micro"
                    system: "si::tesla"
                }
            }];
        optional double y = 2
            [(dccl.field) = {
                units {
                    prefix: "micro"
                    system: "si::tesla"
                }
            }];
        optional double z = 3
            [(dccl.field) = {
                units {
                    prefix: "micro"
                    system: "si::tesla"
                }
            }];
    }

    optional MagneticField magnetic_field = 13;

    message AccelerationWorld {
        optional double north = 1
            [(dccl.field) = {units {
                derived_dimensions: "acceleration"
                system: "si"
                }}
            ];
        optional double east = 2
            [(dccl.field) = {units {
                derived_dimensions: "acceleration"
                system: "si"
                }}
            ];
        optional double down = 3
            [(dccl.field) = {units {
                derived_dimensions: "acceleration"
                system: "si"
                }}
            ];
    }
    optional AccelerationWorld linear_acceleration_world = 14;

}

message IMUIssue
{
    enum SolutionType
    {
        STOP_BOT = 0;
        USE_COG = 1;
        USE_CORRECTION = 2;
        RESTART_BOT = 3;
        REBOOT_BOT = 4;
        REPORT_IMU = 5;
        RESTART_IMU_PY = 6;
        REBOOT_BNO085_IMU = 7;
        REBOOT_BNO085_IMU_AND_RESTART_IMU_PY = 8;
    }

    required SolutionType solution = 1;
    
    enum IssueType {
        HEADING_COURSE_DIFFERENCE_TOO_LARGE = 0;
    }

    optional IssueType type = 2;

    optional MissionState mission_state = 3;

    optional double imu_heading_course_max_diff = 30 [default = 45];

    optional double heading = 31 [(dccl.field) = {
        min: 0
        max: 360
        precision: 0
        units { derived_dimensions: "plane_angle" system: "angle::degree" }
    }];

    optional double desired_heading = 32 [(dccl.field) = {
        min: 0
        max: 360
        precision: 0
        units { derived_dimensions: "plane_angle" system: "angle::degree" }
    }];

    optional double course_over_ground = 33 [(dccl.field) = {
        min: 0
        max: 360
        precision: 0
        units { derived_dimensions: "plane_angle" system: "angle::degree" }
    }];

    optional double heading_course_difference = 34 [(dccl.field) = {
        min: 0
        max: 360
        precision: 0
        units { derived_dimensions: "plane_angle" system: "angle::degree" }
    }];

    optional double pitch = 35 [(dccl.field) = {
        min: -180
        max: 180
        precision: 0
        units { derived_dimensions: "plane_angle" system: "angle::degree" }
    }];
    
    optional double speed_over_ground = 36 [(dccl.field) = {
        min: -5
        max: 10
        precision: 1
        units { derived_dimensions: "velocity" system: "si" }
    }];

    optional double desired_speed = 37 [(dccl.field) = {
        min: -5
        max: 10
        precision: 1
        units { derived_dimensions: "velocity" system: "si" }
    }];
}
