Skip to content

Refactor connection lifecycle for asynchronous sessions contexts#27

Open
michaelosthege wants to merge 6 commits intoCommonplaceRobotics:masterfrom
JuBiotech:contextmanager-refactor
Open

Refactor connection lifecycle for asynchronous sessions contexts#27
michaelosthege wants to merge 6 commits intoCommonplaceRobotics:masterfrom
JuBiotech:contextmanager-refactor

Conversation

@michaelosthege
Copy link
Contributor

This replaces #26 where I tried to work around an issue that I ran into due to unclean connect/disconnect/dispose resource management when connections failed.

Essentially the threads must be regarded as "single use", but this requires them to be recreated if the same CRIController should be re-used.

Even more convenient would be a context manager that deals with proper disconnects and resource disposal, regardless of user level implementation.

Based on my comment here I refactored in the following way:

  • connect is changed to raise on errors -- this is a breaking change, but it's much easier to work with as it enables passing contextual information up the stack (through exception types and messages) which is not the case with return False.
  • CRIController class is split into CRIClient and CRIController(CRIClient) which makes it possible to separate observational and actuating code based on type information.
  • CRIConnector is introduced: This is a factory-like creator of connection session contexts.
    • The context managers deal with resource disposal, which simplifies usage.
    • They are already implemented as async context managers.

I also added an example that uses the CRIConnector contexts.

This asynchronous context manager style connection is relevant for us for multiple reasons:

  • We connect (asynchronously) to OPC UA servers in parallel
  • We connect to multiple iRC controllers
  • CRIClient can be long-lived, auto-reconnectiing to monitor while CRIController is only invoked for movement
  • All this happens in a FastAPI app which needs to remain responsive

What do you think, @cpr-bar ?

@michaelosthege
Copy link
Contributor Author

While testing today I already learned that entering the context should definitely await until the first robot_state arrives. Otherwise the current position and other properties can be at their default values 🤐

@michaelosthege
Copy link
Contributor Author

I can confirm that the code from this PR works.

My two biggest concerns at this point:

  • robot_state can be outdated right after connecting. IMO it should get a timestamp and context entry should not return until the first robot_state has been received.
  • I'm not sure which steps should be taken in "take control" - in my understanding the async with connector.control() as controller context entry should put and confirm the robot into a state where a movement can start.

What do you think?

@cpr-jar cpr-jar requested a review from cpr-olt February 18, 2026 13:53
raise CRICommandError("Kinematics not ready.")
yield controller
# Graceful context exit: give up control and disable robot, then disconnect in finally block.
controller.disable()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO (MO): don't do this by default

Comment on lines +1466 to +1467
if not controller.enable():
raise CRICommandError("Failed to enable robot.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO (@cpr-olt): does this automatically do reset under the hood?

Bei unserer Anlage müssen wir immer damit rechnen, dass der Mensch eine Tür öffnet: Wäre es dafür nicht besser wenn disable() automatisch gemacht wird, damit die Motoren dann schon stromlos sind?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Kapitel 4.6. sind diese Kommandos nicht genauer beschrieben:

CRISTART 1234 CMD Connect CRIEND
CRISTART 1234 CMD Disconnect CRIEND
CRISTART 1234 CMD Reset CRIEND
CRISTART 1234 CMD Enable CRIEND
CRISTART 1234 CMD Disable CRIEND

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants