📄 channelmodel.java
字号:
* Destination position Y * @return Received signal strength (dBm) random variable. The first value is * the random variable mean, and the second is the variance. */ public double[] getReceivedSignalStrength(double sourceX, double sourceY, double destX, double destY) { return getTransmissionData(sourceX, sourceY, destX, destY, TransmissionData.SIGNAL_STRENGTH); } // TODO Fix better data type support private double[] getTransmissionData(double sourceX, double sourceY, double destX, double destY, TransmissionData dataType) { Point2D source = new Point2D.Double(sourceX, sourceY); Point2D dest = new Point2D.Double(destX, destY); double accumulatedVariance = 0; // - Get all ray paths from source to destination - RayData originRayData = new RayData( RayData.RayType.ORIGIN, source, null, getParameterIntegerValue("rt_max_rays"), getParameterIntegerValue("rt_max_refractions"), getParameterIntegerValue("rt_max_reflections"), getParameterIntegerValue("rt_max_diffractions") ); // TODO Current (changing) signal strength should be built into 'build visible lines' to speed up things! // Check if origin tree is already calculated and saved DefaultMutableTreeNode visibleLinesTree = null; visibleLinesTree = buildVisibleLinesTree(originRayData); // Calculate all paths from source to destination, using above calculated tree Vector<RayPath> allPaths = getConnectingPaths(source, dest, visibleLinesTree); if (inLoggingMode) { logger.info("Saved rays:"); Enumeration<RayPath> pathsEnum = allPaths.elements(); while (pathsEnum.hasMoreElements()) { RayPath currentPath = pathsEnum.nextElement(); logger.info("* " + currentPath); for (int i=0; i < currentPath.getSubPathCount(); i++) { savedRays.add(currentPath.getSubPath(i)); } } } // - Extract length and losses of each path - double[] pathLengths = new double[allPaths.size()]; double[] pathGain = new double[allPaths.size()]; int bestSignalNr = -1; double bestSignalPathLoss = 0; for (int i=0; i < allPaths.size(); i++) { RayPath currentPath = allPaths.get(i); double accumulatedStraightLength = 0; for (int j=0; j < currentPath.getSubPathCount(); j++) { Line2D subPath = currentPath.getSubPath(j); double subPathLength = subPath.getP1().distance(subPath.getP2()); RayData.RayType subPathStartType = currentPath.getType(j); // Type specific losses // TODO Type specific losses depends on angles as well! if (subPathStartType == RayData.RayType.REFRACTION) { pathGain[i] += getParameterDoubleValue("rt_refrac_coefficient"); } else if (subPathStartType == RayData.RayType.REFLECTION) { pathGain[i] += getParameterDoubleValue("rt_reflec_coefficient"); // Add FSPL from last subpaths (if FSPL on individual rays) if (!getParameterBooleanValue("rt_fspl_on_total_length") && accumulatedStraightLength > 0) { pathGain[i] += getFSPL(accumulatedStraightLength); } accumulatedStraightLength = 0; // Reset straight length } else if (subPathStartType == RayData.RayType.DIFFRACTION) { pathGain[i] += getParameterDoubleValue("rt_diffr_coefficient"); // Add FSPL from last subpaths (if FSPL on individual rays) if (!getParameterBooleanValue("rt_fspl_on_total_length") && accumulatedStraightLength > 0) { pathGain[i] += getFSPL(accumulatedStraightLength); } accumulatedStraightLength = 0; // Reset straight length } accumulatedStraightLength += subPathLength; // Add length, FSPL should be calculated on total straight length // If ray starts with a refraction, calculate obstacle attenuation if (subPathStartType == RayData.RayType.REFRACTION) { // Ray passes through a wall, calculate distance through that wall // Fetch attenuation constant double attenuationConstant = getParameterDoubleValue("obstacle_attenuation"); Vector<Rectangle2D> allPossibleObstacles = myObstacleWorld.getAllObstaclesNear(subPath.getP1()); for (int k=0; k < allPossibleObstacles.size(); k++) { Rectangle2D obstacle = allPossibleObstacles.get(k); // Calculate the intersection distance Line2D line = getIntersectionLine( subPath.getP1().getX(), subPath.getP1().getY(), subPath.getP2().getX(), subPath.getP2().getY(), obstacle ); if (line != null) { pathGain[i] += attenuationConstant * line.getP1().distance(line.getP2()); break; } } } // Add to total path length pathLengths[i] += subPathLength; } // Add FSPL from last rays (if FSPL on individual rays) if (!getParameterBooleanValue("rt_fspl_on_total_length") && accumulatedStraightLength > 0) { pathGain[i] += getFSPL(accumulatedStraightLength); } // Free space path loss on total path length? if (getParameterBooleanValue("rt_fspl_on_total_length")) { pathGain[i] += getFSPL(pathLengths[i]); } if (bestSignalNr < 0 || pathGain[i] > bestSignalPathLoss) { bestSignalNr = i; bestSignalPathLoss = pathGain[i]; } } // - Calculate total path loss (using simple Rician) - double[] pathModdedLengths = new double[allPaths.size()]; double delaySpread = 0; double delaySpreadRMS = 0; double wavelength = getParameterDoubleValue("wavelength"); double totalPathGain = 0; double delaySpreadTotalWeight = 0; double speedOfLight = 300; // Approximate value (m/us) for (int i=0; i < pathModdedLengths.length; i++) { // Ignore insignificant interfering signals if (pathGain[i] > pathGain[bestSignalNr] - 30) { double pathLengthDiff = Math.abs(pathLengths[i] - pathLengths[bestSignalNr]); // Update delay spread TODO Now considering best signal, should be first or mean? if (pathLengthDiff > delaySpread) delaySpread = pathLengthDiff; // Update root-mean-square delay spread TODO Now considering best signal time, should be mean delay? delaySpreadTotalWeight += pathGain[i]*pathGain[i]; double rmsDelaySpreadComponent = pathLengthDiff/speedOfLight; rmsDelaySpreadComponent *= rmsDelaySpreadComponent * pathGain[i]*pathGain[i]; delaySpreadRMS += rmsDelaySpreadComponent; // OK since cosinus is even function pathModdedLengths[i] = pathLengthDiff % wavelength; // Using Rician fading approach, TODO Only one best signal considered - combine these? (need two limits) totalPathGain += Math.pow(10, pathGain[i]/10.0)*Math.cos(2*Math.PI * pathModdedLengths[i]/wavelength); if (inLoggingMode) { logger.info("Adding ray path with gain " + pathGain[i] + " and phase " + (2*Math.PI * pathModdedLengths[i]/wavelength)); } } else if (inLoggingMode) { pathModdedLengths[i] = (pathLengths[i] - pathLengths[bestSignalNr]) % wavelength; logger.info("Not adding ray path with gain " + pathGain[i] + " and phase " + (2*Math.PI * pathModdedLengths[i]/wavelength)); } } // Calculate resulting RMS delay spread delaySpread /= speedOfLight; delaySpreadRMS /= delaySpreadTotalWeight; // Convert back to dB totalPathGain = 10*Math.log10(Math.abs(totalPathGain)); if (inLoggingMode) { logger.info("Total path gain:\t" + totalPathGain); logger.info("Delay spread:\t" + delaySpread); logger.info("RMS Delay spread:\t" + delaySpreadRMS); } // - Calculate received power - // Using formula (dB) // Received power = Output power + System gain + Transmitter gain + Path Loss + Receiver gain // TODO Update formulas Random random = new Random(); double outputPower = getParameterDoubleValue("tx_power"); double systemGain = getParameterDoubleValue("system_gain_mean"); if (getParameterBooleanValue("apply_random")) { systemGain += Math.sqrt(getParameterDoubleValue("system_gain_var")) * random.nextGaussian(); } else { accumulatedVariance += getParameterDoubleValue("system_gain_var"); } double transmitterGain = getParameterDoubleValue("tx_antenna_gain"); // TODO Should depend on angle double receivedPower = outputPower + systemGain + transmitterGain + totalPathGain; if (inLoggingMode) { logger.info("Resulting received signal strength:\t" + receivedPower + " (" + accumulatedVariance + ")"); } if (dataType == TransmissionData.DELAY_SPREAD || dataType == TransmissionData.DELAY_SPREAD_RMS) return new double[] {delaySpread, delaySpreadRMS}; return new double[] {receivedPower, accumulatedVariance}; } /** * Returns all rays from given source to given destination if a transmission * were to be made. The resulting rays depend on the current settings and may * include rays through obstacles, reflected rays or scattered rays. * * @param sourceX Source position X * @param sourceY Source position Y * @param destX Destination position X * @param destY Destination position Y * @return All resulting rays of a simulated transmission from source to destination */ public Vector<Line2D> getRaysOfTransmission(double sourceX, double sourceY, double destX, double destY) { // Reset current rays vector inLoggingMode = true; savedRays = new Vector<Line2D>(); // Calculate rays, ignore power getProbability(sourceX, sourceY, destX, destY, -Double.MAX_VALUE); inLoggingMode = false; return savedRays; } /** * Calculates and returns the signal to noise ratio (dB) of a signal sent from * the given source position to the given destination position as a random * variable. This method uses current parameters such as transmitted power, * obstacles, overall system loss etc. * * @param sourceX * Source position X * @param sourceY * Source position Y * @param destX * Destination position X * @param destY * Destination position Y * @return Received SNR (dB) random variable. The first value is the random * variable mean, and the second is the variance. The third value is the received signal strength which may be used in comparison with interference etc. */ public double[] getSINR(double sourceX, double sourceY, double destX, double destY, double interference) { // Calculate received signal strength double[] signalStrength = getReceivedSignalStrength(sourceX, sourceY, destX, destY); double[] snrData = new double[] { signalStrength[0], signalStrength[1], signalStrength[0] }; // Add antenna gain TODO Should depend on angle snrData[0] += getParameterDoubleValue("rx_antenna_gain"); double noiseVariance = getParameterDoubleValue("bg_noise_var"); double noiseMean = getParameterDoubleValue("bg_noise_mean"); if (interference > noiseMean) noiseMean = interference; if (getParameterBooleanValue("apply_random")) { noiseMean += Math.sqrt(noiseVariance) * random.nextGaussian(); noiseVariance = 0; } // Applying noise to calculate SNR snrData[0] -= noiseMean; snrData[1] += noiseVariance; if (inLoggingMode) { logger.info("SNR at receiver:\t" + snrData[0] + " (" + snrData[1] + ")"); } return snrData; } /** * Calculates and returns probability that a receiver at given destination receives a packet from a transmitter at given source. * This method uses current parameters such as transmitted power, * obstacles, overall system loss, packet size etc. TODO Packet size?! TODO Interfering signal strength * * @param sourceX * Source position X * @param sourceY * Source position Y * @param destX * Destination position X * @param destY * Destination position Y * @param interference * Current interference at destination (dBm) * @return [Probability of reception, signal strength at destination] */ public double[] getProbability(double sourceX, double sourceY, double destX, double destY, double interference) { double[] snrData = getSINR(sourceX, sourceY, destX, destY, interference); double snrMean = snrData[0]; double snrVariance = snrData[1]; double signalStrength = snrData[2]; double threshold = getParameterDoubleValue("snr_threshold"); double rxSensitivity = getParameterDoubleValue("rx_sensitivity"); // Check signal strength against receiver sensitivity and interference if (rxSensitivity > signalStrength - snrMean && threshold < rxSensitivity + snrMean - signalStrength) { if (inLoggingMode) { logger.info("Signal to low for receiver sensitivity, increasing threshold"); } // Keeping snr variance but increasing theshold to sensitivity threshold = rxSensiti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -