void HclSmartBearing_CalPacket::parseSweeps() { typedef WirelessChannel WC; //read the values from the payload uint8 sensorErrorMask = m_payload.read_uint8(PAYLOAD_OFFSET_ERROR_MASK); uint8 sampleRate = m_payload.read_uint8(PAYLOAD_OFFSET_SAMPLE_RATE); uint16 tick = m_payload.read_uint16(PAYLOAD_OFFSET_TICK); uint64 timestampSeconds = m_payload.read_uint32(PAYLOAD_OFFSET_TS_SEC); //the timestamp (UTC) seconds part uint64 timestampNanos = m_payload.read_uint32(PAYLOAD_OFFSET_TS_NANOSEC); //the timestamp (UTC) nanoseconds part //build the full nanosecond resolution timestamp from the seconds and nanoseconds values read above uint64 realTimestamp = (timestampSeconds * TimeSpan::NANOSECONDS_PER_SECOND) + timestampNanos; //create a SampleRate object from the sampleRate byte SampleRate currentRate = SampleUtils::convertToSampleRate(sampleRate); //build the single sweep DataSweep sweep; sweep.samplingType(DataSweep::samplingType_SyncSampling); sweep.frequency(m_frequency); sweep.tick(tick); sweep.nodeAddress(m_nodeAddress); sweep.sampleRate(currentRate); sweep.timestamp(Timestamp(realTimestamp)); sweep.nodeRssi(m_nodeRSSI); sweep.baseRssi(m_baseRSSI); sweep.calApplied(true); static const uint16 DATA_START = 13; ChannelData chData; chData.reserve(12); chData.emplace_back(WC::channel_error_code, 0, valueType_uint8, anyType(sensorErrorMask)); //Error Mask (not actually in payload) chData.emplace_back(WC::channel_hcl_axialLoadX, 1, valueType_int16, anyType(m_payload.read_int16(DATA_START + 0))); chData.emplace_back(WC::channel_hcl_axialLoadY, 2, valueType_int16, anyType(m_payload.read_int16(DATA_START + 2))); chData.emplace_back(WC::channel_hcl_axialLoadZ, 3, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 4)) * 10)); chData.emplace_back(WC::channel_hcl_bendingMomentFlap, 4, valueType_int16, anyType(m_payload.read_int16(DATA_START + 6))); chData.emplace_back(WC::channel_hcl_bendingMomentLag, 5, valueType_int16, anyType(m_payload.read_int16(DATA_START + 8))); chData.emplace_back(WC::channel_hcl_bendingMomentPitch, 6, valueType_int16, anyType(m_payload.read_int16(DATA_START + 10))); chData.emplace_back(WC::channel_hcl_motionFlap_mag, 7, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 12) / 1000.0))); chData.emplace_back(WC::channel_hcl_motionLag_mag, 8, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 14) / 1000.0))); chData.emplace_back(WC::channel_hcl_motionPitch_mag, 9, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 16) / 1000.0))); chData.emplace_back(WC::channel_hcl_motionFlap_inertial, 10, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 18) / 1000.0))); chData.emplace_back(WC::channel_hcl_motionLag_inertial, 11, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 20) / 1000.0))); chData.emplace_back(WC::channel_hcl_motionPitch_inertial, 12, valueType_float, anyType(static_cast<float>(m_payload.read_int16(DATA_START + 22) / 1000.0))); chData.emplace_back(WC::channel_hcl_cockingStiffness_mag, 13, valueType_int16, anyType(m_payload.read_int16(DATA_START + 24))); chData.emplace_back(WC::channel_hcl_cockingStiffness_inertial, 14, valueType_int16, anyType(m_payload.read_int16(DATA_START + 26))); chData.emplace_back(WC::channel_hcl_temperature, 15, valueType_int16, anyType(static_cast<int16>(m_payload.read_int8(DATA_START + 28)))); //add all of the channel data to the sweep sweep.data(chData); //add the sweep to the container of sweeps addSweep(sweep); }
void DiagnosticPacket::parseSweeps() { DataBuffer payload(m_payload); m_numSweeps = 1; //build the 1 sweep that we need to add DataSweep sweep; sweep.samplingType(DataSweep::samplingType_Diagnostic); sweep.frequency(m_frequency); sweep.nodeAddress(m_nodeAddress); //the data itself is the beacon timestamp. //use this for the current PC time sweep.timestamp(Timestamp::timeNow()); //get this sweep's node and base rssi values sweep.nodeRssi(m_nodeRSSI); sweep.baseRssi(m_baseRSSI); sweep.calApplied(true); //get the packet interval (in seconds) uint16 packetInterval = payload.read_uint16(); sweep.tick(payload.read_uint16()); sweep.sampleRate(SampleRate::Seconds(packetInterval)); size_t numInfoItemBytes = payload.size() - 4; size_t infoByteCounter = 0; ChannelData chData; //iterate over all of the info bytes while(infoByteCounter < numInfoItemBytes) { uint8 infoLen = payload.read_uint8(); uint8 infoId = payload.read_uint8(); addDataPoint(chData, payload, infoLen - 1, infoId); infoByteCounter += (infoLen + 1); } //add the channel data to the sweep sweep.data(chData); //add the sweep to the container of sweeps addSweep(sweep); }
void BufferedLdcPacket::parseSweeps() { //read the values from the payload uint8 channelMask = m_payload.read_uint8(PAYLOAD_OFFSET_CHANNEL_MASK); uint8 sampleRate = m_payload.read_uint8(PAYLOAD_OFFSET_SAMPLE_RATE); uint8 dataType = m_payload.read_uint8(PAYLOAD_OFFSET_DATA_TYPE); uint16 tick = m_payload.read_uint16(PAYLOAD_OFFSET_TICK); //set the data type of the packet m_dataType = static_cast<WirelessTypes::DataType>(dataType); //build the ChannelMask from the channel mask ChannelMask channels(channelMask); //calculate the size of a single sweep m_sweepSize = channels.count() * WirelessTypes::dataTypeSize(m_dataType); //if the sweep size is 0 (no channels active) if(m_sweepSize == 0) { //we only want to insert 1 sweep m_numSweeps = 1; } else { //calculate the number of sweeps in this packet m_numSweeps = (m_payload.size() - PAYLOAD_OFFSET_CHANNEL_DATA) / m_sweepSize; } //if we still have no sweeps, there was an error in the packet if(m_numSweeps == 0) { throw Error("Invalid Packet"); } //build the full nanosecond resolution timestamp from the seconds and nanoseconds values read above uint64 receivedTime = Timestamp::timeNow().nanoseconds(); //create a SampleRate object from the sampleRate byte SampleRate currentRate = SampleUtils::convertToSampleRate(sampleRate); //get the value to increment the timestamp by for each sweep (the timestamp from the packet only applies to the first sweep) const uint64 TS_INCREMENT = currentRate.samplePeriod().getNanoseconds(); //there are multiple sweeps in this packet (buffered) for(uint32 sweepItr = 0; sweepItr < m_numSweeps; sweepItr++) { //build a sweep to add DataSweep sweep; sweep.samplingType(DataSweep::samplingType_NonSync_Buffered); sweep.frequency(m_frequency); sweep.tick(tick++); sweep.nodeAddress(m_nodeAddress); sweep.sampleRate(currentRate); //calculate the timestamp to use for this sweep (last sweep gets PC timestamp, count backwards for the other sweeps) sweep.timestamp(Timestamp(receivedTime - (TS_INCREMENT * (m_numSweeps - (sweepItr + 1))))); //get this sweep's node and base rssi values sweep.nodeRssi(m_nodeRSSI); sweep.baseRssi(m_baseRSSI); //cals applied if the data type is float sweep.calApplied(m_dataType == WirelessTypes::dataType_float32); ChannelData chData; //the index of the channel data int chDataIndex = 0; uint8 lastActiveCh = channels.lastChEnabled(); //loop through all the channels for(uint8 chItr = 1; chItr <= lastActiveCh; ++chItr) { //if the current channel is enabled if(channels.enabled(chItr)) { //insert the data point into the ChannelData object for the wireless channel addDataPoint(chData, (chItr), chDataIndex, sweepItr, wirelessChannelFromChNum(chItr)); chDataIndex++; } } //add the channel data to the sweep sweep.data(chData); //add the sweep to the container of sweeps addSweep(sweep); } }
void AsyncDigitalAnalogPacket::parseSweeps() { const uint32 TS_OFFSET_LEN = 2; //timestamp offset is always 2 bytes const uint32 DIGITAL_LEN = 2; //digital data is always 2 bytes //read the values from the payload uint16 channelMask = m_payload.read_uint16(PAYLOAD_OFFSET_CHANNEL_MASK); uint8 dataType = m_payload.read_uint8(PAYLOAD_OFFSET_DATA_TYPE); uint16 tick = m_payload.read_uint16(PAYLOAD_OFFSET_TICK); uint64 timestampSeconds = m_payload.read_uint32(PAYLOAD_OFFSET_TS_SEC); //the timestamp (UTC) seconds part uint64 timestampNanos = m_payload.read_uint32(PAYLOAD_OFFSET_TS_NANOSEC); //the timestamp (UTC) nanoseconds part //build the full nanosecond resolution timestamp from the seconds and nanoseconds values read above uint64 packetTimestamp = (timestampSeconds * TimeSpan::NANOSECONDS_PER_SECOND) + timestampNanos; //build the ChannelMask from the channel mask ChannelMask channels(channelMask); //set the data type of the packet m_dataType = static_cast<WirelessTypes::DataType>(dataType); //create a sample rate for this data static const SampleRate digitalRate = SampleRate::Event(); std::size_t payloadLen = m_payload.size(); uint16 sweepItr = 0; //find the offset into the payload to get the data uint32 byteItr = PAYLOAD_OFFSET_CHANNEL_DATA; //while there is still more data for us to read while(byteItr < payloadLen) { //build a sweep to add DataSweep sweep; sweep.samplingType(DataSweep::samplingType_AsyncDigitalAnalog); sweep.frequency(m_frequency); sweep.tick(tick++); sweep.nodeAddress(m_nodeAddress); sweep.sampleRate(digitalRate); //get this sweep's timestamp offset uint64 timeOffset = m_payload.read_uint16(byteItr); byteItr += TS_OFFSET_LEN; //get this sweep's digital data value uint16 digitalData = m_payload.read_uint16(byteItr); byteItr += DIGITAL_LEN; //build this sweep's timestamp sweep.timestamp(Timestamp(packetTimestamp + ((timeOffset * TimeSpan::NANOSECONDS_PER_SECOND) / 32768) )); //get this sweep's node and base rssi values sweep.nodeRssi(m_nodeRSSI); sweep.baseRssi(m_baseRSSI); sweep.calApplied(m_dataType == WirelessTypes::dataType_float32); //the digital data is represented as the same structure as a channel mask (16 values, 1 or 0) ChannelMask digitalDataMask(digitalData); ChannelData chData; uint8 lastActiveCh = channels.lastChEnabled(); //loop through all the channels for(uint8 chItr = 1; chItr <= lastActiveCh; ++chItr) { //if the current channel is enabled if(channels.enabled(chItr)) { //if the digital value is enabled (active) for this channel if(digitalDataMask.enabled(chItr)) { //create a WirelessDataPoint from the analog data WirelessDataPoint analogPoint = createAnalogDataPoint(chItr, byteItr); //move the byteItr forward for the amount of bytes we read byteItr += WirelessTypes::dataTypeSize(m_dataType); //add the point to the ChannelData vector chData.push_back(analogPoint); } } } //add the channel data to the sweep sweep.data(chData); //add the sweep to the container of sweeps addSweep(sweep); //moving on to the next sweep in the packet sweepItr++; } //if we didn't add any sweeps, there was an error in the packet if(sweepItr == 0) { throw Error("Invalid Packet"); } }