private void TransmitSlewEvents(AIPlane AIAircraft, uint heading_rate, uint ahead_rate, uint bank_rate, uint pitch_rate, uint alt_rate) { simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_AHEAD_SET, ahead_rate, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_HEADING_SET, heading_rate, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_ALT_SET, alt_rate, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_BANK_SET, bank_rate, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_PITCH_SET, pitch_rate, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); }
private void ResetRates(AIPlane AIAircraft) { TransmitSlewEvents(AIAircraft, 0, 0, 0, 0, 0); }
private void CreateNewAIAircraft(TrafficPositionReportMessage trafficPositionReportMessage) { uint counter; lock (AICounterLock) { counter = AICounter++; } AICounterToCallsignMap.Add(counter, trafficPositionReportMessage.Sender); try { // TODO: OnGround + airspeed var initpos = new SIMCONNECT_DATA_INITPOSITION() { Altitude = trafficPositionReportMessage.TrueAltitude, Bank = -trafficPositionReportMessage.BankAngle, Heading = trafficPositionReportMessage.Heading, Latitude = trafficPositionReportMessage.Latitude, Longitude = trafficPositionReportMessage.Longitude, Pitch = -trafficPositionReportMessage.Pitch, OnGround = 1, Airspeed = 0 }; simconnect.AICreateNonATCAircraft(GetRepaintTitle(), trafficPositionReportMessage.Sender, initpos, (SIMCONNECT_EVENTS)((uint)SIMCONNECT_EVENTS.EVENTID_SETAIAC + counter)); // simconnect.AICreateSimulatedObject(GetRepaintTitle(), initpos, (SIMCONNECT_EVENTS)((uint)SIMCONNECT_EVENTS.EVENTID_SETAIAC + counter)); var aiplane = new AIPlane(trafficPositionReportMessage.Sender); aiplane.SetTargetWaypoint(CreateWaypointFromTrafficPositionReportMsg(trafficPositionReportMessage)); aiplane.AICounter = counter; CallsignToAIPlaneMap.Add(aiplane.Callsign, aiplane); } catch (COMException e) { Logger.Error("SimConnectInterface.CreateNewAIAircraft: " + e); } }
private void MoveAI(AIPlane AIAircraft, Waypoint newWp) { simconnect.TransmitClientEvent(AIAircraft.SimConnectObjectId, SIMCONNECT_EVENTS.EVENTID_AXIS_SLEW_AHEAD_SET, 0, GROUP_PRIORITIES.SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); var aimove = new AIMoveStruct() { latitude = newWp.Latitude, longitude = newWp.Longitude, truealtitude = newWp.Altitude, pitch = newWp.Pitch, bank = newWp.Bank, heading = newWp.Heading, }; Logger.Trace(AIAircraft.Callsign + " doing WARP SPEED"); simconnect.SetDataOnSimObject(DEFINITIONS.AIMoveStruct, AIAircraft.SimConnectObjectId, SIMCONNECT_DATA_SET_FLAG.DEFAULT, aimove); }
private void CalculateSlewAI(AIPlane AIAircraft, Waypoint currentWp, Waypoint newWp) { var period = AIAircraft.RemainingSecondsUntilTarget; AIAircraft.RemainingSecondsUntilTarget --; bool onGround = currentWp.OnGround && Math.Abs(currentWp.Altitude - newWp.Altitude) < 10; AIAircraft.SlowingDownForParkingMode = currentWp.GroundSpeed > 0 && newWp.GroundSpeed == 0 && onGround; double periodCorrectionForParking = period > 1 && AIAircraft.SlowingDownForParkingMode ? -1.0 : 0; Logger.Debug(string.Format("{0} SlowingDownForParkingMode: {1}, periodCorrectionForParking: {2}", AIAircraft.Callsign, periodCorrectionForParking, AIAircraft.SlowingDownForParkingMode)); // now calculate steering deltas based on predict point double bearing_to_wp = SimMath.bearing(currentWp.Latitude, currentWp.Longitude, newWp.Latitude, newWp.Longitude); uint heading_rate = 0; uint ahead_rate = SimMath.slew_ahead_rate(currentWp.Latitude, currentWp.Longitude, newWp.Latitude, newWp.Longitude, period + periodCorrectionForParking); //uint ahead_rate = SimMath.slew_ahead_rate_experimental(AIAircraft.Callsign, currentWp, newWp, period); bool doFinalHardTurnBeforeParking = AIAircraft.SlowingDownForParkingMode && AIAircraft.RemainingSecondsUntilTarget == 1; heading_rate = SimMath.slew_turn_rate(bearing_to_wp, currentWp.Heading, newWp.Heading, currentWp.GroundSpeed, doFinalHardTurnBeforeParking); if (SimMath.AIAircraftIsPushingBack(currentWp, newWp, heading_rate)) { Logger.Debug(string.Format("{0} assuming pushback, old bearing: {1}", AIAircraft.Callsign, bearing_to_wp)); // Hard turn with low real GS, probably a pushback bearing_to_wp = SimMath.bearing(newWp.Latitude, newWp.Longitude, currentWp.Latitude, currentWp.Longitude); heading_rate = SimMath.slew_turn_rate(bearing_to_wp, currentWp.Heading, newWp.Heading, currentWp.GroundSpeed, doFinalHardTurnBeforeParking); ahead_rate = ((uint)-(int)ahead_rate); } double speed = SimMath.distance(currentWp.Latitude, currentWp.Longitude, newWp.Latitude, newWp.Longitude) / (period + periodCorrectionForParking); var desiredHdg = SimMath.desired_heading(bearing_to_wp, newWp.Heading, doFinalHardTurnBeforeParking ? 0.9 : 0.1); Logger.Debug(string.Format("Period: {0} speed: {1} ahead rt: {2} bearing: {3} ({5}) desired heading: {4} ({6})", period, speed, SimMath.slew_ahead_to_rate(speed), bearing_to_wp, desiredHdg, RadianToDegree(bearing_to_wp), RadianToDegree(desiredHdg))); /* uint ahead_rate = SimMath.slew_ahead_rate_experimental(AIAircraft.Callsign, currentWp, newWp, period); if (Math.Abs((int)ahead_rate) > 16384) { }*/ // On ground, and not on the way up or down? ignore pitch + bank uint bank_rate = onGround ? 0 : SimMath.slew_rotation_to_rate((newWp.Bank - currentWp.Bank) / period, currentWp.GroundSpeed); uint pitch_rate = onGround ? 0 : SimMath.slew_rotation_to_rate((newWp.Pitch - currentWp.Pitch) / period, currentWp.GroundSpeed); uint alt_rate = SimMath.slew_alt_to_rate(SimMath.ft2m((currentWp.Altitude - newWp.Altitude)) / period); Logger.Debug(string.Format("CURRENT WP: La {0}, Lo {1}, Alt {2}, Pi {3}, Ba {4}, Hdg {5} ({7}), GS: {6}", currentWp.Latitude.ToString("0000.00000000"), currentWp.Longitude.ToString("0000.00000000"), currentWp.Altitude.ToString("00000"), currentWp.Pitch.ToString("0000.00000000"), currentWp.Bank.ToString("0000.00000000"), currentWp.Heading.ToString("0000.00000000"), currentWp.GroundSpeed.ToString("000.0000"), RadianToDegree(currentWp.Heading) )); Logger.Debug(string.Format("NEW WP : La {0}, Lo {1}, Alt {2}, Pi {3}, Ba {4}, Hdg {5} ({11}), GS {11}, Ahead rt {6}, Alt rt {7}, Pi rt {8}, Ba rt {9}, Hdg rt {10}", newWp.Latitude.ToString("0000.00000000"), newWp.Longitude.ToString("0000.00000000"), newWp.Altitude.ToString("00000"), newWp.Pitch.ToString("0000.00000000"), newWp.Bank.ToString("0000.00000000"), newWp.Heading.ToString("0000.00000000"), (int)ahead_rate, (int)alt_rate, (int)pitch_rate, (int)bank_rate, (int)heading_rate, newWp.GroundSpeed.ToString("000.0000"), RadianToDegree(newWp.Heading) )); // send the actual slew adjustments if (speed <= MAX_SPEED_BEFORE_WARP) { TransmitSlewEvents(AIAircraft, heading_rate, ahead_rate, bank_rate, pitch_rate, alt_rate); if(onGround) { AIAltAboveGroundStruct s = new AIAltAboveGroundStruct() { altAboveGround = 0 }; // simconnect.SetDataOnSimObject(DEFINITIONS.AISetAltAboveGroundStruct, AIAircraft.SimConnectObjectId, SIMCONNECT_DATA_SET_FLAG.DEFAULT, s); } } else MoveAI(AIAircraft, newWp); // send gear up/down as necessary // TODO: ai_gear(ai_index, i, pos); }