Skip to main content

Crate autocore_std

Crate autocore_std 

Source
Expand description

§AutoCore Standard Library

The standard library for writing AutoCore control programs. This crate provides everything you need to build real-time control applications that integrate with the AutoCore server ecosystem.

§Overview

AutoCore control programs run as separate processes that communicate with the autocore-server via shared memory and IPC. This library handles all the low-level details, allowing you to focus on your control logic.

┌─────────────────────────┐     ┌─────────────────────────┐
│   autocore-server       │     │   Your Control Program  │
│                         │     │                         │
│  ┌─────────────────┐    │     │  ┌─────────────────┐    │
│  │ Shared Memory   │◄───┼─────┼──│ ControlRunner   │    │
│  │ (GlobalMemory)  │    │     │  │                 │    │
│  └─────────────────┘    │     │  │ ┌─────────────┐ │    │
│                         │     │  │ │ Your Logic  │ │    │
│  ┌─────────────────┐    │     │  │ └─────────────┘ │    │
│  │ Tick Signal     │────┼─────┼──│                 │    │
│  └─────────────────┘    │     │  └─────────────────┘    │
└─────────────────────────┘     └─────────────────────────┘

§Quick Start

  1. Create a new control project using acctl:

    acctl clone <server-ip> <project-name>
  2. Implement the ControlProgram trait:

    use autocore_std::{ControlProgram, RTrig};
    
    // GlobalMemory is generated from your project.json
    mod gm;
    use gm::GlobalMemory;
    
    pub struct MyProgram {
        start_button: RTrig,
    }
    
    impl MyProgram {
        pub fn new() -> Self {
            Self {
                start_button: RTrig::new(),
            }
        }
    }
    
    impl ControlProgram for MyProgram {
        type Memory = GlobalMemory;
    
        fn process_tick(&mut self, mem: &mut GlobalMemory, _cycle: u64) {
            // Detect rising edge on start button
            if self.start_button.call(mem.inputs.start_button) {
                mem.outputs.motor_running = true;
                autocore_std::log::info!("Motor started!");
            }
        }
    }
  3. Use the autocore_main! macro for the entry point:

    autocore_std::autocore_main!(MyProgram, "my_project_shm", "tick");

§Function Blocks (IEC 61131-3 Inspired)

This library includes standard function blocks commonly used in PLC programming:

  • RTrig - Rising edge detector (false→true transition)
  • FTrig - Falling edge detector (true→false transition)
  • Ton - Timer On Delay (output after delay)
  • SimpleTimer - Simple one-shot timer (NOT IEC 61131-3, for imperative use)
  • StateMachine - State machine helper with automatic timer management

§Example: Edge Detection

use autocore_std::RTrig;

let mut trigger = RTrig::new();

// First call with false - no edge
assert_eq!(trigger.call(false), false);

// Rising edge detected!
assert_eq!(trigger.call(true), true);

// Still true, but no edge (already high)
assert_eq!(trigger.call(true), false);

// Back to false
assert_eq!(trigger.call(false), false);

// Another rising edge
assert_eq!(trigger.call(true), true);

§Example: Timer

use autocore_std::Ton;
use std::time::Duration;

let mut timer = Ton::new();
let delay = Duration::from_millis(100);

// Timer not enabled - output is false
assert_eq!(timer.call(false, delay), false);

// Enable timer - starts counting
assert_eq!(timer.call(true, delay), false);

// Still counting...
std::thread::sleep(Duration::from_millis(50));
assert_eq!(timer.call(true, delay), false);
assert!(timer.et < delay); // Elapsed time < preset

// After delay elapsed
std::thread::sleep(Duration::from_millis(60));
assert_eq!(timer.call(true, delay), true); // Output is now true!

§Logging

Control programs can send log messages to the autocore-server for display in the web console. Logging is handled automatically when using ControlRunner.

use autocore_std::log;

log::trace!("Detailed trace message");
log::debug!("Debug information");
log::info!("Normal operation message");
log::warn!("Warning condition detected");
log::error!("Error occurred!");

See the logger module for advanced configuration.

§Memory Synchronization

The ControlRunner handles all shared memory synchronization automatically:

  1. Wait for tick - Blocks until the server signals a new cycle
  2. Read inputs - Copies shared memory to local buffer (atomic snapshot)
  3. Execute logic - Your process_tick runs on the local buffer
  4. Write outputs - Copies local buffer back to shared memory

This ensures your control logic always sees a consistent view of the data, even when other processes are modifying shared memory.

Re-exports§

pub use log;

Modules§

logger
UDP logger for sending log messages to autocore-server.

Macros§

autocore_main
Generates the standard main function for a control program.

Structs§

ControlRunner
The main execution engine for control programs.
FTrig
Falling Edge Trigger (F_TRIG)
RTrig
Rising Edge Trigger (R_TRIG)
RunnerConfig
Configuration for the ControlRunner.
SimpleTimer
Simple One-Shot Timer
StateMachine
State Machine Helper (FB_StateMachine)
Ton
Timer On Delay (TON)

Constants§

DEFAULT_WS_PORT
Default WebSocket port for autocore-server

Traits§

AutoCoreMemory
Marker trait for generated GlobalMemory structs.
ControlProgram
The trait that defines a control program’s logic.