Skip to main content

ControlProgram

Trait ControlProgram 

Source
pub trait ControlProgram {
    type Memory: Copy + ChangeTracker;

    // Required method
    fn process_tick(&mut self, ctx: &mut TickContext<'_, Self::Memory>);

    // Provided method
    fn initialize(&mut self, _mem: &mut Self::Memory) { ... }
}
Expand description

The trait that defines a control program’s logic.

Implement this trait to create your control program. The associated Memory type should be the generated GlobalMemory struct from your project.

§Memory Type Requirements

The Memory type must implement Copy to allow efficient synchronization between shared memory and local buffers. This is automatically satisfied by the generated GlobalMemory struct.

§Lifecycle

  1. initialize is called once at startup
  2. process_tick is called repeatedly in the control loop with a TickContext that provides shared memory, the IPC client, and the current cycle number.

§Example

use autocore_std::{ControlProgram, TickContext};

mod gm;
use gm::GlobalMemory;

pub struct MyController {
    cycle_counter: u64,
}

impl MyController {
    pub fn new() -> Self {
        Self { cycle_counter: 0 }
    }
}

impl ControlProgram for MyController {
    type Memory = GlobalMemory;

    fn initialize(&mut self, mem: &mut GlobalMemory) {
        // Set initial output states
        mem.outputs.ready = true;
        log::info!("Controller initialized");
    }

    fn process_tick(&mut self, ctx: &mut TickContext<Self::Memory>) {
        self.cycle_counter = ctx.cycle;

        // Your control logic here
        if ctx.gm.inputs.start && !ctx.gm.inputs.estop {
            ctx.gm.outputs.running = true;
        }
    }
}

Required Associated Types§

Source

type Memory: Copy + ChangeTracker

The shared memory structure type (usually the generated GlobalMemory).

Must implement Copy to allow efficient memory synchronization.

Required Methods§

Source

fn process_tick(&mut self, ctx: &mut TickContext<'_, Self::Memory>)

The main control loop - called once per scan cycle.

This is where your control logic lives. Read inputs from ctx.gm, perform calculations, and write outputs back to ctx.gm. Use ctx.client for IPC commands and ctx.cycle for the current cycle number.

The framework calls CommandClient::poll before each invocation, so incoming responses are already buffered when your code runs.

§Arguments
  • ctx - A TickContext containing the local shared memory copy, the IPC command client, and the current cycle number.
§Timing

This method should complete within the scan cycle time. Long-running operations will cause cycle overruns.

Provided Methods§

Source

fn initialize(&mut self, _mem: &mut Self::Memory)

Called once when the control program starts.

Use this to initialize output states, reset counters, or perform any one-time setup. The default implementation does nothing.

§Arguments
  • mem - Mutable reference to the shared memory. Changes are written back to shared memory after this method returns.

Implementors§