
// AI CONTROL
// ==========
struct AIInputVal // There is an array of these in the AIC packet below
{
    byte    Input;        // Select input value to set
    byte    Time;        // Time to hold (optional, hundredths of a second)
    word    Value;        // Value to set
};
const int AIC_MAX_INPUTS = 20; // NOTE: Increase if CS_NUM is increased
struct IS_AIC // AI Control - variable size
{
    byte    Size;        // 4 + 4 * (number of inputs)
    byte    Type;        // ISP_AIC
    byte    ReqI;        // Optional - returned in any immediate response e.g. reply to CS_SEND_AI_INFO
    byte    PLID;        // Unique ID of AI driver to control
    AIInputVal    Inputs    [AIC_MAX_INPUTS];
};
// If the Time value of AIInputVal is set, that input will return to default after that time.
// This is probably most useful for CS_CHUP / CS_CHDN / CS_FLASH / CS_HORN inputs.
// If you don't set Time you will need to send another packet to zero the input.
// Values for Input
// CS_MSX             0 - steer: 1 hard left / 32768 centre / 65535 hard right
// CS_THROTTLE         1 - 0 to 65535
// CS_BRAKE             2 - 0 to 65535
// CS_CHUP             3 - hold shift up lever
// CS_CHDN             4 - hold shift down lever 
// CS_IGNITION         5 - toggle
// CS_EXTRALIGHT     6 - toggle
// CS_HEADLIGHTS     7 - 1:off / 2:side / 3:low / 4:high
// CS_SIREN             8 - hold siren - 1:fast / 2:slow
// CS_HORN             9 - hold horn  - 1 to 5
// CS_FLASH            10 - hold flash - 1:on
// CS_CLUTCH        11 - 0 to 65535
// CS_HANDBRAKE        12 - 0 to 65535
// CS_INDICATORS    13 - 1: cancel / 2: left / 3: right / 4: hazard
// CS_GEAR            14 - for shifter (leave at 255 for sequential control)
// CS_LOOK            15 - 0: none / 4: left / 5: left+ / 6: right / 7: right+
// CS_PITSPEED        16 - toggle
// CS_TCDISABLE        17 - toggle
// CS_FOGREAR        18 - toggle
// CS_FOGFRONT        19 - toggle
// Inputs marked 'hold' must be set back to zero after some time.
// This can be done either by use of the Time field or by sending a later packet with Value = 0.
// E.g. Set Time to 10 when issuing a CS_CHUP - hold shift up lever for 0.1 sec.
// E.g. Set Time to 50 when issuing a CS_HORN - sound horn for 0.5 sec.
// Inputs marked 'toggle' accept the following Values:
// 1 toggle
// 2 switch off
// 3 switch on
// Special values for Input
#define CS_SEND_AI_INFO        240
#define CS_REPEAT_AI_INFO    241
#define CS_SET_HELP_FLAGS    253
#define CS_RESET_INPUTS        254
#define CS_STOP_CONTROL        255
// CS_SEND_AI_INFO - Send an IS_AII (AI Info) packet
// CS_REPEAT_AI_INFO - Start or stop sending regular IS_AII packets
//        Time = time interval in hundredths of a second (0 : stop)
// CS_SET_HELP_FLAGS - Value can be any combination of
//            PIF_AUTOGEARS    // 8 - auto shift
//            PIF_HELP_B        // 64 - brake help
//            PIF_AUTOCLUTCH    // 512 - auto clutch
//        Default value for an AI driver is PIF_AUTOCLUTCH only
//        If you set PIF_AUTOGEARS you don't need to set PIF_AUTOCLUTCH
// CS_RESET_INPUTS - reset all inputs
//        Most inputs are zero / CS_MSX is 32768 / CS_GEAR is 255
// CS_STOP_CONTTROL
//        The AI driver will stop the car
// AI car info
// -----------
// Send a SMALL_AII with UVal set to PLID to receive current information about a local car
struct OSMain // included in IS_AII - identical to OutSimMain (main data in OutSim packet)
{
    Vector        AngVel;        // 3 floats, angular velocity vector
    float        Heading;    // anticlockwise from above (Z)
    float        Pitch;        // anticlockwise from right (X)
    float        Roll;        // anticlockwise from front (Y)
    Vector        Accel;        // 3 floats X, Y, Z
    Vector        Vel;        // 3 floats X, Y, Z
    Vec            Pos;        // 3 ints   X, Y, Z (1m = 65536)
};
struct IS_AII // AI Info
{
    byte        Size;        // 96
    byte        Type;        // ISP_AII
    byte        ReqI;        // ReqI from the SMALL_AII request packet
    byte        PLID;
    OSMain        OSData;
    byte        Flags;        // AIFLAGS_x below
    byte        Gear;        // Reverse:0, Neutral:1, First:2...
    byte        Sp2;
    byte        Sp3;
    float        RPM;        // RPM
    float        SpF0;
    float        SpF1;
    unsigned    ShowLights;    // Dash lights currently switched on (see DL_x in OutGauge section below)
    unsigned    SPU1;
    unsigned    SPU2;
    unsigned    SPU3;
};
#define AIFLAGS_IGNITION    1        // detect if engine running
//
#define AIFLAGS_CHUP        4        // upshift lever currently held
#define AIFLAGS_CHDN        8        // downshift lever currently held

struct IS_RAI // Regular AI
{
    byte    Size;        // 8
    byte    Type;        // ISP_RAI
    byte    ReqI;        // 0
    byte    PLID;
    word    Interval;    // time between updates, 0 to stop
    byte    Sp2;
    byte    Sp3;
};


// AI CONTROL
// ==========
struct AIInputVal // There is an array of these in the AIC packet below
{
    byte    Input;        // Select input value to set
    byte    Time;        // Time to hold (optional, hundredths of a second)
    word    Value;        // Value to set
};
const int AIC_MAX_INPUTS = 20; // NOTE: Increase if CS_NUM is increased
struct IS_AIC // AI Control - variable size
{
    byte    Size;        // 4 + 4 * (number of inputs)
    byte    Type;        // ISP_AIC
    byte    ReqI;        // 0
    byte    PLID;        // Unique ID of AI driver to control
    AIInputVal    Inputs    [AIC_MAX_INPUTS];
};
// If the Time value is set, that input will return to default after that time.
// This is probably most useful for CS_CHUP / CS_CHDN / CS_FLASH / CS_HORN inputs.
// If you don't use Time then you should send another packet to zero the input.
// Values for Input
// CS_MSX            0 - steer: 1 hard left / 32768 centre / 65535 hard right
// CS_THROTTLE        1 - 0 to 65535
// CS_BRAKE            2 - 0 to 65535
// CS_CHUP            3 - shift up (set to 1 for a short time then set back to 0)
// CS_CHDN            4 - shift down
// CS_IGNITION        5 - toggle
// CS_EXTRALIGHT    6 - toggle
// CS_HEADLIGHTS    7 - 1: off / 2: side / 3: low / 4: high
// CS_SIREN            8
// CS_HORN            9
// CS_FLASH            10
// CS_CLUTCH        11 - 0 to 65535
// CS_HANDBRAKE        12 - 0 to 65535
// CS_INDICATORS    13 - 1: cancel / 2: left / 3: right / 4: hazard
// CS_GEAR            14 - for shifter (leave at 255 for sequential control)
// CS_LOOK            15 - 0: none / 4: left / 5: left+ / 6: right / 7: right+
// CS_PITSPEED        16 - toggle
// CS_TCDISABLE        17 - toggle
// CS_FOGREAR        18 - toggle
// CS_FOGFRONT        19 - toggle
// CS_NUM            20 - number of input values above
// The Inputs marked 'toggle' accept the following Values:
// 1 toggle
// 2 switch off
// 3 switch on
// Special values for Input
// 253: set help flags - Value can be any combination of
//            PIF_AUTOGEARS    // 8 - auto shift
//            PIF_HELP_B        // 64 - brake help
//            PIF_AUTOCLUTCH    // 512 - auto clutch
//        Default value for an AI driver is PIF_AUTOCLUTCH only
//        If you set PIF_AUTOGEARS you don't need to set PIF_AUTOCLUTCH
// 254: reset all inputs
//        Most inputs are zero / CS_MSX is 32768 / CS_GEAR is 255
// 255: stop control
//        The AI driver will stop the car
// AI car info
// -----------
// Send a SMALL_AII with UVal set to PLID to receive current information about a local car
struct OSMain // included in IS_AII - identical to OutSimMain (main data in OutSim packet)
{
    Vector        AngVel;        // 3 floats, angular velocity vector
    float        Heading;    // anticlockwise from above (Z)
    float        Pitch;        // anticlockwise from right (X)
    float        Roll;        // anticlockwise from front (Y)
    Vector        Accel;        // 3 floats X, Y, Z
    Vector        Vel;        // 3 floats X, Y, Z
    Vec            Pos;        // 3 ints   X, Y, Z (1m = 65536)
};
struct IS_AII // AI Info
{
    byte        Size;        // 96
    byte        Type;        // ISP_AII
    byte        ReqI;        // ReqI from the SMALL_AII request packet
    byte        PLID;
    OSMain        OSData;
    byte        Flags;        // AIFLAGS_x below
    byte        Gear;        // Reverse:0, Neutral:1, First:2...
    byte        Sp2;
    byte        Sp3;
    float        RPM;        // RPM
    float        SpF0;
    float        SpF1;
    unsigned    ShowLights;    // Dash lights currently switched on (see DL_x in OutGauge section below)
    unsigned    SPU1;
    unsigned    SPU2;
    unsigned    SPU3;
};
#define AIFLAGS_IGNITION    1        // detect if engine running
//
#define AIFLAGS_CHUP        4        // upshift lever currently held
#define AIFLAGS_CHDN        8        // downshift lever currently held