Skip to content

Add method to set replay_mode, also via a start_program kwarg#38

Merged
cpr-mab merged 2 commits into
CommonplaceRobotics:masterfrom
JuBiotech:start-program-options
Jul 2, 2026
Merged

Add method to set replay_mode, also via a start_program kwarg#38
cpr-mab merged 2 commits into
CommonplaceRobotics:masterfrom
JuBiotech:start-program-options

Conversation

@michaelosthege

Copy link
Copy Markdown
Contributor

We'd like to run programs primarily in SINGLE mode, and this way it's easy to make sure it's set.

Observing program execution and awaiting it's completion would be nice, but even after #36 I'm still a bit confused about the exact order of events to monitor for that.

Comment thread cri_lib/cri_controller.py Outdated
)
if (error_msg := await self._wait_for_answer_async(msg_id)) is not None:
raise CRICommandError(f"Could not set replay mode: {error_msg}")
await asyncio.sleep(0.1)

@michaelosthege michaelosthege Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What's the STATUS refresh rate again? Sleeping for one cycle would be best.

@cpr-mab cpr-mab Jul 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The STATUS message is sent roughly every 25ms, it may be a bit slower

@michaelosthege michaelosthege Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I reduced the sleep to 50 ms.

In practice I'd expect the replay mode to usually match already, making the method extremely fast.

Makes it easy to set the replay mode before starting a program.
@michaelosthege michaelosthege force-pushed the start-program-options branch from 31cd026 to 959caba Compare July 2, 2026 07:45
@cpr-mab

cpr-mab commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

About observing program execution:

  • EXECACK is sent after each successful command execution (i.e. once per line in the program)
  • EXECERROR is sent when a command fails, this implies that the further program execution is aborted and the program must be restarted
  • EXECPAUSE is sent when the program is paused (by user, command, PLC, hardware error, etc.)
  • EXECEND is sent when the program is stopped (when finished, on hardware error, by PLC etc.)

Each of those command got the parameters

  • cmdNr (int) - index of the command in the currently running (sub-)program, starting at 0
  • progNr (int) - index of the currently running (sub-)program, 0 is the main program
  • programName - string, filename of the currently running (sub-)program

EXECEND and EXECERROR may contain an error message / reason string as 4th parameter


Logic programs send EXECERROR on error but no other messages. In the current RobotControl version 15 Move-To commands generate MOVETOxxx (e.g. MOVETOEXECACK) messages and mobile platform programs generate PLTFxxx messages.


So to wait for completion you will need to observe EXECEND, EXECERROR and perhaps EXECPAUSE.

Regarding your comment in PR #36: Each EXECxxx message generates a new message ID.

@cpr-mab cpr-mab merged commit 8ab5469 into CommonplaceRobotics:master Jul 2, 2026
5 checks passed
@michaelosthege michaelosthege deleted the start-program-options branch July 2, 2026 09:10
@michaelosthege

Copy link
Copy Markdown
Contributor Author

Thanks!

My execution/observation code is currently this, and it works too. For the moment I think it's sufficient.

logger.info("Executing program '%s' once", fname)
if not await controller.start_programm_async(replay_mode=ReplayMode.SINGLE):
    raise MovementError("Program execution failed.")
# Wait for it to start
while controller.robot_state.main_runstate != RunState.RUNNING:
    await asyncio.sleep(0.1)
# Observe and log progress
cmd_count = -1
while controller.robot_state.main_runstate == RunState.RUNNING:
    if controller.robot_state.main_current_command != cmd_count:
        cmd_count = controller.robot_state.main_current_command
        logger.info(
            "Program '%s' is in step %d/%d",
            controller.robot_state.main_current_program,
            controller.robot_state.main_current_command,
            controller.robot_state.main_commands_count,
        )
    await asyncio.sleep(0.025)
logger.info("Program '%s' completed.", fname)

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