//TODO: Finish these private static List<ThrustSet> GetZeroTorques(ThrustContribution[] used, double fuelToThrust, Point3D centerMass) { // Split the list into inline thrusters, and thrusters that produce torque. So there could be 5 total, but if only 2 // produce torque, only those 2 are used in the torque calculations List<ThrustContribution> noTorque = new List<ThrustContribution>(); List<ThrustContribution> hasTorque = new List<ThrustContribution>(); for (int cntr = 0; cntr < used.Length; cntr++) { if (IsNearZeroTorque(used[cntr].Torque)) { noTorque.Add(used[cntr]); } else { hasTorque.Add(used[cntr]); } } List<ThrustSet> retVal = new List<ThrustSet>(); if (hasTorque.Count == 0) { // All zero torque retVal.AddRange(GetZeroTorquesSprtZeroTorque(noTorque, fuelToThrust)); } else if (hasTorque.Count == 2) { // Two retVal.AddRange(GetZeroTorquesSprtTwoTorque(noTorque, hasTorque, fuelToThrust)); } else if (hasTorque.Count > 2) { // Many //retVal.AddRange(GetZeroTorquesSprtManyTorque1(noTorque, hasTorque, fuelToThrust)); retVal.AddRange(GetZeroTorquesSprtManyTorque5(noTorque, hasTorque, fuelToThrust, centerMass)); } // Throw out any that have zero translation retVal = retVal.Where(o => !IsNearZeroTranslation(o.TranslationLength)).ToList(); // Exit Function return retVal; }
private static List<ThrustSet> GetZeroTranslations(ThrustContribution[] used, double fuelToThrust) { return new List<ThrustSet>(); }
private static Tuple<int, int>[] GetIllegalCombos(ThrustContribution[] thrusters) { List<Tuple<int, int>> retVal = new List<Tuple<int, int>>(); for (int outer = 0; outer < thrusters.Length - 1; outer++) { for (int inner = outer + 1; inner < thrusters.Length; inner++) { if (thrusters[outer].Thruster == thrusters[inner].Thruster) { Vector3D dir1 = thrusters[outer].Thruster.ThrusterDirectionsModel[thrusters[outer].Index]; Vector3D dir2 = thrusters[inner].Thruster.ThrusterDirectionsModel[thrusters[inner].Index]; if (Math1D.IsNearValue(Vector3D.DotProduct(dir1, dir2), -1d)) { retVal.Add(new Tuple<int, int>(outer, inner)); } } } } return retVal.ToArray(); }
/// <summary> /// This taks a set of thrusters and tries to find combinations that will produce zero torque and combinations that will produce zero translation /// </summary> /// <returns> /// Item1=Torques /// Item2=Translations /// </returns> private static Tuple<ThrustSet[], ThrustSet[]> GetZeros(ThrustContribution[] all, int[] combo, double fuelToThrust, Point3D centerMass) { // Get an array of the referenced thrusters ThrustContribution[] used = new ThrustContribution[combo.Length]; for (int cntr = 0; cntr < combo.Length; cntr++) { used[cntr] = all[combo[cntr]]; } //This is now done up front (more efficient) // Make sure this combo doesn't have the same thruster firing is opposite directions //if (!IsValidCombo(used)) //{ // return null; //} // Try to find combinations of these thrusters that will produce zero torque and zero translation List<ThrustSet> torques = GetZeroTorques(used, fuelToThrust, centerMass); List<ThrustSet> translations = GetZeroTranslations(used, fuelToThrust); // Exit Function if (torques.Count == 0 && translations.Count == 0) { return null; } else { return new Tuple<ThrustSet[], ThrustSet[]>(torques.ToArray(), translations.ToArray()); } }
private static IEnumerable<ThrusterSetting> EnsureThrustKeysBuilt_Rotate(Vector3D axis, ThrustContribution[] contributions, double maxAcceleration, MassMatrix inertia) { axis = axis.ToUnit(); // doing this so the dot product can be used as a percent List<Tuple<ThrustContribution, double>> retVal = new List<Tuple<ThrustContribution, double>>(); // Get a list of thrusters that will contribute to the direction foreach (ThrustContribution contribution in contributions) { double dot = Vector3D.DotProduct(contribution.TorqueUnit, axis); if (dot > .5d) { //retVal.Add(new ThrusterSetting(contribution.Thruster, contribution.Index, 1)); // for now, just do 100% retVal.Add(Tuple.Create(contribution, contribution.TorqueLength * dot)); } } retVal = FilterThrusts(retVal); #region Reduce Percent double percent = 1; if (retVal.Count > 0) { double torque = retVal.Sum(o => o.Item2); // A=F/M //double accel = torque / (Vector3D.DotProduct(inertia.Inertia, axis) * inertia.Mass); double accel = torque / Math.Abs(Vector3D.DotProduct(inertia.Inertia, axis)); if (accel > maxAcceleration) { percent = maxAcceleration / accel; } } #endregion return retVal.Select(o => new ThrusterSetting(o.Item1.Thruster, o.Item1.Index, percent)).ToArray(); // commiting to array so that this linq isn't rerun each time it's iterated over }
/// <summary> /// This overload will cut back the returned percents if the thrusters exceed the acceleration passed in /// </summary> private static IEnumerable<ThrusterSetting> EnsureThrustKeysBuilt_Linear(Vector3D direction, ThrustContribution[] contributions, double maxAcceleration, double mass) { direction = direction.ToUnit(); // doing this so the dot product can be used as a percent List<Tuple<ThrustContribution, double>> retVal = new List<Tuple<ThrustContribution, double>>(); // Get a list of thrusters that will contribute to the direction foreach (ThrustContribution contribution in contributions) { double dot = Vector3D.DotProduct(contribution.TranslationForceUnit, direction); if (dot > .05d) { retVal.Add(Tuple.Create(contribution, contribution.TranslationForceLength * dot)); } } retVal = FilterThrusts(retVal); #region Reduce Percent double percent = 1; if (retVal.Count > 0) { double force = retVal.Sum(o => o.Item2); //F=MA, A=F/M double accel = force / mass; if (accel > maxAcceleration) { percent = maxAcceleration / accel; } } #endregion return retVal.Select(o => new ThrusterSetting(o.Item1.Thruster, o.Item1.Index, percent)).ToArray(); // commiting to array so that this linq isn't rerun each time it's iterated over }
private static IEnumerable<ThrusterSetting> EnsureThrustKeysBuilt_Rotate(Vector3D torque, ThrustContribution[] contributions) { torque = torque.ToUnit(); // doing this so the dot product can be used as a percent List<Tuple<ThrustContribution, double>> retVal = new List<Tuple<ThrustContribution, double>>(); // Get a list of thrusters that will contribute to the direction foreach (ThrustContribution contribution in contributions) { double dot = Vector3D.DotProduct(contribution.TorqueUnit, torque); if (dot > .5d) { retVal.Add(Tuple.Create(contribution, contribution.TorqueLength * dot)); } //if (dot > .05d) //{ // retVal.Add(new ThrusterSetting(thruster, cntr, dot)); // for now, use the dot as the percent //} } retVal = FilterThrusts(retVal, .05); return retVal.Select(o => new ThrusterSetting(o.Item1.Thruster, o.Item1.Index, 1)).ToArray(); // commiting to array so that this linq isn't rerun each time it's iterated over }