-
-
July 2, 2025 at 9:34 am
Solution
ParticipantIntroduction
Modern space missions demand highly accurate and reliable control systems, especially when it comes to satellite attitude control. This article explores how Ansys SCADE and Ansys STK (Systems Tool Kit) can be integrated to create a powerful simulation environment for satellite embedded software development, enabling real-time testing and validation of attitude control strategies.
In this blog, we integrate STK and SCADE to simulate a satellite attitude control software on a host computer.
Note: this article is written using SCADE Suite for embedded software design, but the integration would be similar with our new generation product, Ansys Scade One.
Satellite Attitude Control
Attitude control refers to the orientation of a spacecraft relative to an inertial frame of reference. Maintaining the correct attitude is vital for satellite operations, such as ensuring that antennas point towards Earth or solar panels face the Sun.
Combining the power of SCADE and STK
SCADE is a model-based development environment focused on safety-critical embedded software.
It is used to develop, simulate, and generate code for critical systems, such as the satellite attitude controller.
STK is used to simulate and visualize air and space missions, satellite orbits, and dynamic systems.
It provides realistic physics-based modeling.
The integration of SCADE and STK bridges model-based software design with high-fidelity mission simulation. When combined, these tools create a closed-loop simulation environment, where satellite dynamics and control logic interact in real time.
Use case description
In our scenario, a satellite is orbiting Earth with a defined initial state (angular speed and orientation) and a target state (target angular speed and orientation). While its orbit remains unchanged, we want the satellite’s orientation to be actively managed by a software controller.
Simulated satellite with its initial attitude (grey) and target attitude (red)
Simulated satellite trajectory and angular speedsOur SCADE Model is responsible for the following:
- Reading inputs: Current and target angular speeds and orientations, expressed as quaternions and Euler angles.
- Computing output: Torque needed to correct the satellite’s orientation, expressed as a three-dimensional vector. Note that the torque is just a vector. How it gets applied to the satellite (reaction wheels, thrusters…) is up to the STK model.
Integration Workflow
The integration between SCADE and STK involves several components:
- A SCADE model, compiled into a Windows DLL.
- A Python proxy, using the SCADE Python Wrapper, to exercise the model.
- A manual Python script that maps STK parameters to SCADE inputs/outputs, and calls the SCADE root operator at each simulation step.
- The STK engine to process attitude changes and send updates.
On the STK side, the Attitude Simulator provides an interface to connect to MATLAB, VBScript, Python, or Perl scripts. The STK to Python interface is done through COM interaction.
Note: The approach described is specific to attitude control plugin. Adapting it to other simulation domains within STK may require adjustments due to differing APIs.
Requirements
Running this integration requires:
- An STK 12 installation (the Jupyter Notebook Plugin is optional but recommended).
- A SCADE Suite Installation in version 2024 R2 or later.
- A Python Interpreter in version 3.10 or later. One comes packaged with SCADE, under
/contrib/Python310
. - The SCADE Python Wrapper.
SCADE Model and Python Wrapper
The core logic of the SCADE model is a simple Proportional / Derivative controller, converting the measured and target data into a torque vector:
Scade Attitude Controller logicTo generate the Python Proxy module, we’ll use the same technique described in a previous blog.
Once generated, the proxy contains the following:
- A global variable called
sensors
with one read/write property per sensor in the model. - A class per root operator which defines:
- One read/write property per input
- One read-only property per output
- Two functions to exercise the generated code:
call_reset(self) -> None
call_cycle(self, cycles: int = 1) -> None
In white box simulation mode, the
call_cycle
signature becomes:call_cycle(self, cycles: int = 1, refresh: bool = True, debug: bool = False) -> None
Integrating the wrapper with the Attitude Controller Plugin
On the STK side, the attitude controller expects the registration of Python functions with a particular signature. We manually write these ‘glue’ functions between STK and the SCADE Python Proxy into an intermediary Python file.
For this code, we rely on two sections of the STK documentation: Python functions and Attitude Simulator plugin points.
The code consists of three main parts.
First, a main function serves as the entry point called by STK. It takes a list argument, the first element of which is the calling mode. This mode is set to
register
once to indicate the initialization phase. Then, it is set toNone
to run simulation steps. Some STK interfaces may also set it tocompute
.def Attitude_Torque_Controller(argList): callMode = str(argList[0]) if callMode in ['None','compute']: retVal = Attitude_Torque_Controller_compute(argList) # Run a SCADE cycle elif callMode == 'register': global Attitude_Torque_Controller_init Attitude_Torque_Controller_init = -1 retVal = Attitude_Torque_Controller_register() else: retVal = [] # bad call, return empty list return retVal
Next, a function to register inputs and outputs once during initialization:
def Attitude_Torque_Controller_register(): # Register arguments, as described in https://help.agi.com/stkdevkit/12.9.1/index.htm#../Subsystems/pluginScripts/Content/pythonFunction.htm arg1 = 'ArgumentType = Output ; Type = Parameter ; ArgumentName = Torque ; Name = Torque ; BasicType = Vector' arg2 = 'ArgumentType = Input ; ArgumentName = time ; Name = Epoch' arg3 = 'ArgumentType = Input ; ArgumentName = att ; Type = Attitude; Derivative = Yes ' arg5 = 'ArgumentType = Input ; ArgumentName = q1r ; Name = q1; Type = Scalar; Source = Satellite/Reference' arg6 = 'ArgumentType = Input ; ArgumentName = q2r ; Name = q2; Type = Scalar; Source = Satellite/Reference' arg7 = 'ArgumentType = Input ; ArgumentName = q3r ; Name = q3; Type = Scalar; Source = Satellite/Reference' arg8 = 'ArgumentType = Input ; ArgumentName = q4r ; Name = q4; Type = Scalar; Source = Satellite/Reference' arg9 = 'ArgumentType = Input ; ArgumentName = angxr ; Name = angx; Type = Scalar; Source = Satellite/Reference' arg10 = 'ArgumentType = Input ; ArgumentName = angyr ; Name = angy; Type = Scalar; Source = Satellite/Reference' arg11 = 'ArgumentType = Input ; ArgumentName = angzr ; Name = angz; Type = Scalar; Source = Satellite/Reference' argList = [arg1, arg2, arg3, arg5, arg6, arg7, arg8, arg9, arg10, arg11] # Instantiate the SCADE model proxy # The cosim flag would start a simulator session in SCADE global adcs_op adcs_op = SCADE_ADCS(cosim=False) # Provide initial SCADE model inputs as constants adcs_op.ThetaX = 1000 adcs_op.ThetaY = 1000 adcs_op.ThetaZ = 1000 adcs_op.SigmaQuaternion = 0 adcs_op.SigmaOmega = 0.001 return argList
And finally, a compute function, running one cycle of the SCADE model and called by STK at each step of the simulation:
def Attitude_Torque_Controller_compute(argList): global Attitude_Torque_Controller_init global Attitude_Torque_Controller_Inputs # Access data based on argument names if Attitude_Torque_Controller_init < 0: Attitude_Torque_Controller_init = 1 Attitude_Torque_Controller_Inputs = g_PluginArrayInterfaceHash["Attitude_Torque_Controller_Inputs"] # Retrieve STK inputs q1r = argList[Attitude_Torque_Controller_Inputs['q1r']] q2r = argList[Attitude_Torque_Controller_Inputs['q2r']] q3r = argList[Attitude_Torque_Controller_Inputs['q3r']] q4r = argList[Attitude_Torque_Controller_Inputs['q4r']] angxr = argList[Attitude_Torque_Controller_Inputs['angxr']] angyr = argList[Attitude_Torque_Controller_Inputs['angyr']] angzr = argList[Attitude_Torque_Controller_Inputs['angzr']] att = np.array(argList[Attitude_Torque_Controller_Inputs['att']]) # Pass inputs to the SCADE Model through the adcs object adcs_op.MeasuredQuaternion[0] = att[0] adcs_op.MeasuredQuaternion[1] = att[1] adcs_op.MeasuredQuaternion[2] = att[2] adcs_op.MeasuredQuaternion[3] = att[3] adcs_op.MeasuredAngularSpeed[0] = math.degrees(att[4]) adcs_op.MeasuredAngularSpeed[1] = math.degrees(att[5]) adcs_op.MeasuredAngularSpeed[2] = math.degrees(att[6]) adcs_op.RefQuater[0] = q1r adcs_op.RefQuater[1] = q2r adcs_op.RefQuater[2] = q3r adcs_op.RefQuater[3] = q4r adcs_op.RefAngularSpeed[0] = math.degrees(angxr) adcs_op.RefAngularSpeed[1] = math.degrees(angyr) adcs_op.RefAngularSpeed[2] = math.degrees(angzr) # Call the SCADE model’s root operator # Set refresh to true to have the value refreshed in the UI # Set debug to true to pause the simulation after executing the cycle adcs_op.call_cycle(refresh=True,debug=True) # Retrieve and return the output output = adcs_op.OutputTorque retList = np.array([output[0], output[1], output[2]]) return np.array([retList])
Running and debugging the simulation
Once the Python part is done, we can register the script from the STK IDE.
The Attitude Simulator plugin is accessible from right click the Satellite > Satellite > Attitude Simulator…
Accessing the Attitude SimulatorFrom there, we click Configuration…:
Attitude Simulator Configuration menuIn Simulation, we click Add and select the Python file located under
/Scripting/Attitude
. We see it successfully appear:Once registered, we run the simulation with the plugin dialog’s Run… button:
If co-simulation was set to true in the Python code, a SCADE Simulator Session starts, allowing to do a step by step debugging of the scenario. Otherwise, the simulation runs by itself.
This video showcases all steps above, up to the execution of the simulation:
Want to learn more?
In this article, we have seen how to integrate SCADE and STK to simulate a satellite attitude control system.
You may start a free trial of SCADE Suite (30 days) using this link, and of STK (21 days) using that link. If you’d like to know more about how Ansys SCADE and STK can improve your engineering workflows, you may contact us from the Ansys Embedded Software page or the Ansys Digital Mission Engineering page.
In future blogs, we will dive into other use cases where SCADE and STK come together to solve real world engineering problems:
- Enhancing the Satellite Attitude Controller using the FMI standard
- Battery Monitoring for autonomous eVTOL vehicles
- Thermal and attitude control simulations
- UAV & fighter formation flight
About the author
Romain Andrieux (LinkedIn) is a Product Specialist Engineer at Ansys. He has been working on SCADE Ecosystem and the SCADE Support team development for 2 years.
-

Introducing Ansys Electronics Desktop on Ansys Cloud
The Watch & Learn video article provides an overview of cloud computing from Electronics Desktop and details the product licenses and subscriptions to ANSYS Cloud Service that are...

How to Create a Reflector for a Center High-Mounted Stop Lamp (CHMSL)
This video article demonstrates how to create a reflector for a center high-mounted stop lamp. Optical Part design in Ansys SPEOS enables the design and validation of multiple...

Introducing the GEKO Turbulence Model in Ansys Fluent
The GEKO (GEneralized K-Omega) turbulence model offers a flexible, robust, general-purpose approach to RANS turbulence modeling. Introducing 2 videos: Part 1Â provides background information on the model and a...

Postprocessing on Ansys EnSight
This video demonstrates exporting data from Fluent in EnSight Case Gold format, and it reviews the basic postprocessing capabilities of EnSight.
- Scade One – Bridging the Gap between Model-Based Design and Traditional Programming
- Scade One – An Open Model-Based Ecosystem, Ready for MBSE
- Scade One – A Visual Coding Experience
- How to Verify a Model on Host with SCADE Test? (Part 4 of 6)
- Using the SCADE Python APIs from your favorite IDE
- ARINC 661: the standard behind modern cockpit display systems
- Introduction to the SCADE Environment (Part 1 of 5)
- How to integrate multiple SCADE models into one executable
- Scade One – Democratizing model-based development
- How to Generate Code with SCADE Display (Part 6 of 6)
© 2025 Copyright ANSYS, Inc. All rights reserved.