/** \file
 *
 *  Specifies the interface details for the VerticalControl component in the
 *  ControlModule.
 *
 *  VerticalControl.h should only be included by VerticalControl.cpp
 *  Other classes should include VerticalControlIF.h
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef VERTICALCONTROLIF_H_
#define VERTICALCONTROLIF_H_

#include "data/ElementURI.h"

/**
 *  Specifies the interface details for the VerticalControl component in the
 *  ControlModule.
 *
 *  VerticalControl.h should only be included by VerticalControl.cpp
 *  Other classes should include VerticalControlIF.h
 *
 *  \ingroup modules_control
 */
namespace VerticalControlIF
{
/// Static const for component name
/// (Can be used by other components)
static const Str NAME( "VerticalControl" );

// Include common ConfigURIs -- must be in namespace and follow definition of NAME
#include "component/HasLoadAtStartupIF.h"

/// Static consts for input settings
/// (Supplied so outputs can be directed to these inputs)
static const DataURI VERTICAL_MODE( NAME, "verticalMode", Units::ENUM );
static const DataURI DEPTH_CMD( NAME, "depthCmd", Units::METER );
static const DataURI DEPTH_RATE_CMD( NAME, "depthRateCmd", Units::METER_PER_SECOND );
static const DataURI PITCH_CMD( NAME, "pitchCmd", Units::RADIAN );   // specify a pitch to hold
static const DataURI PITCH_RATE_CMD( NAME, "pitchRateCmd", Units::RADIAN_PER_SECOND ); // specify a pitch rate if desired
static const DataURI BUOYANCY_CMD( NAME, "buoyancyCmd", Units::CUBIC_CENTIMETER );
static const DataURI MASS_POSITION_CMD( NAME, "massPositionCmd", Units::METER );
static const DataURI ELEVATOR_ANGLE_CMD( NAME, "elevatorAngleCmd", Units::RADIAN );

/// Configuration
static const ConfigURI BUOYANCY_DEFAULT_CFG( NAME, "buoyancyDefault", Units::CUBIC_CENTIMETER );
static const ConfigURI BUOYANCY_LIMIT_HI_CC_CFG( NAME, "buoyancyLimitHiCC", Units::CUBIC_CENTIMETER );
static const ConfigURI BUOYANCY_LIMIT_LO_CC_CFG( NAME, "buoyancyLimitLoCC", Units::CUBIC_CENTIMETER );
static const ConfigURI BUOYANCY_NEUTRAL_CFG( NAME, "buoyancyNeutral", Units::CUBIC_CENTIMETER );
static const ConfigURI BUOYANCY_PUMP_DEPTH_CFG( NAME, "buoyancyPumpDepth", Units::METER );
static const ConfigURI DEPTH_DEADBAND_CFG( NAME,  "depthDeadband", Units::METER );
static const ConfigURI DEPTH_RATE_DEADBAND_CFG( NAME,  "depthRateDeadband", Units::METER_PER_SECOND );
static const ConfigURI DEPTH_RATE_SAMPLES_CFG( NAME,  "depthRateSamples", Units::COUNT );
static const ConfigURI DROP_WEIGHT_DEPTH_EXCURSION_CFG( NAME,  "dropWtDepthExcursion", Units::METER );
static const ConfigURI DROP_WEIGHT_OVERRIDE_DELAY_CFG( NAME,  "dropWtOverrideDelay", Units::METER );
static const ConfigURI ELEVATOR_DEADBAND_CFG( NAME, "elevDeadband", Units::RADIAN );
static const ConfigURI ELEVATOR_LIMIT_CFG( NAME, "elevLimit", Units::RADIAN );
static const ConfigURI ELEVATOR_TURN_TIME_CFG( NAME, "elevTurnTime", Units::RADIAN );
static const ConfigURI EXCURSION_DEPTH_TIMEOUT_CFG( NAME, "excursionDepthTimeout", Units::SECOND );
static const ConfigURI KD_DEPTH_CFG( NAME, "kdDepth", Units::RADIAN_SECOND_PER_METER );
static const ConfigURI KD_DEPTH_BUOY_CFG( NAME,  "kdDepthBuoy", Units::SECOND );
static const ConfigURI KD_DEPTH_RATE_BUOY_CFG( NAME,  "kdDepthRateBuoy", Units::SECOND );
static const ConfigURI KD_PITCH_ELEVATOR_CFG( NAME, "kdPitchElevator", Units::SECOND );
static const ConfigURI KD_PITCH_MASS_CFG( NAME, "kdPitchMass", Units::SECOND );
static const ConfigURI KI_DEPTH_CFG( NAME, "kiDepth", Units::RADIAN_PER_SECOND_PER_METER );
static const ConfigURI KI_DEPTH_BUOY_CFG( NAME,  "kiDepthBuoy", Units::RECIPROCAL_SECOND );
static const ConfigURI KI_DEPTH_OFF_CFG( NAME, "kiDepthOff", Units::METER_PER_SECOND );
static const ConfigURI KI_DEPTH_RATE_BUOY_CFG( NAME,  "kiDepthRateBuoy", Units::RECIPROCAL_SECOND );
static const ConfigURI KI_PITCH_ELEVATOR_CFG( NAME, "kiPitchElevator", Units::RECIPROCAL_SECOND );
static const ConfigURI KI_PITCH_MASS_CFG( NAME, "kiPitchMass", Units::RECIPROCAL_SECOND );
static const ConfigURI KP_DEPTH_CFG( NAME, "kpDepth", Units::RADIAN_PER_METER );
static const ConfigURI KP_DEPTH_BUOY_CFG( NAME,  "kpDepthBuoy", Units::RATIO );
static const ConfigURI KP_DEPTH_RATE_BUOY_CFG( NAME,  "kpDepthRateBuoy", Units::RATIO );
static const ConfigURI KP_PITCH_ELEVATOR_CFG( NAME, "kpPitchElevator", Units::RATIO );
static const ConfigURI KP_PITCH_MASS_CFG( NAME, "kpPitchMass", Units::RATIO );
static const ConfigURI LIMIT_DEPTH_TRAJECTORY_CFG( NAME, "limitDepthTrajectory", Units::BOOL );
static const ConfigURI MASS_DEADBAND_CFG( NAME, "massDeadband", Units::METER );
static const ConfigURI MASS_DEFAULT_CFG( NAME, "massDefault", Units::METER );
static const ConfigURI MASS_FILTER_LIMIT_CFG( NAME, "massFilterLimit", Units::RADIAN );
static const ConfigURI MASS_FILTER_WIDTH_CFG( NAME, "massFilterWidth", Units::SECOND );
static const ConfigURI MASS_POSITION_LIMIT_FWD_CFG( NAME, "massPositionLimitFwd", Units::METER );
static const ConfigURI MASS_POSITION_LIMIT_AFT_CFG( NAME, "massPositionLimitAft", Units::METER );
static const ConfigURI MASS_TURN_TIME_CFG( NAME, "massTurnTime", Units::SECOND );
static const ConfigURI MAX_BUOY_DIVE_ACCEL_CFG( NAME, "maxBuoyDiveAccel", Units::METER_PER_SECOND_SQUARED );
static const ConfigURI MAX_BUOY_DIVE_RATE_CFG( NAME, "maxBuoyDiveRate", Units::METER_PER_SECOND );
static const ConfigURI MAX_BUOY_INT_CFG( NAME,  "maxBuoyInt", Units::CUBIC_CENTIMETER );
static const ConfigURI MAX_DEPTH_INT_CFG( NAME, "maxDepthInt", Units::RADIAN );
static const ConfigURI MAX_DIVE_ACCEL_CFG( NAME, "maxDiveAccel", Units::METER_PER_SECOND_SQUARED );
static const ConfigURI MAX_DIVE_RATE_CFG( NAME, "maxDiveRate", Units::METER_PER_SECOND );
static const ConfigURI MAX_PITCH_ELEVATOR_INT_CFG( NAME, "maxPitchElevatorInt", Units::RADIAN );
static const ConfigURI MAX_PITCH_MASS_INT_CFG( NAME, "maxPitchMassInt", Units::METER );
static const ConfigURI MAX_PITCH_RATE_CFG( NAME, "maxPitchRate", Units::RADIAN_PER_SECOND );
static const ConfigURI MIN_ASCEND_PITCH_CFG( NAME, "minAscendPitch", Units::RADIAN );
static const ConfigURI MIN_DEPTH_EXCURSION_CFG( NAME, "minDepthExcursion", Units::METER );
static const ConfigURI PITCH_LIMIT_CFG( NAME, "pitchLimit", Units::RADIAN );
static const ConfigURI STOP_DEPTH_EXCURSION_CFG( NAME, "stopDepthExcursion", Units::METER );
static const ConfigURI STOP_OVERRIDE_DELAY_CFG( NAME, "stopOverrideDelay", Units::SECOND );
static const ConfigURI STOP_OVERRIDE_DELAY_BUOY_CFG( NAME, "stopOverrideDelayBuoy", Units::SECOND );
static const ConfigURI SURFACE_THRESHOLD_CFG( NAME, "surfaceThreshold", Units::METER );
static const ConfigURI USE_ELEV_INT_IN_DEPTH_MODE( NAME, "useElevIntInDepthMode", Units::BOOL );
static const ConfigURI MASS_BACK_ON_GO_TO_SURFACE( NAME, "massBackOnGoToSurface", Units::BOOL );
static const ConfigURI PITCH_TIMEOUT_GO_TO_SURFACE( NAME, "pitchTimeoutGoToSurface", Units::SECOND );

/// Static consts for "internal" outputs
static const DataURI DEPTH2BUOYINT_INTERNAL( NAME, "depth2buoyIntInternal", Units::CUBIC_CENTIMETER );
static const DataURI DEPTH_ERROR_INTERNAL( NAME, "depthErrorInternal", Units::METER );
static const DataURI DEPTH_INTEGRAL_INTERNAL( NAME, "depthIntegralInternal", Units::RADIAN );
static const DataURI DT_INTERNAL( NAME, "dtInternal", Units::SECOND );
static const DataURI ELEVATOR_INTEGRAL_INTERNAL( NAME, "elevatorIntegralInternal", Units::RADIAN );
static const DataURI MASS_INTEGRAL_INTERNAL( NAME, "massIntegralInternal", Units::METER );
static const DataURI MASS_PITCH_ERROR_INTERNAL( NAME, "massPitchErrorInternal", Units::RADIAN );
static const DataURI PITCH_INTERNAL( NAME, "pitchInternal", Units::RADIAN );
static const DataURI SMOOTH_DEPTH_INTERNAL( NAME, "smoothDepthInternal", Units::METER );

/// Static consts for outputs to Servos
static const DataURI ELEVATOR_ANGLE_ACTION( NAME, "elevatorAngleAction", Units::RADIAN );
static const DataURI MASS_POSITION_ACTION( NAME, "massPositionAction", Units::METER );
static const DataURI BUOYANCY_ACTION( NAME, "buoyancyAction", Units::CUBIC_CENTIMETER );

/// Defines vertical modes
typedef enum
{
    NONE,              // No depth control - drift or wander
    SURFACE,           // Go to the surface
    DEPTH,             // Go to a specified depth
    DEPTH_RATE,        // Go at a specified depth rate
    PITCH_ZERO,        // Hold a zero pitch
    PITCH,             // Hold the specified pitch angle
    PITCH_RATE,        // Hold the specified pitch angle rate (until max pitch)
    MASS_AND_ELEVATOR, // Hold the specified mass and elevator positions
    FLOAT_ON_SURFACE,             // Float on the surface
} VerticalMode;
}

#endif /*VERTICALCONTROLIF_H_*/
