-
Notifications
You must be signed in to change notification settings - Fork 1.5k
TlmPacketizer Group Level Control Improvements #4668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: devel
Are you sure you want to change the base?
Changes from all commits
ea668f1
e4b61e2
bf5053c
a76515d
7c542a1
3081d38
57c7c2f
a23a0ef
8f9f573
7f0a66a
38a2bb9
3c2447c
29ea42e
015c0f9
27a1d05
75c224a
c6d75ce
5fbd74b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,47 @@ | ||
| module Svc { | ||
|
|
||
| port EnableSection ( | ||
| section: FwIndexType @< Section to enable (Primary, Secondary, etc...) | ||
| enabled: Fw.Enabled @< Enable / Disable Section | ||
| ) | ||
| @ A component for storing telemetry | ||
| active component TlmPacketizer { | ||
| # ---------------------------------------------------------------------- | ||
| # Types | ||
| # ---------------------------------------------------------------------- | ||
|
|
||
| enum RateLogic { | ||
| SILENCED, | ||
| EVERY_MAX, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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, | ||
| ON_CHANGE_MIN_OR_EVERY_MAX, | ||
| } | ||
|
Comment on lines
+12
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can ignore if you want, but with explicit indexing (I think it technically already works) you could make this a bitfield of min and max ruleset enable (i.e. rateLogic & 0x01 is MAX_ENABLED and rateLogic & 0x02 is MIN_ENABLED)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just be careful that the resulting code isn't "too clever". If it cleans the code up, then go for it. |
||
|
|
||
| struct GroupConfig { | ||
| 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note in the annotation that this only applies to the MIN setting, same with |
||
| max: U32 @< Maximum Sched Ticks | ||
| } default { | ||
| enabled = Fw.Enabled.ENABLED | ||
| forceEnabled = Fw.Enabled.DISABLED | ||
| rateLogic = RateLogic.ON_CHANGE_MIN | ||
| min = 0 | ||
| max = 0 | ||
| } | ||
|
|
||
| array GroupConfigs = [NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS] GroupConfig | ||
| array SectionConfigs = [NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS] GroupConfigs | ||
| array SectionEnabled = [NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS] Fw.Enabled default Fw.Enabled.ENABLED | ||
|
|
||
| # ---------------------------------------------------------------------- | ||
| # General ports | ||
| # ---------------------------------------------------------------------- | ||
|
|
||
| @ Packet send port | ||
| output port PktSend: Fw.Com | ||
| output port PktSend: [NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS * NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS] Fw.Com | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be just
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is by design - wanted an output port for each telemetry group within each section. The PktSend array is ordered by Section, Group. |
||
|
|
||
| async input port controlIn: EnableSection | ||
|
|
||
| @ Ping input port | ||
| async input port pingIn: Svc.Ping | ||
|
|
@@ -62,10 +95,46 @@ module Svc { | |
|
|
||
| @ Force a packet to be sent | ||
| async command SEND_PKT( | ||
| $id: U32 @< The packet ID | ||
| $id: U32 @< The packet ID | ||
| section: FwIndexType @< Section to emit packet | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should default section to 0 for backwards compatibility
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if I can assign a default here unless I create another alias type.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Believe FwIndexType defaults at 0 too
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an options to "emit to all"?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is titled SEND_PKT, but the FORCE_GROUP command is called
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Send PKT is a one time request by an operator, while a |
||
| ) \ | ||
| opcode 1 | ||
|
|
||
| @ Enable / disable telemetry of a group on a section | ||
| async command ENABLE_SECTION( | ||
| section: FwIndexType @< Section grouping to configure | ||
| enable: Fw.Enabled @< Section enabled or disabled | ||
| ) \ | ||
| opcode 2 | ||
|
|
||
| @ Enable / disable telemetry of a group on a section | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting, left align the @ |
||
| async command ENABLE_GROUP( | ||
| section: FwIndexType @< Section grouping to configure | ||
| tlmGroup: FwChanIdType @< Group Identifier | ||
| enable: Fw.Enabled @< Section enabled or disabled | ||
| ) \ | ||
| opcode 3 | ||
|
|
||
| @ Force telemetering a group on a section, even if disabled | ||
| async command FORCE_GROUP( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| section: FwIndexType @< Section grouping | ||
| tlmGroup: FwChanIdType @< Group Identifier | ||
| enable: Fw.Enabled @< Section enabled or disabled | ||
| ) \ | ||
| opcode 4 | ||
|
|
||
| @ Set Min and Max Deltas between successive packets | ||
| async command SET_GROUP_DELTAS( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Call this |
||
| section: FwIndexType @< Section grouping | ||
| tlmGroup: FwChanIdType @< Group Identifier | ||
| rateLogic: RateLogic @< Rate Logic | ||
| minDelta: U32 @< Minimum Sched Ticks to send packets on updates | ||
| maxDelta: U32 @< Maximum Sched Ticks to send packets | ||
| ) \ | ||
| opcode 5 | ||
|
|
||
|
|
||
|
|
||
| # ---------------------------------------------------------------------- | ||
| # Events | ||
| # ---------------------------------------------------------------------- | ||
|
|
@@ -111,12 +180,21 @@ module Svc { | |
| id 4 \ | ||
| format "Could not find packet ID {}" | ||
|
|
||
| event SectionUnconfigurable( | ||
| section: FwIndexType @< The Section | ||
| enable: Fw.Enabled @< Attempted Configuration | ||
| ) \ | ||
| severity warning low \ | ||
| id 5 \ | ||
| format "Section {} is unconfigurable and cannot be set to {}" | ||
|
|
||
| # ---------------------------------------------------------------------- | ||
| # Telemetry | ||
| # ---------------------------------------------------------------------- | ||
|
|
||
| @ Telemetry send level | ||
| telemetry SendLevel: FwChanIdType id 0 | ||
| telemetry GroupConfigs: SectionConfigs id 0 | ||
| telemetry SectionEnabled: SectionEnabled id 1 | ||
|
|
||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,8 @@ | |||||
|
|
||||||
| 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. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "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. |
||||||
|
|
||||||
| ## 2. Requirements | ||||||
|
|
||||||
| The requirements for `Svc::TlmPacketizer` are as follows: | ||||||
|
|
@@ -29,26 +31,60 @@ The `Svc::TlmPacketizer` component has the following component diagram: | |||||
|
|
||||||
| #### 3.1.2 Ports | ||||||
|
|
||||||
| The `Svc::TlmChan` component uses the following port types: | ||||||
| The `Svc::TlmPacketizer` component uses the following port types: | ||||||
|
|
||||||
| Port Data Type | Name | Direction | Kind | Usage | ||||||
| -------------- | ---- | --------- | ---- | ----- | ||||||
| [`Svc::Sched`](../../Sched/docs/sdd.md) | Run | Input | Asynchronous | Execute a cycle to write changed telemetry channels | ||||||
| [`Fw::Tlm`](../../../Fw/Tlm/docs/sdd.md) | TlmRecv | Input | Synchronous Input | Update a telemetry channel | ||||||
| [`Fw::Com`](../../../Fw/Com/docs/sdd.md) | PktSend | Output | n/a | Write a set of packets with updated telemetry | ||||||
| `Svc::EnableSection` | controlIn | Input | Asynchronous | Enable / Disable sections of telemetry groups | ||||||
|
|
||||||
| #### 3.1.3 Terminology | ||||||
| Telemetry Point: An emitted value. | ||||||
| Telemetry Channel: A tagged type and identifier for emitting telemetry points. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also has time! |
||||||
| Telemetry Packets: A group of telemetry channels. | ||||||
| Telemetry Group / Level: An identifier for a telemetry packet used to determine which packets get transmitted. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "A set of telemetry packets with shared control"
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using implied "definition" from here: https://nasa.github.io/fpp/fpp-users-guide.html#Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Sets |
||||||
| Telemetry Section: A resampling of telemetry groups. Each Section typically is destined for a different destination (e.g. realtime downlink vs store & forward) | ||||||
|
|
||||||
| #### 3.2 Functional Description | ||||||
|
|
||||||
| The `Svc::TlmPacketizer` component has an input port `TlmRecv` that receives channel updates from other components in the system. These calls from the other components are made by the component implementation classes, but the generated code in the base classes takes the type specific channel value and serializes it, then makes the call to the output port. The `Svc::TlmPacketizer` component can then store the channel value as generic data. The channel ID is used to look up offsets for the channel in each of the defined packets. A channel can be defined in more than one packet. The time tag is stripped from the incoming telemetry value. The time tag of the channel will become the time tag of the entire frame when it is sent. | ||||||
|
|
||||||
| The implementation uses a hashing function to find the location of telemetry channels that is tuned in the configuration file `TlmPacketizerImplCfg.hpp`. See section 3.5 for description. | ||||||
|
|
||||||
| When a call to the `Run()` interface is called, the packet writes are locked and all the packets are copied to a second set of packets. Once the copy is complete, the packets writes are unlocked. The destination packet set gets updated with the current time tag and are sent out the `pktSend()` port. | ||||||
| When a call to the `Run()` interface is called, the packet writes are locked and all the packets are copied to a second set of packets. Once the copy is complete, the packets writes are unlocked. The destination packet set gets updated with the current time tag and are sent out the `pktSend` port. | ||||||
|
|
||||||
| Each telemetry group, depending on section and group configurations, are sent out on several indices of the `pktSend` port. Since each section holds a continuous range of ports, a packet with group 1 with a TlmPacketizer configuration of 3 sections (0, 1, and 2), and a max group of 3 (0 and 3 inclusive), will be sent on 3 indices: 1, 5, and 9. Port invocations to `controlIn` or the command, `ENABLE_SECTION` are used to enable / disable each section, supporting downstream components that rely on different samplings of groups of telemetry. Each group instance is separately sampled from each other, allowing for individual rates per section and group. | ||||||
|
|
||||||
| ### 3.3 Scenarios | ||||||
|
|
||||||
| #### 3.3.1 External User Option | ||||||
|
|
||||||
| #### 3.3.2 Configuring Telemetry Group Rates Per Port | ||||||
|
|
||||||
| The `Svc::TlmPacketizer` is configurable to have multiple `PktSend` group outputs using the fpp constant, `MAX_CONFIGURABLE_TLMPACKETIZER_GROUP`. Doing so allows each packet group have different configurations for each `PktSend` output section. | ||||||
|
|
||||||
| `PktSend` output is ordered by `[section][group]`, where within each section telemetry groups are emitted. Each group within each section are separately sampled, and have their own configuration rates and logic independent from each other. | ||||||
|
|
||||||
| Each group is configured with min/max delta parameters, as well as a logic gate determining its output rate behavior. Deltas are counters of sched ticks invoked through the `run()` port. Min Delta is the least number of `Run()` invocations between successive packets before a packet with an updated channel is allowed to be sent. Updated packets will not be sent until their counter reaches Min Delta. This mitigates against telemetry spam while allowing users to benefit from asynchronously updating channels (e.g. those that don't occupy a set schedule). Max Delta is the maximum number of `Run()` invocations between successive packets. Upon reaching this counter, the packet would be sent, regardless of change. | ||||||
|
|
||||||
| 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. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No faster than min delta intervals, yes?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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`: Packet will be sent on updates at at least Min Delta intervals, or at most Max Delta intervals. | ||||||
|
|
||||||
| Groups are configured using the `SET_GROUP_DELTAS` command. | ||||||
|
|
||||||
| #### 3.3.3 Switching Telemetry Sections | ||||||
| `Svc::TlmPacketizer` also has a configurable constant `NUM_CONFIGURABLE_TLMPACKETIZER_SECTIONS` that allows separately streamed outputs of packets of the same group. This is useful for downstream components that would handle different telemetry groups at different rates. Examples of this configuration includes live telemetry throughput, detailed sim reconstruction, or critical data operations. | ||||||
|
|
||||||
| Telemetry sections are enabled and disabled upon spacecraft state transitions through `controlIn()` port invocations or via operator commands. A section and group pair must be both enabled to emit a telemetry packet. | ||||||
| * `ENABLE_SECTION` / `controlIn()`: Enable / Disable telemetry sections. | ||||||
| * `ENABLE_GROUP`: Within a section, Enable / Disable a telemetry group. | ||||||
| * `FORCE_GROUP`: If set to Enabled, telemetry of the chosen group in a section will be emitted regardless if the section or group within the section is disabled. | ||||||
|
|
||||||
| ### 3.4 State | ||||||
|
|
||||||
| `Svc::TlmPacketizer` has no state machines. | ||||||
|
|
@@ -71,4 +107,5 @@ To see unit test coverage run fprime-util check --coverage | |||||
| Date | Description | ||||||
| ---- | ----------- | ||||||
| 12/14/2017 | Initial version | ||||||
| 01/23/2026 | Added group level rate logic | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add some annotations to explain what each of these mean.