TlmPacketizer Group Level Control Improvements#4668
TlmPacketizer Group Level Control Improvements#4668Lex-ari wants to merge 18 commits intonasa:develfrom
Conversation
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| this->m_sendBuffers[buffer].updated = false; | ||
| } | ||
|
|
||
| // clear enabled sections |
There was a problem hiding this comment.
Isn't this block enabling all sections rather than clearing enabled sections?
| for (FwIndexType section = 0; section < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; section++) { | ||
| for (FwChanIdType group = 0; group <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP; group++) { | ||
| this->m_groupConfigs[section][group].enabled = | ||
| group <= this->m_startLevel ? Fw::Enabled::ENABLED : Fw::Enabled::DISABLED; | ||
| } | ||
| } |
There was a problem hiding this comment.
Nit: (you can realistically ignore this since it only happens on startup)
If swap the inner loop and the outer loop you can hoist the enabled calc outside of the inner loop.
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| for (FwIndexType port = 0; port < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; port++) { | ||
| this->m_packetFlags[port][pkt].updateFlag = true; | ||
| } |
There was a problem hiding this comment.
Move this from port -> section if that's what you're consistently using
| for (FwIndexType port = 0; port < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; port++) { | |
| this->m_packetFlags[port][pkt].updateFlag = true; | |
| } | |
| for (FwIndexType section = 0; section < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; section++) { | |
| this->m_packetFlags[section][pkt].updateFlag = true; | |
| } |
Svc/TlmPacketizer/docs/sdd.md
Outdated
|
|
||
| Uses can change the individual rates at which groups per group instance are outputted upon a `run()` port call. Groups are configured with a MIN number of `run()` invocations to emit updated telemetry, and a MAX number of `run()` invocations that shall output a packet if it exceeds MAX. Packets are evaluated individually and have a counter since last invocation. MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all. |
There was a problem hiding this comment.
I personally like the phrasing of "Sched ticks," "Rate Group ticks," or simply "ticks" to contrast other unscheduled, non-thead-providing port invocations
There was a problem hiding this comment.
"each group on each output section can have its own telemetry rate resampling configuration"
There was a problem hiding this comment.
"Packets can be sent on change with a rate limiting enforced minimum number of ticks between updates. Or packets can be sent with at a guaranteed rate of a maximum number of ticks between updates."
| Telemetry Point: An emitted value. | ||
| Telemetry Channel: A tagged type and identifier for emitting telemetry points. | ||
| Telemetry Packets: A group of telemetry channels. | ||
| Telemetry Group / Level: An identifier for a telemetry packet used to determine which packets get transmitted. |
There was a problem hiding this comment.
"A set of telemetry packets with shared control"
There was a problem hiding this comment.
Using implied "definition" from here: https://nasa.github.io/fpp/fpp-users-guide.html#Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Sets
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| // If a packet in the group has been updated since last sent on section | ||
| if (pktEntryFlags.updateFlag) { | ||
| // If delta min is disabled (Disable on change, Only send on Delta Max) | ||
| if (entryGroupConfig.rateLogic == Svc::TlmPacketizer_RateLogic::EVERY_MAX) { |
There was a problem hiding this comment.
See my bitfield comment in the fpp. Regardless, I think you also need to check for SILENCED here
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| if (pktEntryFlags.prevSentCounter < 0xFFFFFFFF) { | ||
| pktEntryFlags.prevSentCounter++; | ||
| } |
There was a problem hiding this comment.
I would add a comment about preventing rollover & how you init the counter to int max to prevent a delay before first tlm packet on startup. Only counterpoint to the int max thing is you might create a whole bunch of tlm at the same time that would normally spread out.
There was a problem hiding this comment.
Telemetry Spam only applies when the tlmpacketizer is configured to PACKET_UPDATE_ALWAYS. Otherwise, it waits until first change before ON_CHANGE / AFTER_FIRST_CHANGE logic applies.
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| } else if (pktEntryFlags.prevSentCounter < entryGroupConfig.min) { | ||
| // Keep flag true but do not send. | ||
| continue; | ||
| } |
There was a problem hiding this comment.
I believe this doesn't account for you being in in MIN_AND_MAX mode (at least w/ min > max)
There was a problem hiding this comment.
I suspect the logic will have fewer checks if you avoid using continue to early escape. But that hunch may be very wrong
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| pktEntryFlags.updateFlag = true; | ||
| } | ||
|
|
||
| if (not((entryGroupConfig.enabled and this->m_sectionEnabled[section] == Fw::Enabled::ENABLED) or |
There was a problem hiding this comment.
I would probably do the enabled checks first, & for those I think early exit w/ continue does make sense
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| GroupConfig& entryGroupConfig = this->m_groupConfigs[section][entryGroup]; | ||
|
|
||
| // If a packet in the group has been updated since last sent on section | ||
| if (pktEntryFlags.updateFlag) { |
There was a problem hiding this comment.
I would recommend using a separate updateFlag from sendFlag for clarity
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| if (pktEntryFlags.updateFlag == UpdateFlag::NEVER_UPDATED) continue; // Avoid No Data | ||
|
|
||
| // Update Counter, prevent overflow. | ||
| if (pktEntryFlags.prevSentCounter < 0xFFFFFFFF) { |
There was a problem hiding this comment.
Can you use std::numeric_limits here?
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
|
|
||
| void TlmPacketizer ::SEND_PKT_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq, U32 id) { | ||
| void TlmPacketizer ::SEND_PKT_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U32 id, FwIndexType section) { |
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| if (this->m_sendBuffers[pkt].updated) { | ||
| this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::NEW; | ||
| } |
There was a problem hiding this comment.
I really like how you're using the UpdateEnum. Only catch I've seen: I think you need to check here that updateFlag != REQUESTED otherwise an update might downgrade a request to something that needs to get past the min checks
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| this->m_startLevel = startLevel; | ||
|
|
||
| } // end packet list | ||
| FW_ASSERT(maxLevel <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP, maxLevel); |
There was a problem hiding this comment.
| FW_ASSERT(maxLevel <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP, maxLevel); | |
| FW_ASSERT(maxLevel <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP, static_cast<FwAssertArgType>(maxLevel)); |
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| break; | ||
| case PACKET_UPDATE_ALWAYS: | ||
| this->m_packetFlags[section][group].updateFlag = UpdateFlag::PAST; | ||
| [[fallthrough]]; // Intentional Fallthrough (Both are configured for EVERY_MAX) |
There was a problem hiding this comment.
Fallthrough doesn't seem to work on c++ 14
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| Fw::Time::SERIALIZED_SIZE); | ||
| Fw::SerializeStatus stat = buff.serializeFrom(this->m_sendBuffers[pkt].latestTime); | ||
| FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, stat); | ||
| this->PktSend_out(outIndex, this->m_sendBuffers[pkt].buffer, 0); |
There was a problem hiding this comment.
What if you sent the prevSentCounter as the context field?
| async command SEND_PKT( | ||
| $id: U32 @< The packet ID | ||
| $id: U32 @< The packet ID | ||
| section: FwIndexType @< Section to emit packet |
There was a problem hiding this comment.
Probably should default section to 0 for backwards compatibility
There was a problem hiding this comment.
Not sure if I can assign a default here unless I create another alias type.
There was a problem hiding this comment.
Believe FwIndexType defaults at 0 too
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
| if (pktEntryFlags.updateFlag == UpdateFlag::REQUESTED) { | ||
| sendOutFlag = true; | ||
| } |
There was a problem hiding this comment.
Might be my coverage visualization glitching out, but make sure your SEND_PKT tests hit these lines
There was a problem hiding this comment.
UpdateFlag:: New Bug
Svc/TlmPacketizer/TlmPacketizer.hpp
Outdated
| TlmPacketizer_RateLogic rateLogic = TlmPacketizer_RateLogic::ON_CHANGE_MIN; | ||
| U32 min = 0; //!< Default for Backwards Compatible Behavior | ||
| U32 max = 0; //!< Default for Backwards Compatible Behavior | ||
| } m_groupConfigs[NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS][MAX_CONFIGURABLE_TLMPACKETIZER_GROUP + 1]{}; |
There was a problem hiding this comment.
| } m_groupConfigs[NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS][MAX_CONFIGURABLE_TLMPACKETIZER_GROUP + 1]{}; | |
| } m_groupConfigs[NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS][NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS]{}; |
Svc/TlmPacketizer/TlmPacketizer.cpp
Outdated
There was a problem hiding this comment.
I think just get rid of this guy
LeStarch
left a comment
There was a problem hiding this comment.
I did a first pass and will come back and do more. However, I want to understand one thing:
What is the use case for "Telemetry Groups get their own output index"? It seems that section maps to the thing that is handling the output.....so what is the advantage of breaking the groups into individual output ports too? This seems to complicate topologies, group definitions, etc.
Note: I am sure we discussed this before, but I am failing to remember.
Also, I need @timcanham to look through this.
|
|
||
| The `Svc::TlmPacketizer` Component is used to store telemetry values written by other components. The values are stored in serialized form. TlmPacketizer differs from `Svc::TlmChan` in that it stores telemetry in defined packets instead of streaming the updates as they come. The defined packets are passed in as a table to the `setPacketList()` public method. When telemetry updates are passed to the component, they are placed at the offset in a packet buffer defined by the table. When the `run()` port is called, all the defined packets are sent to the output port with the most recent . This is meant to replace `Svc::TlmCham` for use cases where a more compact packet format is desired. The disadvantage is that all channels are pushed whether or not they have been updated. | ||
|
|
||
| Uses can change the individual rates at which groups per group instance are outputted upon a `run()` sched tick. Each group on each output section has independently configurable telemetry resampling rates. Packets can be sent on change with a rate limiting enforced minimum number of ticks between updates. Or packets can be sent with at a guaranteed rate of a maximum number of ticks between updates. Packets are evaluated individually and have a counter since last invocation. MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all. |
There was a problem hiding this comment.
| Uses can change the individual rates at which groups per group instance are outputted upon a `run()` sched tick. Each group on each output section has independently configurable telemetry resampling rates. Packets can be sent on change with a rate limiting enforced minimum number of ticks between updates. Or packets can be sent with at a guaranteed rate of a maximum number of ticks between updates. Packets are evaluated individually and have a counter since last invocation. MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all. | |
| Users can change the individual rates at which telemetry groups are output upon a `run()` sched tick for each telemetry section. Each group for each section has independently configurable telemetry resampling rates. Packets can be sent on change with a rate limiting enforced minimum number of ticks between updates. Alternatively, packets can be sent with at a guaranteed rate of a maximum number of ticks between updates. Packets are evaluated individually and have a counter since last invocation. MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all. |
| # ---------------------------------------------------------------------- | ||
|
|
||
| enum RateLogic { | ||
| SILENCED, |
There was a problem hiding this comment.
Should add some annotations to explain what each of these mean.
|
|
||
| @ Packet send port | ||
| output port PktSend: Fw.Com | ||
| output port PktSend: [NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS * NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS] Fw.Com |
There was a problem hiding this comment.
Shouldn't this be just NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS? That is the number of output destinations (realtime, recorded, etc).
There was a problem hiding this comment.
This is by design - wanted an output port for each telemetry group within each section. The PktSend array is ordered by Section, Group.
| async command SEND_PKT( | ||
| $id: U32 @< The packet ID | ||
| $id: U32 @< The packet ID | ||
| section: FwIndexType @< Section to emit packet |
There was a problem hiding this comment.
Is there an options to "emit to all"?
There was a problem hiding this comment.
This is titled SEND_PKT, but the FORCE_GROUP command is called FORCE_GROUP. We should either use SEND_PACKET and SEND_GROUP or FORCE_PACKET and FORCE_GROUP
There was a problem hiding this comment.
The Send PKT is a one time request by an operator, while a FORCE_GROUP is a toggleable switch for a group within a section
| // Packet is updated and not REQUESTED (Prevent Downgrading) | ||
| if (this->m_sendBuffers[pkt].updated and | ||
| this->m_packetFlags[section][pkt].updateFlag != UpdateFlag::REQUESTED) | ||
| this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::NEW; |
There was a problem hiding this comment.
Style: add {} around if clauses
| this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::NEW; | |
| { | |
| this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::NEW; | |
| } |
| 5. The packet has data (marked updated in the past or new) | ||
| */ | ||
| if (not this->isConnected_PktSend_OutputPort(outIndex)) | ||
| continue; |
There was a problem hiding this comment.
add {}
| continue; | |
| { | |
| continue; | |
| } |
@LeStarch Appreciate it, thanks! We wanted to separately output different telemetry groups to change and configure their priority on downstream components based on group, rather than having them all set on a single port, or several sections. Some groups can receive a higher priority than other connections to, for example, a ComQueue, such as Events or FileDownlink operations. |
LeStarch
left a comment
There was a problem hiding this comment.
Still looking for the section -> enum change, but I finished the deeper review!
| # ====================================================================== | ||
| module Svc { | ||
| @ The number of sections of ports (Primary = 0, Secondary = 1, etc...) | ||
| constant NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS = 3; |
There was a problem hiding this comment.
When made into an enumeration, this should be captured as a MAX constant or NUMBER constant. e.g:
enum ABC {
ABC
DEF
NUMBER_ABC
}
| #ifndef TESTER_HPP | ||
| #define TESTER_HPP | ||
|
|
||
| #include <queue> |
There was a problem hiding this comment.
This appears to be unused. Can we remove it?
|
|
||
| enum RateLogic { | ||
| SILENCED, | ||
| EVERY_MAX, |
There was a problem hiding this comment.
I find the MIN and MAX parts of these names a bit confusing? Can we add annotations for what these mean?
e.g.
ON_CHANGE_MIN, //@< Send on change with minimum delay between sends
EVERY_MAX, //@< Send with maximum delay between sends
ON....
| enum RateLogic { | ||
| SILENCED, | ||
| EVERY_MAX, | ||
| ON_CHANGE_MIN, | ||
| ON_CHANGE_MIN_OR_EVERY_MAX, | ||
| } |
There was a problem hiding this comment.
Just be careful that the resulting code isn't "too clever". If it cleans the code up, then go for it.
| enabled: Fw.Enabled @< Enable / Disable Telemetry Output | ||
| forceEnabled: Fw.Enabled @< Force Enable / Disable Telemetry Output | ||
| rateLogic: RateLogic @< Rate Logic Configuration | ||
| min: U32 @< Minimum Sched Ticks |
There was a problem hiding this comment.
Note in the annotation that this only applies to the MIN setting, same with max and MAX
| opcode 3 | ||
|
|
||
| @ Force telemetering a group on a section, even if disabled | ||
| async command FORCE_GROUP( |
There was a problem hiding this comment.
SEND_GROUP to be consistent with SEND_PKT?
There was a problem hiding this comment.
FORCE_GROUP is a toggleable switch that forces logic on a telemetry group. SEND_PKT is an operator requested command
| this->m_sendBuffers[pkt].updated = false; | ||
| } | ||
| this->m_sendBuffers[pkt] = this->m_fillBuffers[pkt]; | ||
| this->m_fillBuffers[pkt].updated = false; |
There was a problem hiding this comment.
This would imply that if all sections disable this packet's group, then this update would be cleared but the packet would not be sent. This would be worth updating in the SDD.
| for (FwIndexType section = 0; section < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; section++) { | ||
| // Packet is updated and not REQUESTED (Prevent Downgrading) | ||
| if (this->m_sendBuffers[pkt].updated and | ||
| this->m_packetFlags[section][pkt].updateFlag != UpdateFlag::REQUESTED) |
There was a problem hiding this comment.
must enclose all ifs with {} regardless of being 1 line.
|
|
||
| // Iterate through output sections | ||
| for (FwIndexType section = 0; section < NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS; section++) { | ||
| // Packet is updated and not REQUESTED (Prevent Downgrading) |
There was a problem hiding this comment.
I don't know what PREVENT Downgrading means. Elaborate. "When not REQUESTED updated packets need to be marked as NEW" or something.
There was a problem hiding this comment.
Comment left to describe packets marked as REQUESTED don't accidentally get marked as NEW, as REQUESTED packets bypass MIN/MAX logic
| 4. The rate logic is not SILENCED. | ||
| 5. The packet has data (marked updated in the past or new) | ||
| */ | ||
| if (not this->isConnected_PktSend_OutputPort(outIndex)) |
|
|
||
| The `Svc::TlmPacketizer` Component is used to store telemetry values written by other components. The values are stored in serialized form. TlmPacketizer differs from `Svc::TlmChan` in that it stores telemetry in defined packets instead of streaming the updates as they come. The defined packets are passed in as a table to the `setPacketList()` public method. When telemetry updates are passed to the component, they are placed at the offset in a packet buffer defined by the table. When the `run()` port is called, all the defined packets are sent to the output port with the most recent . This is meant to replace `Svc::TlmCham` for use cases where a more compact packet format is desired. The disadvantage is that all channels are pushed whether or not they have been updated. | ||
|
|
||
| Uses can change the individual rates at which groups per group instance are outputted upon a `run()` sched tick. Each group on each output section has independently configurable telemetry resampling rates. Packets can be sent on change with a rate limiting enforced minimum number of ticks between updates. Or packets can be sent with at a guaranteed rate of a maximum number of ticks between updates. Packets are evaluated individually and have a counter since last invocation. MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all. |
There was a problem hiding this comment.
"MIN and MAX logic are selectable, for users that desire only "on change" telemetry, MAX invocations between telemetry points, both, or none at all." Might need rephrasing.
|
|
||
| #### 3.1.3 Terminology | ||
| Telemetry Point: An emitted value. | ||
| Telemetry Channel: A tagged type and identifier for emitting telemetry points. |
| Each telemetry group per section is configured with a `RateLogic` parameter: | ||
| * `SILENCED`: Packet will never be sent | ||
| * `EVERY_MAX`: Packet will be sent every Max Delta intervals | ||
| * `ON_CHANGE_MIN`: Packet will only be sent on updates at at least Min Delta intervals. |
There was a problem hiding this comment.
No faster than min delta intervals, yes?
There was a problem hiding this comment.
In the current implementation, MAX will take priority over MIN if MIN is greater than MAX (when set to ON_CHANGE_MIN_OR_EVERY_MAX). Will add to sdd.
LeStarch
left a comment
There was a problem hiding this comment.
Somehow it approved, meant to request changes.
| for (PktSendCounters& pkt : this->m_packetFlags[section]) { | ||
| // Trigger sending packets even if they're empty. | ||
| pkt.updateFlag = UpdateFlag::PAST; | ||
| } |
Check notice
Code scanning / CodeQL
Multiple variable declarations on one line Note
| } | ||
|
|
||
| void TlmPacketizer ::SEND_PKT_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq, U32 id) { | ||
| void TlmPacketizer ::SEND_PKT_cmdHandler(const FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
| this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
| } | ||
|
|
||
| void TlmPacketizer ::ENABLE_SECTION_cmdHandler(FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
| this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
| } | ||
|
|
||
| void TlmPacketizer ::ENABLE_GROUP_cmdHandler(FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
| this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
| } | ||
|
|
||
| void TlmPacketizer ::FORCE_GROUP_cmdHandler(FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
| this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
| } | ||
|
|
||
| void TlmPacketizer ::SET_GROUP_DELTAS_cmdHandler(FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Function too long Note
| this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
| } | ||
|
|
||
| void TlmPacketizer ::SET_GROUP_DELTAS_cmdHandler(FwOpcodeType opCode, |
Check notice
Code scanning / CodeQL
Long function without assertion Note
| REQUESTED = 3, | ||
| }; | ||
|
|
||
| struct PktSendCounters { |
Check notice
Code scanning / CodeQL
More than one statement per line Note
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Change Description
Group Level Control of Telemetry and individually sampled rates.
PktSendoutput is now "Sections" of Telemetry GroupsPktSendout array for each telemetry group.SILENCED,ON_CHANGE_MIN,EVERY_MAX, andON_CHANGE_MIN_OR_EVERY_MAXcontrolInport to support enabling / disabling separate Telemetry SectionsRationale
This is a wanted telemetry improvement for several projects. In the current implementation, Packets with telemetry groups are emitted only if the current level is at or above the entry's telemetry group. This means that packet specifications must be carefully designed in order to account which packets should be linked with which group, as there is no way to "disable" specific packets other than having sequential ones chosen.
Additionally, projects would want to change the stream throughput of packets in flight. This is currently a limitation backed by a single rate group and cannot be configured in-flight.
This implementation allows users to individually configure each group, which are then evaluated on an individual packet basis. Telemetry have a configurable minimum thresholds of
Runport invocations before sending updates, preventing telemetry spam. Additionally, they have a configurable maximum threshold that will send packets, ensuring that feedback is continuously monitored. Packets can be configured to emit on changes or every standard interval in flight, without needing an update or restart.Sections of telemetry groups allow downstream components of the
tlmPacketizerto handle resampling of data at different rates. This could be lower fidelity live telemetry on one section, while high detailed sim reconstruction happens on another section. Each section is individually configurable. These sections can be turned on and off following different spacecraft modes.Additionally, individual group ports per section allow downstream components to "listen in" or prioritize specific groups against other groups / packets (Ex on ComQueue, File Downlink / Events).
Testing/Review Recommendations
These changes were designed to be near backwards compatible in terms of Telemetry group send behavior. Without configuration, it works similarly to the current implementation of
tlmPacketizer.Major changes to topologies would include merging output ports of
pktSendto downstream topology components. Packets are now sent on an array of indices onpktSend, which are also sent for however many "sections" is included in the configuration forTlmPacketizer.CC @LeStarch @Willmac16