Field-Oriented Control of a Permanent Magnet Synchronous Machine
This example shows how you can model a controller and implement it on a Xilinx® Zynq™-7000 All Programmable SoC target. This example is based on a ZedBoard using an Analog Devices motor control FMC board. Note that if you do not have the required hardware, you can use this example to gain experience that will help you develop a controller for your own hardware configuration.
In this example you will review common tasks to design a control algorithm and implement it on a Zynq processor. The example is based on a Field-Oriented Controller (FOC) for a Permanent Magnet Synchronous Machine (PMSM), but you can apply these techniques to the development of most controller algorithms. The below image illustrates the workflow that you will apply.
You will begin by simulating a system test bench to gain insight into the behavior of the controller algorithm design. You will then explore the design to see how the algorithm is partitioned. The high rate portion of the algorithm is partitioned into a model which is configured for HDL code generation. The low rate portion of the algorithm is partitioned into a model which is configured for C code generation. You will generate C and HDL code from these models and learn how you could integrate this code into your design.
After exploring the algorithmic C and HDL code, you will learn how to automate deployment of the algorithmic code into reference frameworks for the ARM and programmable logic. You will execute a test on the deployed application, log the results, and compare them to the simulation results.
- To deploy the bitstream and ARM executable to Zynq, you must complete the setup steps for your Zynq hardware. To ensure your environment is setup correctly, we recommend you complete the example Getting Started with Hardware-Software Codesign Workflow for Xilinx Zynq Platform for your hardware configuration.
- Vivado is required to generate the bitstream. This is because the Reference Design used for this example was created using Vivado.
In this section you will learn about the hardware used to develop this example. If you have the same hardware, you can follow the subsequent tasks to reproduce this example yourself. If you do not have the hardware, you can still explore this example to help you understand how to architect your design to support simulation, code generation, and deployment to a Zynq SoC.
This example was developed and tested using the following hardware:
- Analog Devices® AD-FMCMOTCON2-EBZ - Controller board
- Brushless DC motor: 24V, 4000 RPM, Hall Sensors and 1250 CPR indexed encoder
For more information about the hardware, see Zynq All Programmable SoC/Analog Devices Intelligent Drives Kit. If you have this hardware:
1. Make the connections to the ZedBoard as shown in the figure below.
2. Make the AD-FMCMOTCON2-EBZ Controller board and ZedBoard connections as shown in the figure below.
Task 1: Open and explore the project
In this task you will open the example project and identify the shortcuts that you will run in subsequent tasks. This example is packaged as a Simulink Project. The Simulink Project is a convenient way to manage related files, configure the environment, and provide easy entry points to design tasks using project shortcuts. If you are new to Simulink Projects, you can learn more by reviewing the help documentation: What Are Simulink Projects?
1. Run zynqexPMSMFOCStart to create and open a working copy of the project files for this example. The example will use a default folder in your system as initial folder. For choosing a specific folder,use the absolute path of the folder as a parameter. Example: zynqexPMSMFOCStart('C:\Temp') Note: If the absolute path of the folder is longer than 80 characters, use a shorter path.
2. Select Shortcut Management to view the shortcuts that you will use in this example. Right click on the shortcut and identify the Open and Run Shortcut context menu items.
You will use the Run Shortcut menu item to perform common development tasks. If you want to see the MATLAB code that is being executed for these tasks, you can use the Open menu item.
Task 2: Verify algorithm behavior with simulation
In this task, you will explore and verify the behavior of the controller through simulation.
1. Run the task.t1_openSimulationTestBenchModel shortcut to open the focZynqTestBench model.
The Motor_And_Load subsystem consists of a mathematical model of a surface PMSM, motor load, encoder and current sensor. If you have SimPowerSystems™ installed, you can explore the individual components and parameters in this subsystem. If you do not have SimPowerSystems installed, the Motor_And_Load subsystem will contain a block that enables you to simulate the model with default motor and load parameters, but you will not be able to explore or modify parameters. The Controller_Algorithm subsystem includes I/O engineering unit conversion, an electrical position calculation, a rotor velocity calculation, a mode scheduler, and four control modes: disabled, open loop velocity control, encoder calibration, and closed loop velocity control. During closed loop velocity control FOC is used to regulate phase current in the PMSM. The C/D and D/C subsystems convert data between continuous-time simulation (variable time step solver and floating point data types) and discrete-time simulation (fixed time step solver and fixed-point data types).
2. Click the Run button to simulate the model and view the results in the System Response scope. To improve simulation speed, consider running the model in Accelerator Mode by selecting the menu item Simulation > Mode > Accelerator before running the simulation.
Note that for the first two seconds the controller is commanded to calibrate the encoder position sensor. The encoder position sensor must be calibrated before the controller can achieve closed loop control. During the first portion of position calibration, the motor spins using open loop control in order to identify the index pulse of the encoder. During this period the velocity is linear. Once the index is found, the controller commands and holds a zero position until the encoder offset is identified. During this period the velocity is zero. At two seconds, the controller changes into closed loop control and follows a velocity profile while steps between positive and negative velocity commands.
You can further explore signals logged during simulation using the Simulation Data Inspector. You will use the Simulation Data Inspector again later in this example to compare simulation and hardware results.
3. Select Simulation > Output > Simulation Data Inspector
4. In Simulation Data Inspector, select the rotorVelocity signal.
Task 3: Partition algorithm to generate C and HDL code
In this task you will explore how the controller algorithm is partitioned to support software and hardware implementation. You will then generate C code for the software portion and HDL for the hardware portion. You will review the generated reports and learn how you can integrate this code into your own embedded design.
1. In the focZynqTestBench model, double-click the Controller_Algorithm subsystem to open it.
Note the controller algorithm is partitioned into two components. The Algorithm_C block references the model focZynqC which specifies the portion of the algorithm which will be implemented in software. The Algorithm_HDL block references the model focZynqHDL which specifies the portion of the algorithm which will be implemented in hardware.
The focZynqC model specifies the mode scheduler and the velocity control loop, an open-loop velocity controller, and a routine to automatically calibrate the encoder offset
2. Run the task.t2_generateCCode shortcut to open the focZynqC model, generate C code, and generate a report.
You can explore the Code Generation report to see how the code corresponds to the model. If you are new to the Code Generation report, you may want to start with the Code Interface Report to view the function interface of the code.
The C code for the algorithm is portable and you could integrate it with any floating point embedded processor that has an ANSI-C compiler. You can integrate this code in the same manner that you would integrate hand-written C code.
The focZynqHdl model specifies the electrical position calculation, rotor velocity calculation, over-current checks, and the current controller (field-oriented controller).
2. Run the task.t3_generateHdlCode shortcut to open the focZynqHdl, generate HDL code, and generate a report.
You can explore the Code Generation report to see how the code corresponds to the model. If you are new to the HDL Code Generation report, you may want to start by exploring the Generated Source Files section of the report and selecting the focZynqHdl.vhd file which contains the entity specification.
The HDL code for the algorithm is portable and you could integrate it with any FPGA that support VHDL code. You can integrate this code in the same manner that you would integrate hand-written HDL code.
Task 4: Deploy bitstream to programmable logic
In this task, you will use the HDL Workflow Advisor to generate HDL code for the algorithm, package it into an IP core, integrate the IP core into a Xilinx reference design, and create a bitstream.
1. Run the task.t4_openHdlWorkflowAdvisor shortcut to open HDL Workflow Advisor configured for this example.
2. Select 1.1. Set Target Device and Synthesis Tool and note the Target platform is set to ZedBoard Motor Control.
ZedBoard Motor Control is a reference design created for this example. This reference design contains ADC, encoder, and PWM components. The reference design was created in Vivado using the technique described in Define and Register Custom Board and Reference Design for SoC Workflow.
3. Select 1.2. Set Target Interface to identify the ports. The Target Platform Interfaces with the prefix IP refer to connections that are registered with the ZedBoard Motor Control reference design.
4. Select 4.3 Build FPGA Bitstream > Run to Selected Task (or run the task.t5_generateBitstreamAndInterfaceBlock shortcut from the Simulink Project) to generate the HDL code for the algorithm and create the FPGA bitstream from the Xilinx reference design.
5. Follow the progress of bitstream generation on the new DOS Command Prompt that opens.
In addition to generating a bitstream, notice that the target is customized to generate a software interface library focZynqHdlAxiInterfaceLib. The library contains an AXI_Interface block which contains AXI4-Lite interface components. You will use this block in the next task when deploying to the ARM.
6. Run task 4.4 Program Target Device (or run the task.t6_downloadBitstream shortcut from the Simulink Project) to program the FPGA.
Task 5: Deploy executable to ARM processor
In this task you will generate C code for the controller, automate integrating this code with a Linux reference framework to create an executable, download the executable to the ARM, run the executable, log data and compare it to the simulation test bench results.
1. Run the task.t7_openZynqArmModel shortcut to open the focZynqArmDeployment model which enables deployment to the ARM.
The deployment model is configured to generate C code and automate integrating with a Linux ARM reference framework. The deployment model references the original controller model and also contains test stimulus, a scope, and the AXI interface library block that was created in the previous step.
2. Press the Run button to deploy and run the ARM executable.
When you press the Run button you start the process of generating code for the algorithm, test stimulus, and AXI interface. The code is then compiled against the reference framework to create an executable. This executable is downloaded to the ARM then executed. While executing, the scope signals are logged using External Mode. When the simulation stops, the logged signals are uploaded into the Simulation Data Inspector.
You can use the Simulation Data Inspector to view the logged signals and compare them to the signals logged previously from focZynqTestBench.
3. Select Simulation > Output > Simulation Data Inspector
4. In Simulation Data Inspector, select the rotorVelocity signal
Note that while in the encoder calibration mode the signals initially differ then agree, this is expected due to the fact that the simulation and hardware started at different rotor positions. While in closed loop velocity control the simulation and hardware results are very similar. Small differences occur because the simulation uses data sheet values for the motor and the actual motor has slightly different values due to manufacturing tolerances.
In this example you reviewed common tasks for designing a control algorithm and implementing it on a Zynq SoC. You verified algorithm behavior with desktop simulation, explored the hardware-software partitioning, and generated C and HDL code which you could integrate into your own embedded frameworks. You then automated the deployment of the algorithm into the embedded frameworks provided in this example and verified the behavior on hardware. You can continue to explore the files in this example to gain more insight into how simulation, code generation, and automation deployment can help you develop a controller for your hardware.
Starting with R2016b release, HDL Coder supports floating-point single precision data types. Run zynqexPMSMFOCSingleStart to open a floating-point model of the above example. The floating-point model highlights the ability of HDL Coder to generate HDL code from a model containing a mix of fixed-point and floating-point data types. Follow the tasks in an identical manner to implement the control algorithm with single precision current control on a Zynq SOC. To learn more about floating-point support in HDL Coder, refer to the help document on Native Floating Point and the online video HDL Coder: Native Floating Point.