STARS (State Autocoding for Real time Systems) is an innovative software tool designed to streamline and optimize the development of embedded real-time applications. Leveraging state-of-the-art autocoding technology, Stars transforms state-machine models into efficient, reliable, and maintainable code, suitable for a wide range of applications. Developed with a focus on user-friendliness and versatility, it supports multiple modeling tools and generates code in C or C++ and specifically generates code for two different frameworks - the F' framework and the Quantum Framework, addressing the diverse needs of developers and engineers. By automating the code generation process, Stars not only accelerates development cycles but also significantly reduces the potential for human error, ensuring higher quality and performance in the final product. Whether you are working on small-scale projects or complex embedded systems, Stars is engineered to enhance productivity and foster innovation in your development endeavors.
State machine models may be specified using any of these modeling tools:
- MagicDraw Cameo Systems Modeler
- Quantum Modeler
- PlantUML text
The Autocoder processes the model into any one of the following:
- C state machine code
- C++ state machine code
- F' component state machine code and F' FPP
- Quantum Framework state machine code
This diagram highlights the input models (front end) and the autocoder products (back end)
This diagram highlights the design and process flow of the QM State Machine Autocoder:
- Install the Python module:
pip install -r requirements.txt- Check that it all works by running the test models using the pytest framework
# Navigate to the TestModels directory
cd models/TestModels
# Run all tests
pytest -v
# Expected output: Tests passed (multiple combinations across models)STARS uses a pytest-based testing framework that validates the autocoder across multiple models, input formats, and backend code generators. The testing framework verifies that:
- The autocoder correctly processes different input formats (QM, PlantUML, Cameo)
- The generated code compiles successfully for different backends (C, C++, QF, F')
- The compiled code produces expected outputs when executed
You can easily filter tests to focus on specific models, backends, or input formats:
# Test only the Simple model
pytest -m Simple
# Test only the Complex_Junction model
pytest -m Complex_Junction# Test only C backend
pytest -m c
# Test only F' (fprime) backend
pytest -m fprime# Test only QM input format
pytest -k qm
# Test only PlantUML input format
pytest -k plantuml
# Test only Cameo input format
pytest -k cameo# Test Simple model with C backend
pytest -k "Simple and c"
# Test QM input with F' backend
pytest -k "qm and fprime"
# Test Transitions model with PlantUML input and C++ backend
pytest -k "Transitions and plantuml and c++"Note: The
-koption matches substrings in test names, which include the model name, input format, and backend. This makes it easy to combine filters with logical operators likeand.
# Run with 4 parallel workers (requires pytest-xdist)
pytest -n 4# Update golden file for a specific test
pytest -k "simple and c" --update-golden
# Update all golden files (use carefully!)
pytest --update-goldenFor more details on the testing framework, see TestModels README
The Quantum Modeler tool is a free open source application for Windows, Linux or Mac that can be downloaded from: https://www.state-machine.com/#Downloads
The full users guide is here: https://www.state-machine.com/qm/bm_diagram.html
But the quick approach is to to open up an existing model i.e. Open up Simple.qm and just rename the model.
Otherwise this is the procedure:
- From the File pull down menu, select 'New Model'
- In the Model Template, select None
- In the Framework, select qpc
- Highlight 'model' in the Model Explorer, right click and Add Package
- Highlight 'package', right click and Add Class
- In the Property Editor, rename 'Class1' with the name of your state machine (ie 'MySm')
- In the Property Editor, in the superclass, select 'qpc::QHsm'
- In the Model Explorer, right click the named state machine (ie 'MySm:QHsm') and Add State Machine
- In the Model Explorer, double click the SM icon
- Expand the drawing canvas
- On right hand side, select the state icon, move to the canvas and click to drop it in.
Here are some examples of QM state machine models that are parsed correctly by this Autocoder:
- Simple.qm
- Simple_Composite.qm
- Cases.qm
- Cameo.qm
- Actions.qm
- Complex_Junction.qm
- Simple_Junction.qm
- Multiple_Actions.qm
- Arg_Actions.qm
- Transitions.qm
- String_Guards.qm
- Simple_Junction.qm
For using the PlantUML, see the users guide:
Here are some examples of PlantUML state machine models that are parsed correctly by this Autocoder:
- Simple.plantuml
- Simple_Composite.plantuml
- Cases.plantuml
- Cameo.plantuml
- Actions.plantuml
- Complex_Junction.plantuml
- Simple_Junction.plantuml
- Multiple_Actions.plantuml
- Arg_Actions.plantuml
- Transitions.plantuml
- String_Guards.plantuml
- Simple_Junction.plantuml
Diagrams can be generated from PlantUML models: Example: For the Blinky model:
@startuml
[*] --> Off: /Bsp_Initialize()
state Off {
Off:Entry: Bsp_LED_TurnOff()
}
state On {
On:Entry: Bsp_LED_TurnOn()
}
Off --> On : TIMEOUT
On --> Off : TIMEOUT
@enduml
Issue the Command:
python -m plantuml Blinky.plantumlWill generate the following graphic:
MagicDraw is not a free tool. If you have a license then you should also have the documentation. MagicDraw is a complex tool and there are many ways to specify a state machine that looks correct but will not be parsed correctly by this Autocoder. Here are some example models that do parse correctly:
- models/TestModels/Simple/Simple.xml
- models/TestModels/Simple_Composite/Simple_Composite.xml
- models/TestModels/Cases/Cases.xml
- models/TestModels/Cameo/Cameo.xml
- models/TestModels/Actions/Actions.xml
- models/TestModels/Complex_Junction/Complex_Junction.xml
- models/TestModels/Simple_Junction/Simple_Junction.xml
- models/TestModels/Multiple_Actions/Multiple_Actions.xml
- models/TestModels/Arg_Actions/Arg_Actions.xml
- models/TestModels/Transitions/Transitions.xml
- models/TestModels/String_Guards/String_Guards.xml
- models/TestModels/Simple_Junction/Simple_Junction.xml
The Python state-machine Autocoder command syntax:
usage: Stars.py [-h] [-backend {c,qf,c++,fprime}] [-model MODEL] [-noImpl] [-noSignals] [-debug] [-smbase]
State-machine Autocoder.
| Switch | Argument | Description |
|---|---|---|
| -h, --help | show this help message and exit | |
| -backend | c, qf, c++, fprime | back-end code to generate |
| -model | MODEL | QM state-machine model file: .qm |
| -noImpl | Don't generate the Impl files | |
| -noSignals | Don't generate the Signals header file | |
| -debug | prints out the models | |
| -smbase | Generates the component state-machine base class |
cd autocoder
./Stars.py -backend c -noImpl -model ../models/Blinky/Blinky.qm
./Stars.py -backend c++ -noImpl -model ../models/Blinky/Blinky.plantuml
./Stars.py -backend qf -noImpl -model ../models/Blinky/Blinky.qm
./Stars.py -backend fprime -noImpl model ../models/Blinky/Blinky.plantuml
./Stars.py -backend fprime -noImpl -model ../models/Blinky/Blinky.xml
./Stars.py -smbase
For other examples see:
The test harness provides the capability to test a PlantUML state machine model by setting guard states and sending events. A graphical rendering of the state machine is updated to animate the state machine.
# Navigate to the debug directory
cd debug
# Copy a PlantUML model
cp ../models/TestModels/Complex_Junction/Complex_Junction.plantuml .
# Launch the test harness
make harnessIn the interactive Python session:
# Load the model
set_model("Complex_Junction.plantuml")
# Open and view Complex_Junction.png to see the state machine diagram
# Set guard conditions
set_guard("g3", "True")
# Send events to transition the state machine
send_event("Ev1")
# The diagram will update to show the current state highlighted in goldAvailable commands in the test harness:
set_model("<model>.plantuml")- Load a PlantUML modelsend_event("<event>")- Send an event to the state machineset_guard("<guard>", "True"|"False")- Set a guard conditioncommands()- Display available commands



