예제 #1
0
    /// <summary>
    /// ship will maintain a course using as much helm as needed, used when it is necessary to override the direction of the turn rather than letting the program decide (eg. when you need to turn the long way around)
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="course"></param>
    public override void Steer(Direction direction, float course)
    {
        switch (direction)
        {
        case Direction.STARBOARD:
            if (RelVelCalc.CalculateDifferenceOfBearing(shipsHead, course, Direction.STARBOARD) > 180f)
            {
            }
            else
            {
                Steer(course);
            }
            break;

        case Direction.PORT:
            if (RelVelCalc.CalculateDifferenceOfBearing(shipsHead, course, Direction.PORT) > 180f)
            {
            }
            else
            {
                Steer(course);
            }
            break;

        default:
            break;
        }
    }
예제 #2
0
 // Update is called once per frame
 void Update()
 {
     transform.LookAt(Camera.main.transform);
     this.transform.Rotate(0, 180, 0);
     dynamicFontSizeAdjust();
     RelVelCalc.TrueBearingAndRangeFrom(ownShip.transform.position, guideShip.transform.position, out bearingFromGuide, out rangeToGuide);
     //infotext.text = "Guide Bears: " + bearingFromGuide.ToString() + "°\nGuide Range: " + rangeToGuide.ToString()+ "x" + "\nKey Range: " + ownShip.keyRange.ToString() + "\nKey Bearing: " + ownShip.keyBearing.ToString();
 }
예제 #3
0
 public void CalculateKeyRangeAndBearing(float alterationSize)
 {
     if (alterationSize < 30)
     {
         RelVelCalc.CalculateKeyRangeAndBearing(Advance, FormationData.Instance.guideCRS, FormationData.Instance.guideBears, FormationData.Instance.rangeToGuideStartInYards, FormationData.Instance.guideWillBear, FormationData.Instance.rangetoGuideEndInYards, out keyRange, out keyBearing);
     }
     else if (alterationSize > 30 && alterationSize < 60)
     {
         RelVelCalc.CalculateKeyRangeAndBearing(DNC, FormationData.Instance.guideCRS, FormationData.Instance.guideBears, FormationData.Instance.rangeToGuideStartInYards, FormationData.Instance.guideWillBear, FormationData.Instance.rangetoGuideEndInYards, out keyRange, out keyBearing);
     }
     else if (alterationSize > 60 && alterationSize < 90)
     {
         RelVelCalc.CalculateKeyRangeAndBearing(Transfer, FormationData.Instance.guideCRS, FormationData.Instance.guideBears, FormationData.Instance.rangeToGuideStartInYards, FormationData.Instance.guideWillBear, FormationData.Instance.rangetoGuideEndInYards, out keyRange, out keyBearing);
     }
     else
     {
         RelVelCalc.CalculateKeyRangeAndBearing(DNC, FormationData.Instance.guideCRS, FormationData.Instance.guideBears, FormationData.Instance.rangeToGuideStartInYards, FormationData.Instance.guideWillBear, FormationData.Instance.rangetoGuideEndInYards, out keyRange, out keyBearing);
     }
 }
예제 #4
0
    /// <summary>
    /// gets called whenever calculate is pressed
    /// </summary>
    public void OnCalculatePress()
    {
        //refactor this code later to make it more neat
        if (SpeedOfManeuverField.value == 0)
        {
            RelVelCalc.CalculateRVel(FormationData.Instance.stationingSpeed, out CTS);
        }
        else if (SpeedOfManeuverField.value == 1)
        {
            RelVelCalc.CalculateRVel(FormationData.Instance.guideSpd, out CTS);
        }
        else if (SpeedOfManeuverField.value == 2)
        {
            RelVelCalc.CalculateRVel(FormationData.Instance.fallbackSpeed, out CTS);
        }
        else
        {
            App.Log(this, "Possible off by one or null reference error for desired speed, send bug reports to [email protected]");
            return;
        }

        //sanity check to ensure valid numbers are being output
        if (float.IsNaN(CTS.x) || float.IsNaN(CTS.y))
        {
            App.Log(this, "Error! relvel calculator has returned invalid parameters, send bug reports to [email protected]");
            return;
        }

        float CTSAngle = (Mathf.Atan2(CTS.x, CTS.y) * Mathf.Rad2Deg);

        if (CTSAngle < 0)
        {
            CTSAngle += 360;
        }

        //VectorDisplay.editTrueCTSVector(RelVelCalc.AngleAndMagnitudeToVector2D(CTSAngle - FormationData.Instance.guideCRS, c));

        //Quick sanity check to eliminate revel solutions which do not result in a course or speed alteration. (this can occur when for example, the starting bearing and destination bearing are set to be the same, or in cases where the relvel "triangle" calculated  is actually a straight line)
        float angleCheck = FormationData.Instance.guideCRS - CTSAngle;

        angleCheck = Mathf.Abs(angleCheck);
        float speedCheck = FormationData.Instance.guideSpd - CTS.magnitude;

        speedCheck = Mathf.Abs(speedCheck);

        //check to see if there is any appreciable change in course or speed, if neither has changed, then no solution exists for the given parameters
        if (angleCheck > 1f || speedCheck > 1f)
        {
            CTSAngle = Mathf.Round(CTSAngle);
            float roundedSpeed = Mathf.Round(CTS.magnitude);
            if (CTSAngle < 100)
            {
                CTSText.text   = "CTS: 0" + CTSAngle.ToString() + "°";
                SpeedText.text = "SPD: " + roundedSpeed.ToString() + "KTS";
            }
            else
            {
                CTSText.text   = "CTS: " + CTSAngle.ToString() + "°";
                SpeedText.text = "SPD: " + roundedSpeed.ToString() + "KTS";
            }

            ExecuteButton.interactable = true;
        }
        else
        {
            //change this to a popup message once that functionality is in place
            App.Log(this, "A Relvel Solution could not be calculated for the supplied values, this typically occurs either when a maneuver is physically impossible for the given parameters (eg. abeam to ahead at fallback speed) or when the start and end locations are the same (eg. Guide bears 090 @ 500 yards, Guide will bear 090 at 500 yards) there are some rare instances where a relvel solution should be possible and this error gets thrown, please report these errors by giving as much detailed information as possible to [email protected]");
            ResetInterfaceText();
            ExecuteButton.interactable = false;
        }
    }
예제 #5
0
    /// <summary>
    /// Pulls data from the user interface fields and makes it accessible to the program
    /// </summary>
    void PullInterfaceData()
    {
        //if fields are blank or contain invalid data, exit the method without copying data
        if (CheckInputFieldValidity(FormationStateUIObjects) == false | CheckInputFieldValidity(RelVelCalcUIObjects) == false)
        {
            App.Log(this, "Error, Formation State Fields have been left blank or contain invalid values");
            return;
        }

        float tempCRS;
        float tempSPD;
        float tempGB;
        float tempGWB;
        float tempSSPD;

        float tempGuideStartDistance;
        float tempGuideEndDistance;

        float.TryParse(SSpeedField.text, out tempSSPD);
        float.TryParse(GuideCRSField.text, out tempCRS);
        float.TryParse(GuideSpdField.text, out tempSPD);
        float.TryParse(GuideBearsField.text, out tempGB);
        float.TryParse(GWBField.text, out tempGWB);
        float.TryParse(RangeToGuideStart.text, out tempGuideStartDistance);
        float.TryParse(RangeToGuideEnd.text, out tempGuideEndDistance);

        FormationData.Instance.guideCRS        = tempCRS;
        FormationData.Instance.guideSpd        = tempSPD;
        FormationData.Instance.guideBears      = tempGB;
        FormationData.Instance.guideWillBear   = tempGWB;
        FormationData.Instance.stationingSpeed = tempSSPD;


        if (RangeToGuideStartUnits.value == 0)
        {
            FormationData.Instance.rangeToGuideStartInYards = tempGuideStartDistance;
            RangeToGuideStart.text = FormationData.Instance.rangeToGuideStartInYards.ToString();
        }
        else
        {
            //convert nm to yards for storage consistency
            FormationData.Instance.rangeToGuideStartInYards = RelVelCalc.Yards2NM(tempGuideStartDistance);
            RangeToGuideStart.text = FormationData.Instance.rangeToGuideStartinNM.ToString();
        }
        if (RangetoGuideEndUnits.value == 0)
        {
            FormationData.Instance.rangetoGuideEndInYards = tempGuideEndDistance;
        }
        else
        {
            //convert nm to yards for storage consistency
            FormationData.Instance.rangetoGuideEndInYards = RelVelCalc.Yards2NM(tempGuideEndDistance);
        }

        //Initialise speed rings
        EqualSpeedRing.radius    = FormationData.Instance.guideSpd * 100;
        FallbackSpeedRing.radius = FormationData.Instance.fallbackSpeed * 100;
        compassRing.ChangeRadius(FormationData.Instance.stationingSpeed * 100);

        //Reset Vector Display
        VectorDisplay.ClearVector(LineComponent.RELVECTOR);
        VectorDisplay.ClearVector(LineComponent.CTSVECTOR);
        VectorDisplay.EditGuideVector(FormationData.Instance.guideSpd, FormationData.Instance.guideCRS);

        // FormationData.Instance.DebugDump();

        if (CheckInputFieldValidity(FormationStateUIObjects) && CheckInputFieldValidity(RelVelCalcUIObjects))
        {
            CalculateButton.interactable = true;
        }
        else
        {
            App.Log(this, "error, fields are empty or contain invalid data, check all fields and try again");
        }
    }