//------------------------------------------------------------------------------ // transmitDataMessage() -- send a data message emission; // returns true if the data emission was sent. //------------------------------------------------------------------------------ bool CommRadio::transmitDataMessage(base::Object* const msg) { bool sent = false; // Transmitting, scanning and have an antenna? if(getOwnship() == nullptr) { if (isMessageEnabled(MSG_DEBUG)) { std::cout << "CommRadio ownship == nullptr!" << std::endl; } return sent; } if (msg != nullptr && isTransmitterEnabled() && getAntenna() != nullptr) { // Send the emission to the other player Emission* em = new Emission(); em->setDataMessage(msg); em->setFrequency(getFrequency()); em->setBandwidth(getBandwidth()); em->setPower(getPeakPower()); em->setTransmitLoss(getRfTransmitLoss()); em->setMaxRangeNM(getMaxDetectRange()); em->setTransmitter(this); em->setReturnRequest(false); getAntenna()->rfTransmit(em); em->unref(); sent = true; } return sent; }
void RfSystem::reset() { BaseClass::reset(); // --- // Do we need to find the antenna? // --- if (getAntenna() == 0 && getAntennaName() != 0 && getOwnship() != 0) { // We have a name of the antenna, but not the antenna it's self const char* name = *getAntennaName(); // Get the named antenna from the player's list of gimbals, antennas and optics Antenna* p = dynamic_cast<Antenna*>( getOwnship()->getGimbalByName(name) ); if (p != 0) { setAntenna( p ); getAntenna()->setSystem(this); } if (getAntenna() == 0) { // The assigned antenna was not found! std::cerr << "RfSystem::reset() ERROR -- antenna: " << name << ", was not found!" << std::endl; setSlotAntennaName(0); } } // --- // Initialize players of interest // --- processPlayersOfInterest(); }
//------------------------------------------------------------------------------ // transmit() -- send radar emissions //------------------------------------------------------------------------------ void Radar::transmit(const LCreal dt) { BaseClass::transmit(dt); // Transmitting, scanning and have an antenna? if ( !areEmissionsDisabled() && isTransmitting() ) { // Send the emission to the other player Emission* em = new Emission(); em->setFrequency(getFrequency()); em->setBandwidth(getBandwidth()); const LCreal prf1 = getPRF(); em->setPRF(prf1); int pulses = static_cast<int>(prf1 * dt + 0.5); if (pulses == 0) pulses = 1; // at least one em->setPulses(pulses); const LCreal p = getPeakPower(); em->setPower(p); em->setMaxRangeNM(getRange()); em->setPulseWidth(getPulseWidth()); em->setTransmitLoss(getRfTransmitLoss()); em->setReturnRequest( isReceiverEnabled() ); em->setTransmitter(this); getAntenna()->rfTransmit(em); em->unref(); } }
//------------------------------------------------------------------------------ // Process players of interest -- This will work with the function in Gimbal to create // a filtered list of players that we plan to send emission packets to. //------------------------------------------------------------------------------ void RfSystem::processPlayersOfInterest() { // --- // Do we have an antenna? // --- if (getAntenna() != 0) { // Pass our players of interest to the antenna for processing Basic::PairStream* poi = 0; Simulation* sim = getSimulation(); if ( sim != 0 && !areEmissionsDisabled() ) { poi = sim->getPlayers(); } getAntenna()->processPlayersOfInterest(poi); if (poi != 0) { poi->unref(); poi = 0; } } }
//------------------------------------------------------------------------------ // process() -- //------------------------------------------------------------------------------ void Sar::process(const LCreal dt) { BaseClass::process(dt); // Imaging in porgress? if (timer > 0) { // --- // Point the beam // --- Antenna* ant = getAntenna(); if (ant != 0) { Simulation* s = getSimulation(); double refLat = s->getRefLatitude(); double refLon = s->getRefLongitude(); osg::Vec3 pos; Basic::Nav::convertLL2PosVec( refLat, refLon, // Ref point (at sea level) getStarePointLatitude(), getStarePointLongitude(), getStarePointElevation(), &pos); // x,y,z NED // Platform (ownship) coord and then body osg::Vec3 posP = pos - getOwnship()->getPosition(); osg::Vec3 posB = getOwnship()->getRotMat() * posP; // Convert to az/el LCreal tgt_az = 0.0; // Angle (degs) LCreal tgt_el = 0.0; // Angle (degs) xyz2AzEl(posB, &tgt_az, &tgt_el); // Command to that position LCreal az = tgt_az * (LCreal)Basic::Angle::D2RCC; LCreal el = tgt_el * (LCreal)Basic::Angle::D2RCC; ant->setRefAzimuth(az); ant->setRefElevation(el); ant->setScanMode(Antenna::CONICAL_SCAN); } // --- // Process timer // --- LCreal ttimer = timer - dt; if (ttimer <= 0) { // ### test -- Generate a test image ### Image* p = new Image(); p->testImage(width,height); p->setImageId(getNextId()); p->setLatitude(getStarePointLatitude()); p->setLongitude(getStarePointLongitude()); p->setElevation(getStarePointElevation()); p->setOrientation(0); if (isMessageEnabled(MSG_INFO)) { std::cout << "Sar:: Generating test image: resolution: " << getResolution() << std::endl; } if (getResolution() > 0) p->setResolution( getResolution() ); else p->setResolution( 3.0f * Basic::Distance::FT2M ); Basic::Pair* pp = new Basic::Pair("image", p); addImage(pp); // ### TEST TEST // Just finished! ttimer = 0; setTransmitterEnableFlag(false); } timer = ttimer; } BaseClass::updateData(dt); }
//------------------------------------------------------------------------------ // receive() -- process received emissions //------------------------------------------------------------------------------ void Radar::receive(const LCreal dt) { BaseClass::receive(dt); // Can't do anything without an antenna if (getAntenna() == nullptr) return; // Clear the next sweep csweep = computeSweepIndex( static_cast<LCreal>(Basic::Angle::R2DCC * getAntenna()->getAzimuth()) ); clearSweep(csweep); // Compute noise level // CGB moved here from RfSystem // Basically, we're simulation Hannen's S/I equation from page 356 of his notes. // Where I is N + J. J is noise from jamming. // Receiver Loss affects the total I, so we have to wait until this point to account for it. const LCreal interference = (getRfRecvNoise() + jamSignal) * getRfReceiveLoss(); const LCreal noise = getRfRecvNoise() * getRfReceiveLoss(); currentJamSignal = jamSignal * getRfReceiveLoss(); int countNumJammedEm = 0; // --- // Process Returned Emissions // --- Emission* em = nullptr; LCreal signal = 0; // Get an emission from the queue lcLock(packetLock); if (np > 0) { np--; // Decrement 'np', now the array index em = packets[np]; signal = signals[np]; } lcUnlock(packetLock); while (em != nullptr) { // exclude noise jammers (accounted for already in RfSystem::rfReceivedEmission) if (em->getTransmitter() == this || (em->isECM() && !em->isECMType(Emission::ECM_NOISE)) ) { // compute the return trip loss ... // Compute signal received LCreal rcs = em->getRCS(); // Signal Equation (Equation 2-7) LCreal rl = em->getRangeLoss(); signal *= (rcs * rl); // Integration gain signal *= rfIGain; // Range attenuation: we don't want the strong signal from short range targets LCreal maxRng = getRange() * Basic::Distance::NM2M; //LCreal maxRng4 = (maxRng*maxRng*maxRng*maxRng); //LCreal rng = (em->getRange()); const LCreal s1 = 1.0; //if (rng > 0) { // LCreal rng4 = (rng*rng*rng*rng); // s1 = (rng4/maxRng4); // if (s1 > 1.0f) s1 = 1.0f; //} signal *= s1; if (signal > 0.0) { // Signal/Noise (Equation 2-9) const LCreal signalToInterferenceRatio = signal / interference; const LCreal signalToInterferenceRatioDbl = 10.0f * lcLog10(signalToInterferenceRatio); const LCreal signalToNoiseRatio = signal / noise; const LCreal signalToNoiseRatioDbl = 10.0f * lcLog10(signalToNoiseRatio); //std::cout << "Radar::receive(" << em->getTarget() << "): "; //std::cout << " pwr=" << em->getPower(); //std::cout << " gain=" << em->getGain(); //std::cout << " rl=" << rl; //std::cout << " rcs=" << rcs; //std::cout << " signal=" << signal; //std::cout << " recvN=" << getRfRecvNoise(); //std::cout << " signalToInterferenceRatio=" << signalToInterferenceRatio; //std::cout << " signalToInterferenceRatioDbl=" << signalToInterferenceRatioDbl; //std::cout << " thrs=" << getRfThreshold(); //std::cout << std::endl; // Is S/N above receiver threshold and within 125% of max range? // CGB, if "signal <= 0.0", then "signalToInterferenceRatioDbl" is probably invalid // we should probably do something smart with "signalToInterferenceRatioDbl" above as well. lcLock(myLock); if (signalToInterferenceRatioDbl >= getRfThreshold() && em->getRange() <= (maxRng*1.25) && rptQueue.isNotFull()) { // send the report to the track manager em->ref(); rptQueue.put(em); rptSnQueue.put(signalToInterferenceRatioDbl); //std::cout << " (" << em->getRange() << ", " << signalToInterferenceRatioDbl << ", " << signalToInterferenceRatio << ", " << signalToInterferenceRatioDbl << ")"; // Save signal for real-beam display int iaz = csweep; int irng = computeRangeIndex( em->getRange() ); sweeps[iaz][irng] += (signalToInterferenceRatioDbl/100.0f); vclos[iaz][irng] = em->getRangeRate(); } else if (signalToInterferenceRatioDbl < getRfThreshold() && signalToNoiseRatioDbl >= getRfThreshold()) { countNumJammedEm++; } lcUnlock(myLock); } } em->unref(); // this unref() undoes the ref() done by RfSystem::rfReceivedEmission em = nullptr; //if (np >= 0 && np < MAX_EMISSIONS) { // packets[np] = 0; // signals[np] = 0; //} // Get another emission from the queue lcLock(packetLock); if (np > 0) { np--; em = packets[np]; signal = signals[np]; } lcUnlock(packetLock); } //std::cout << std::endl; numberOfJammedEmissions = countNumJammedEm; // Set interference signal back to zero jamSignal = 0; }
//------------------------------------------------------------------------------ // transmit() -- send radar emissions //------------------------------------------------------------------------------ void RealBeamRadar::transmit(const LCreal dt) { BaseClass::transmit(dt); // Test parameters double latitude = 0; double longitude = 0; beamWidth = 7.0; // const Simulation::Player* own = getOwnship(); if (own != nullptr) { // Get our ownship parameters altitude = static_cast<LCreal>(own->getAltitude()); latitude = own->getLatitude(); longitude = own->getLongitude(); // Locate the terrain elevation database if (terrain == nullptr) { const Simulation::Simulation* sim = own->getSimulation(); if (sim != nullptr) { setTerrain( sim->getTerrain() ); } } } // Transmitting, scanning const Simulation::Antenna* ant = getAntenna(); if (isTransmitting() && ant != nullptr && image != nullptr && terrain != nullptr && terrain->isDataLoaded()) { // Compute max range (NM) LCreal maxRngNM = getRange(); // Compute ground range LCreal groundRange[IMG_HEIGHT]; computeGroundRanges(groundRange, IMG_HEIGHT, maxRngNM); // Compute slant range LCreal slantRange2[IMG_HEIGHT]; computeSlantRanges2(slantRange2, IMG_HEIGHT, groundRange, altitude); // Compute the loss from range LCreal rangeLoss[IMG_HEIGHT]; computeRangeLoss(rangeLoss, IMG_HEIGHT, slantRange2); // Compute the earth's curvature effect LCreal curvature[IMG_HEIGHT]; computeEarthCurvature(curvature, IMG_HEIGHT, maxRngNM, static_cast<LCreal>(Basic::Nav::ERAD60)); LCreal hue = 120.0; // see Hsv LCreal saturation = 0.0; // see Hsv const Basic::Hsva* grayTable[19]; grayTable[0] = new Basic::Hsva( hue, saturation, 0.0f, 1.0f ); grayTable[1] = new Basic::Hsva( hue, saturation, 0.0872f, 1.0f ); grayTable[2] = new Basic::Hsva( hue, saturation, 0.1736f, 1.0f ); grayTable[3] = new Basic::Hsva( hue, saturation, 0.2588f, 1.0f ); grayTable[4] = new Basic::Hsva( hue, saturation, 0.3420f, 1.0f ); grayTable[5] = new Basic::Hsva( hue, saturation, 0.4226f, 1.0f ); grayTable[6] = new Basic::Hsva( hue, saturation, 0.5000f, 1.0f ); grayTable[7] = new Basic::Hsva( hue, saturation, 0.5736f, 1.0f ); grayTable[8] = new Basic::Hsva( hue, saturation, 0.6428f, 1.0f ); grayTable[9] = new Basic::Hsva( hue, saturation, 0.7071f, 1.0f ); grayTable[10] = new Basic::Hsva( hue, saturation, 0.7660f, 1.0f ); grayTable[11] = new Basic::Hsva( hue, saturation, 0.8192f, 1.0f ); grayTable[12] = new Basic::Hsva( hue, saturation, 0.8660f, 1.0f ); grayTable[13] = new Basic::Hsva( hue, saturation, 0.9063f, 1.0f ); grayTable[14] = new Basic::Hsva( hue, saturation, 0.9397f, 1.0f ); grayTable[15] = new Basic::Hsva( hue, saturation, 0.9659f, 1.0f ); grayTable[16] = new Basic::Hsva( hue, saturation, 0.9848f, 1.0f ); grayTable[17] = new Basic::Hsva( hue, saturation, 0.9962f, 1.0f ); grayTable[18] = new Basic::Hsva( hue, saturation, 1.0f, 1.0f ); // Get antenna look angles antAzAngle = static_cast<LCreal>(ant->getAzimuthD()); antElAngle = static_cast<LCreal>(ant->getElevationD()); // Which ray are we on? LCreal halfRay = static_cast<LCreal>(IMG_WIDTH/2.0f); int ray = static_cast<int>(((antAzAngle/45.0f) * halfRay) + halfRay); if (ray < 0) ray = 0; if (ray > (IMG_WIDTH-1)) ray = (IMG_WIDTH-1); if (fpass) { ray0 = ray; fpass = false; } // --- // For all rays from ray0 to our current ray // --- int icol = ray0; while (icol != ray) { for (int irow = 0; irow < IMG_HEIGHT; irow++) { elevations[irow] = 0; aacData[irow] = 1.0; validFlgs[irow] = false; maskFlgs[irow] = false; } // Direction int xx = icol - (IMG_WIDTH/2); LCreal direction = 45.0 * static_cast<LCreal>(xx) / static_cast<LCreal>(IMG_WIDTH/2); // get a strip of elevations from south to north unsigned int num = terrain->getElevations(elevations, validFlgs, IMG_HEIGHT, latitude, longitude, direction, groundRange[IMG_HEIGHT-1], interpolate); // Apply earth curvature effects to terrain elevations for (int irow = 0; irow < IMG_HEIGHT; irow++) { elevations[irow] -= curvature[irow]; } // Generate Masks Basic::Terrain::vbwShadowChecker(maskFlgs, elevations, validFlgs, IMG_HEIGHT, groundRange[IMG_HEIGHT-1], altitude, antElAngle, beamWidth); // Compute AAC data Basic::Terrain::aac(aacData, elevations, maskFlgs, IMG_HEIGHT, groundRange[IMG_HEIGHT-1], altitude); // Draw a line along the Y points (moving from south to north along the latitude lines) for (int irow = 0; irow < IMG_HEIGHT; irow++) { LCreal sn = aacData[irow]; // convert to a color (or gray) value osg::Vec3 color(0,0,0); if (validFlgs[irow] && !maskFlgs[irow]) { Basic::Terrain::getElevationColor(sn, 0.0, 1.0, grayTable, 19, color); } // store this color int idx = irow*imgWidth*PIXEL_SIZE + icol*PIXEL_SIZE; image[idx+0] = static_cast<unsigned char>( 255.0 * color[0] ); image[idx+1] = static_cast<unsigned char>( 255.0 * color[1] ); image[idx+2] = static_cast<unsigned char>( 255.0 * color[2] ); } if (icol < ray) icol++; else if (icol > ray) icol--; } ray0 = ray; } }
// Returns true if the R/F system is transmitting bool RfSystem::isTransmitting() const { // Default: if we're enabled and have an antenna, we're transmitting. return ( isTransmitterEnabled() && getAntenna() != 0 && getOwnship() != 0 ); }