Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e659529
Renamed current example file to "pmsm_ccs_mpc_dq_current_control.ipyn…
manjeetjha070 Jun 10, 2025
4c0f1ba
renamed existing ccs mpc and added new file for fcs(finte control set…
manjeetjha070 Jun 11, 2025
8469ee1
Upadted the title of pmsm_ccs_mpc_dq_current_control.ipynb and implem…
manjeetjha070 Jun 24, 2025
abd859c
Refactored FCS-MPC implementation to align with environment-provided …
manjeetjha070 Jul 15, 2025
4f29241
added (self.u_abc_k1 = self.u_lim * self.subactions) for calculation…
manjeetjha070 Jul 15, 2025
e18a4bf
Revised Description for FCS-MPC
manjeetjha070 Jul 23, 2025
4c3d80d
added mpc controller in gem_controllers,though testing is pending
manjeetjha070 Jul 29, 2025
a456db5
1)In gym_controller file edited such that MPC controller should not w…
manjeetjha070 Aug 26, 2025
ee8eabe
[200~fix: avoid double-counting of cross-coupling terms in MPC model
manjeetjha070 Sep 6, 2025
fdb0ef8
I have updated my MPC controller that takes motor dynamics from model…
manjeetjha070 Sep 12, 2025
7ca1004
Added MPC current controller with delay compensation
manjeetjha070 Sep 24, 2025
96efeb8
support weighted cost function (w_d, w_q) and forward args via GemCon…
manjeetjha070 Sep 28, 2025
047b7f1
added configurable delay compensation feature
manjeetjha070 Sep 30, 2025
6822bb4
added DeadTimeProcessor from environment and removed Extrapolation of…
manjeetjha070 Oct 14, 2025
af50dc7
added comments more clearly and corrected the sequence of Id and Iq
manjeetjha070 Oct 27, 2025
50f730a
Renamed current example file to "pmsm_ccs_mpc_dq_current_control.ipyn…
manjeetjha070 Jun 10, 2025
5e08efb
renamed existing ccs mpc and added new file for fcs(finte control set…
manjeetjha070 Jun 11, 2025
720f08b
Upadted the title of pmsm_ccs_mpc_dq_current_control.ipynb and implem…
manjeetjha070 Jun 24, 2025
676d691
Refactored FCS-MPC implementation to align with environment-provided …
manjeetjha070 Jul 15, 2025
39e418a
added (self.u_abc_k1 = self.u_lim * self.subactions) for calculation…
manjeetjha070 Jul 15, 2025
34ab8f4
Revised Description for FCS-MPC
manjeetjha070 Jul 23, 2025
8ad4a5a
added mpc controller in gem_controllers,though testing is pending
manjeetjha070 Jul 29, 2025
72ebcce
1)In gym_controller file edited such that MPC controller should not w…
manjeetjha070 Aug 26, 2025
baa022d
[200~fix: avoid double-counting of cross-coupling terms in MPC model
manjeetjha070 Sep 6, 2025
31f5c88
I have updated my MPC controller that takes motor dynamics from model…
manjeetjha070 Sep 12, 2025
ea18b08
Added MPC current controller with delay compensation
manjeetjha070 Sep 24, 2025
06ff656
support weighted cost function (w_d, w_q) and forward args via GemCon…
manjeetjha070 Sep 28, 2025
76816eb
added configurable delay compensation feature
manjeetjha070 Sep 30, 2025
fa5d30c
added DeadTimeProcessor from environment and removed Extrapolation of…
manjeetjha070 Oct 14, 2025
17373c6
added comments more clearly and corrected the sequence of Id and Iq
manjeetjha070 Oct 27, 2025
6e97fd4
added document for finite MPC
manjeetjha070 Oct 28, 2025
b5a9001
added mpc in gem_control.rst
manjeetjha070 Oct 29, 2025
37ebd9a
changed top level syntax
manjeetjha070 Oct 29, 2025
38664ef
Force add image file
manjeetjha070 Nov 5, 2025
0f29606
Force add image file
manjeetjha070 Nov 5, 2025
ac33a5b
Merge remote-tracking branch 'origin/nightly' into 274-add-some-autom…
bhk11 Nov 5, 2025
7e7c4e2
Fix figure paths in mpc_current_controller.rst
manjeetjha070 Nov 5, 2025
71a7380
docs: Add docstrings to MPC controller
manjeetjha070 Nov 5, 2025
54094ee
modified changelog and pyptoject toml to make a new realease after me…
bhk11 Dec 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Changed
## Fixed

## [3.0.3] - unreleased
## [3.0.3] - 2025-12-19
## Added
- Automated testing of the existing examples
- Automated testing of the electric motors
- 2x3 phase PMSM environment with tests and documentation
- finite-control-set MPC example
- finite-control-set model predicitve current control as base current control in gem-control for PMSM and SynRM (Currently working not with superimposed speed and/or torque control)
- merged gem-control documentation into the gem docs
## Changed
- Changed minimal required gymnasium version to 0.29.1.
- updated the code of gem-control to be compatible with gymnasium v1.0.0
- Updated the code of gem-control to be compatible with gymnasium v1.0.0
## Fixed
- Updated syntax in the classic_controllers to run with gymnasium v1.0.0
- #263 updated the sb3, mpc and gem-control examples to run with gymnasium v1.0.0
- #263 updated the sb3, mpc and gem-control examples to run with gymnasium v1.0.0
- exchanged widget to ipympl in the examples to run the visualization in visual studio code

## [3.0.2] - 2024-11-19
## Added
Expand Down
1 change: 1 addition & 0 deletions docs/parts_gc/api_documentation/gem_control.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ GEM Control API Documentation
pi_current_controller
torque_controller
pi_speed_controller
mpc_current_controller
gem_adapter
reference_plotter
utils
Expand Down
155 changes: 155 additions & 0 deletions docs/parts_gc/api_documentation/mpc_current_controller.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
Finite-Control-Set Model Predictive Control (FCS-MPC)
******************************************************

We apply a finite-control set (FCS) model predictive control (MPC) approach to realize
current control of a permanent magnet synchronous motor (PMSM) and Synchronous Reluctance
Motor (SRM) in rotor field-oriented coordinates. Unlike continuous-control set (CCS) MPC,
FCS-MPC directly evaluates a finite set of switching states to optimize the control input
based on a cost function over a prediction horizon.

.. figure:: ../../plots/mpc_structure.png


.. figure:: ../../plots/mpc_scheme.png


With the help of the system model, the output variables are predicted for each possible
switching state in the finite control set. The optimizer evaluates a cost function
(typically the quadratic control error) for all possible switching combinations over
the prediction horizon. The switching state that minimizes the cost function is
selected and applied to the system in the next time step.

Unlike CCS-MPC, FCS-MPC does not require an iterative numerical solver or barrier
functions to handle constraints, as the voltage limits are inherently respected by
evaluating only the physically realizable switching states of the converter.
The computational efficiency of FCS-MPC comes from the direct enumeration and evaluation
of the finite number of possible switching states, rather than solving an optimization
problem with constraints.


MPC Current Controller
======================

.. autoclass:: gem_controllers.mpc_current_controller.MPCCurrentController
:members:
:undoc-members:
:inherited-members:
:show-inheritance:
:member-order: groupwise


Example Usage
=============

The following example demonstrates how to apply the :class:`MPCCurrentController` to
control a permanent magnet synchronous motor (PMSM) using a finite-control-set MPC approach
within the ``gym-electric-motor`` simulation environment.

.. code-block:: python

import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
from gem_controllers import GemController
import gym_electric_motor as gem
from gym_electric_motor.envs.motors import ActionType, ControlType, Motor, MotorType
from gym_electric_motor.physical_systems import ConstantSpeedLoad
from gym_electric_motor.reference_generators import (
MultipleReferenceGenerator, SwitchedReferenceGenerator,
TriangularReferenceGenerator, SinusoidalReferenceGenerator,
StepReferenceGenerator
)
from gym_electric_motor.visualization.motor_dashboard import MotorDashboard

motor_parameter = dict(r_s=15e-3, l_d=0.37e-3, l_q=1.2e-3, psi_p=65.6e-3, p=3, j_rotor=0.06)
limit_values = dict(i=160 * 1.41, omega=12000 * np.pi / 30, u=450)
nominal_values = {key: 0.7 * limit for key, limit in limit_values.items()}

q_generator = SwitchedReferenceGenerator(
sub_generators=[
SinusoidalReferenceGenerator(reference_state='i_sq', amplitude_range=(0, 0.3), offset_range=(0, 0.2)),
StepReferenceGenerator(reference_state='i_sq', amplitude_range=(0, 0.5)),
TriangularReferenceGenerator(reference_state='i_sq', amplitude_range=(0, 0.3), offset_range=(0, 0.2))
],
super_episode_length=(500, 1000)
)

d_generator = SwitchedReferenceGenerator(
sub_generators=[
SinusoidalReferenceGenerator(reference_state='i_sd', amplitude_range=(0, 0.3), offset_range=(0, 0.2)),
StepReferenceGenerator(reference_state='i_sd', amplitude_range=(0, 0.5)),
TriangularReferenceGenerator(reference_state='i_sd', amplitude_range=(0, 0.3), offset_range=(0, 0.2))
],
super_episode_length=(500, 1000)
)

reference_generator = MultipleReferenceGenerator([d_generator, q_generator])

visu = MotorDashboard(state_plots=['i_sq', 'i_sd', 'u_sq', 'u_sd'], update_interval=10)

motor = Motor(
MotorType.PermanentMagnetSynchronousMotor,
ControlType.CurrentControl,
ActionType.Finite
)

#physical_system_wrapper = [DeadTimeProcessor(steps=1)] # Dead time processor with 1 step delay
#uncomment the above line to activate the DeadTimeProcessor
env = gem.make(
motor.env_id(),
visualization=visu,
load=ConstantSpeedLoad(omega_fixed=1000 * np.pi / 30),
reference_generator=reference_generator,
reward_function=dict(
reward_weights={'i_sq': 1, 'i_sd': 1},
reward_power=0.5,
),
supply=dict(u_nominal=400),
motor=dict(
motor_parameter=motor_parameter,
limit_values=limit_values,
nominal_values=nominal_values
),
#physical_system_wrappers=physical_system_wrapper,
#uncomment the above line to activate the DeadTimeProcessor
)

visu.initialize()

controller = GemController.make(
env=env,
env_id=motor.env_id(),
base_current_controller="MPC",
block_diagram=False,
prediction_horizon=1,
w_d=0.5,
w_q=2.0
)

(state, reference), _ = env.reset()
cum_rew = 0

for i in range(10000):
env.render()
action = controller.control(state, reference)
(state, reference), reward, terminated, truncated, _ = env.step(action)
cum_rew += reward
if terminated:
(state, reference), _ = env.reset()
controller.reset()

print('Reward =', cum_rew)
env.close()

Simulation Results
==================

The following figures illustrate the performance of the FCS-MPC controller in current control of the PMSM under varying reference trajectories.
The controller accurately tracks both the d- and q-axis current references while ensuring smooth control actions.

.. figure:: ../../plots/MPC_Time_Plots.png

FCS-MPC current tracking of *i<sub>d</sub>* and *i<sub>q</sub>*.

The results show that the finite-control-set MPC effectively minimizes the current tracking error within each sampling period while satisfying the converter switching
constraints. Compared to conventional PI controllers, the FCS-MPC achieves faster dynamic response and improved steady-state performance without overshoot.
Binary file added docs/plots/MPC_Time_Plots.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/plots/mpc_scheme.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/plots/mpc_structure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading