public static double MinimumTheoreticalEbN0(double SpectralEfficiency) { // Given SpectralEfficiency in bits/sec/Hz (= Channel Capacity / Bandwidth) // Solve Shannon Hartley for Eb/N0 >= (2^(C/B) - 1) / (C/B) return(RATools.LogScale(Math.Pow(2, SpectralEfficiency) - 1) / SpectralEfficiency); // 1=> 0dB, 2=> 1.7dB, 3=> 3.7dB, 4=> 5.7dB, 5=> 8dB, 6=> 10.2dB, 7=> 12.6dB, 8=> 15dB // 9=> 17.6dB, 10=> 20.1dB, 11=> 22.7dB, 20=> 47.2dB // 0.5 => -0.8dB. Rate 1/2 BPSK Turbo code is EbN0 = +1dB, so about 1.8 above Shannon? }
public static double GainFromReference(double refGain, double refFreq, double newFreq) { double gain = 0; if (refGain > 0) { gain = refGain; gain += (refGain <= RealAntenna.MaxOmniGain) ? 0 : RATools.LogScale(newFreq / refFreq); } return(gain); }
public static double GainFromDishDiamater(double diameter, double freq, double efficiency = 1) { double gain = 0; if (diameter > 0 && efficiency > 0) { double wavelength = Physics.c / freq; gain = RATools.LogScale(9.87 * efficiency * diameter * diameter / (wavelength * wavelength)); } return(gain); }
public static float GainFromReference(float refGain, float refFreq, float newFreq) { float gain = 0; if (refGain > 0) { gain = refGain; gain += (refGain <= MaxOmniGain) ? 0 : RATools.LogScale(newFreq / refFreq); } return(gain); }
public static float GainFromDishDiamater(float diameter, float freq, float efficiency = 1) { float gain = 0; if (diameter > 0 && efficiency > 0) { float wavelength = Physics.c / freq; gain = RATools.LogScale(9.87f * efficiency * diameter * diameter / (wavelength * wavelength)); } return(gain); }
private bool BestPeerModulator(RealAntenna rx, out double modRate, out double codeRate) { RealAntennaDigital tx = this; Antenna.Encoder encoder = Antenna.Encoder.BestMatching(tx.Encoder, rx.Encoder); codeRate = encoder.CodingRate; modRate = 0; if (!(rx is RealAntennaDigital)) { return(false); } if (!Compatible(rx)) { return(false); } if ((tx.Parent is ModuleRealAntenna) && !tx.Parent.CanComm()) { return(false); } if ((rx.Parent is ModuleRealAntenna) && !rx.Parent.CanComm()) { return(false); } Vector3 toSource = rx.Position - tx.Position; double distance = toSource.magnitude; RAModulator txMod = tx.modulator, rxMod = (rx as RealAntennaDigital).modulator; if ((distance < tx.MinimumDistance) || (distance < rx.MinimumDistance)) { return(false); } if (!txMod.Compatible(rxMod)) { return(false); } int maxBits = Math.Min(txMod.ModulationBits, rxMod.ModulationBits); double maxSymbolRate = Math.Min(txMod.SymbolRate, rxMod.SymbolRate); double minSymbolRate = Math.Max(txMod.MinSymbolRate, rxMod.MinSymbolRate); double RxPower = Physics.ReceivedPower(tx, rx, distance, tx.Frequency); double temp = Physics.NoiseTemperature(rx, tx.Position); double N0 = Physics.NoiseSpectralDensity(temp); // In dBm double minEb = encoder.RequiredEbN0 + N0; // in dBm double maxBitRateLog = RxPower - minEb; // in dB*Hz double maxBitRate = RATools.LinearScale(maxBitRateLog); /* * Vessel tv = (tx.ParentNode as RACommNode).ParentVessel; * Vessel rv = (rx.ParentNode as RACommNode).ParentVessel; * if (tv != null && rv != null) * { * string debugStr = $"{ModTag} {tx} to {rx} RxP {RxPower:F2} vs temp {temp:F2}. NSD {N0:F1}, ReqEb/N0 {encoder.RequiredEbN0:F1} -> minEb {minEb:F1} gives maxRate {RATools.PrettyPrint(maxBitRate)}bps vs symbol rates {RATools.PrettyPrint(minSymbolRate)}Sps-{RATools.PrettyPrint(maxSymbolRate)}Sps"; * Debug.Log(debugStr); * } */ // We cannot slow our modulation enough to achieve the required Eb/N0, so fail. if (maxBitRate < minSymbolRate) { return(false); } double targetRate; int negotiatedBits; if (maxBitRate <= maxSymbolRate) { // The required Eb/N0 occurs at a lower symbol rate than we are capable of at 1 bit/sec/Hz. // Step down the symbol rate and modulate at 1 bit/sec/Hz (BPSK). // (What if the modulator only supports schemes with >1 bits/symbol?) // (Then our minimum EbN0 is an underestimate.) float ratio = Convert.ToSingle(maxBitRate / maxSymbolRate); double log2 = Math.Floor(Mathf.Log(ratio, 2)); targetRate = maxSymbolRate * Math.Pow(2, log2); negotiatedBits = 1; //debugStr += $" Selected rate {RATools.PrettyPrint(targetRate)}bps (MaxSymbolRate * log2 {log2})"; } else { // We need to go to SNR here and rely a bit more on Shannon-Hartley double Noise = N0 + RATools.LogScale(maxSymbolRate); double CI = RxPower - Noise; double margin = CI - encoder.RequiredEbN0; targetRate = maxSymbolRate; negotiatedBits = Math.Min(maxBits, Convert.ToInt32(1 + Math.Floor(margin / 3))); //debugStr += $" Noise {Noise:F2} CI {CI:F2} margin {margin:F1}"; } modRate = targetRate * negotiatedBits; //Debug.LogFormat(debugStr); return(true); // Energy/bit (Eb) = Received Power / datarate // N0 = Noise Spectral Density = K*T // Noise = N0 * BW // SNR = RxPower / Noise = RxPower / (N0 * BW) = Eb*datarate / N0*BW = (Eb/N0) * (datarate/BW) // I < B * log(1 + S/N) where I = information rate, B=Bandwidth, S=Total Power, N=Total Noise Power = N0*B // // Es/N0 = (Total Power / Symbol Rate) / N0 // = Eb/N0 * log(modulation order) }