Repository navigation
Conversation
is_element_or_parent_off() searched the whole pool for an element's parent on every call, nested three loops deep and once per level. It runs for every section from the AOG heartbeat and the VT section map, which cost about 2.3 ms a call on a Raspberry Pi CM4 with 64 sections (#100). The parent of each element is now read once from its parent object ID when the pool is activated, and the check walks that map. On the fixture pools, 64 lookups drop from 1-23 ms to about 4 us on a desktop PC. The old search looked for parents in element child lists, which in ISO 11783-10 only reference process data and properties, so it rarely found the real parent. Its fallback matched elements through the DDI-to-element map, which keeps one element per DDI, and could pick a sibling or loop (seen on the Sulky and Kuhn fixture pools). Using the parent object IDs gives the real ancestors; on the Müller pools from #41 the result for the condensed section element is unchanged. Also adds the missing <algorithm> include for std::find_if. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #100.
For condensed-work-state implements,
get_section_actual_state()callsis_element_or_parent_off(). That function used to search the whole object pool for an element's parent on every call, three loops deep and once per level. It runs for every section from the AOG heartbeat (PGN 0xF0, every 100 ms) and from the VT section map.Now each element's parent is read once from its parent object ID when the pool is activated (
ClientState::build_element_hierarchy()), and the check just walks that map. The lookup lives in a small header,include/element_hierarchy.hpp, so it can be unit tested without the TC server.Behaviour change
The old search looked for parents in element child lists. In ISO 11783-10 those lists only reference process data and properties, so it rarely found the real parent. Its fallback, added for the Müller master switch in #41, matched elements through
ddiToElementNumber. That map keeps one element per DDI, so it could pick a wrong element.I compared old and new on every pool in the fixture collection (25 pools):
The only pools where the reported section state can change are those where the condensed-state element now also checks an ancestor that reports DDI 141 (Actual Work State). That's the root element in the AgIsoStack example seeder, the AGL sprayer, and the MFG89 E-COM UD and IXSPRAY demos. If that ancestor reports "not working", the sections now report OFF to AOG. That's the master-switch behaviour #41 was aiming for.
Implements using per-element control still return early and are not affected.
Also
#include <algorithm>forstd::find_if(item 5 in Splitting out an embeddable core so changes flow to AgOpenWeb's HAT daemon #101), and drops the now unused<set>.Testing
element_hierarchyCTest: parents come from parent object IDs; only ancestors are checked (a sibling or child being off doesn't count); a malformed pool with a parent cycle terminates.🤖 Generated with Claude Code