
/* Generated by Interface Builder */

#import "Car_main.h"
#import "Transmission.h"
#import "Wheels.h"
#import "Cycle.h"
#import "defs.h"

@implementation Transmission

- init
{
    [super init];
    transmission = self;
    return self;
}

- read:(NXTypedStream *)stream
{
    [super read:stream];
    NXReadTypes(stream,"iffff",&currentGear,&efficiency,&finalDriveRatio,&mass,&shiftLag);
    NXReadArray(stream,"f",5,gearRatios);
    NXReadArray(stream,"f",4,shiftPoints);
    return self;
}

- write:(NXTypedStream *)stream
{
    [super write:stream];
    NXWriteTypes(stream,"iffff",&currentGear,&efficiency,&finalDriveRatio,&mass,&shiftLag);
    NXWriteArray(stream,"f",5,gearRatios);
    NXWriteArray(stream,"f",4,shiftPoints);
    return self;
}

- (int)currentGear
{
    return currentGear;
}

- setCurrentGear:(int)aNumber
{
    currentGear = aNumber;
    return self;
}

- (float)efficiency
{
    return efficiency;
}

- setEfficiency:(float)aNumber
{
    efficiency = aNumber;
    return self;
}

- (float)finalDriveRatio
{
    return finalDriveRatio;
}

- setFinalDriveRatio:(float)aNumber
{
    finalDriveRatio = aNumber;
    return self;
}

- (float *)gearRatios
{
    return gearRatios;
}

- setGearRatios:(float *)theRatios
{
int i;

    for ( i = 0 ; i < 5 ; i++ )
        gearRatios[i] = theRatios[i];
    return self;
}

- (float)mass
{
    return mass;
}

- setMass:(float)aNumber
{
    mass = aNumber;
    return self;
}

- (float)shiftLag
{
    return shiftLag;
}

- setShiftLag:(float)aNumber
{
    shiftLag = aNumber;
    return self;
}

- (float*)shiftPoints
{
    return shiftPoints;
}

- setShiftPoints:(float *)thePoints
{
int i;

    for ( i = 0 ; i < 4 ; i++ )
        shiftPoints[i] = thePoints[i];
    return self;
}

- (float)inputSpeed
{
float outputSpeed;
float inputSpeed;
int tempGear;
float rpm;

    if ( shifting )
        return 0;

    outputSpeed = [wheel speed];
    outputSpeed = outputSpeed * finalDriveRatio;
		
    for ( tempGear = 1 ; tempGear < 5 ; tempGear++ )		// Favors the lowest gear possible to do the job.
        {
        inputSpeed = outputSpeed * gearRatios[tempGear-1];
        rpm = inputSpeed * 60 / ( 2 * PI );
        if ( rpm < shiftPoints[tempGear-1] )
            break;
        }
    if ( rpm > shiftPoints[tempGear-1] )
        tempGear = 5;

    // Now that we've found the proper gear, we have to decide if we want to shift to it.
    if ( tempGear == currentGear - 1 )		// We have a 500 rpm buffer zone where the Transmission won't downshift.
        if ( rpm > shiftPoints[tempGear-1] - 500 )
            tempGear = currentGear;

    if ( currentGear != tempGear )
        {
        currentGear = tempGear;
        shifting = YES;
        shiftTime = [cycle lastTime];
        }
    inputSpeed = outputSpeed * gearRatios[currentGear-1]; 
    return inputSpeed;
}

- engineInput:(float)torque
{
    engineTorque = torque;
    return self;
}

- motorInput:(float)torque
{
float total;

    motorTorque = torque;
    total = motorTorque + engineTorque;
    total *= gearRatios[currentGear - 1];
    total *= finalDriveRatio;

    if ( shifting )
        {
        if ( [cycle lastTime] - shiftTime < shiftLag )
            total = 0;
        else
            shifting = NO;
        }

    total = total * efficiency;
    [wheel inputTorque:total];
    return self;
}

@end















