Author Topic: PI Control in foc.cpp  (Read 213 times)

shivang1993

  • Active Member
  • *
  • Posts: 6
PI Control in foc.cpp
« on: June 24, 2019, 10:08:11 PM »
I have a couple of questions regarding the code given in foc.cpp:

1.  Are the int variables defined 16-bit or 32-bit? If they are 32-bit, then why the value of MAX_LIM and MIN_LIM (defined in foc.h) are 32767 and -32767, respectively, while using Clip32 function? Shouldn't it be 2^31 if the signed integer bit is 32 bit. The same happens for the integral error max and min value. While they are being stored as 48 bit signed integer, the maximum error value they can have is only 16777215 (line 40 in foc.cpp).

2. Whenever the PI control function is called, the set point is passed as negative of the actual value set. For eg. the speed PI control function is called as:
RPM_Out = PI_Control(RPM_filtered, -args[RPM_SP_REG], args[RPM_KP_REG], args[RPM_KI_REG], Mode_Change, RPM_GiE_prev). As we can see the set point is passed as the negative of args[RPM_SP_REG]. Why is that? Looking at the definition of the function as defined in lines 100-120, it should be passed as it is.

3. RPM_filtered, Id, Iq are also passed to status registers with negation. Why?

4. In the foc.h file, are the Kp, Ki values being stored in 16-bit registers or 32-bit?

5. Is there an example foc code available  with floating point operation instead of fixed-point arithmetic?

Andrei Errapart

  • Active Member
  • *
  • Posts: 25
Re: PI Control in foc.cpp
« Reply #1 on: June 25, 2019, 05:06:58 PM »
1.  Are the int variables defined 16-bit or 32-bit? If they are 32-bit, then why the value of MAX_LIM and MIN_LIM (defined in foc.h) are 32767 and -32767, respectively, while using Clip32 function? Shouldn't it be 2^31 if the signed integer bit is 32 bit. The same happens for the integral error max and min value. While they are being stored as 48 bit signed integer, the maximum error value they can have is only 16777215 (line 40 in foc.cpp).
The variables of type integer are 32-bit, because the fictional target for the C compiler in the HLS is a 32-bit microprocessor. 16-bit integers are usually used when the target microprocessor is 16-bit or 8-bit.

The definitions MAX_LIM and MIN_LIM are not for the numerical limits of the chosen variable type, but for the saturated 16-bit arithmetic. The intermediate results can occupy up to 32 bits in the case of multiplication. Not reserving enough bits for the intermediate results in undetected integer operation overflow and incorrect values.

The use of 32-bit variables was chosen out of convenience, because it matches the default size of integers and also the AXI bus transaction size.

You can optimize the storage space by using optimal bit width for the variables, but while optimizing you have to make sure that enough bits are used for the intermediate results.

2. Whenever the PI control function is called, the set point is passed as negative of the actual value set. For eg. the speed PI control function is called as:
RPM_Out = PI_Control(RPM_filtered, -args[RPM_SP_REG], args[RPM_KP_REG], args[RPM_KI_REG], Mode_Change, RPM_GiE_prev). As we can see the set point is passed as the negative of args[RPM_SP_REG]. Why is that? Looking at the definition of the function as defined in lines 100-120, it should be passed as it is.

3. RPM_filtered, Id, Iq are also passed to status registers with negation. Why?
I don't recall the exact circumstances, but at one point in the development it was necessary to invert the rotation direction. I think this is why there are the negations.


4. In the foc.h file, are the Kp, Ki values being stored in 16-bit registers or 32-bit?
All the registers contain 32-bit. The Kp, Ki have been specified to have fixed point format of Q16.16, e.g. 16 integer bits and 16 fractional bits.

5. Is there an example foc code available with floating point operation instead of fixed-point arithmetic?
No.

Let me note that the floating point operations are relatively expensive to implement in comparision to the equivalent fixed point arithmetic. See the documentation for the DSP slices DSP48E2 to see what integer arithmetic operations are directly supported by the hardware on the FPGA.

shivang1993

  • Active Member
  • *
  • Posts: 6
Re: PI Control in foc.cpp
« Reply #2 on: July 08, 2019, 10:33:54 PM »
Thank you so much Andrei for the quick response. I am using a different motor with the board and I have a few more queries about the evaluation board:

1. Do I have to build the project from scratch every time I make some changes to foc.h file? It takes about 30 minutes for the complete build process. Is there any shortcut to build only the incremental change?

2. Do I need to change the value of CPR in focserver.h file if I am using a different encoder? I changed the value in foc.h and sin_cos_table.h but don't know if "ppr" variable in focserver.h also needs to be changed.

3. Also if I want to change something in focserver.conf file (like the Kp and Ki values), do I need to build the project as usual or are there any extra steps involved as well?

4. Is there a possibility to get the PCB sheet with the complete layout of the EDPS board? In the EDPS user manual, the basic block diagram is given but not the complete layout of the board.

shivang1993

  • Active Member
  • *
  • Posts: 6
Re: PI Control in foc.cpp
« Reply #3 on: July 09, 2019, 10:35:36 PM »
I also have a couple of other queries :

1. The outputs of foc.cpp is the pwm pulse made by the three phase voltages: pwm = MAKE_DATA4(Van, Vbn, Vcn, 0). This means all the phase voltages are only occupying 16 bits each. Going by the resolution of pwm (=0.0003662), this means a maximum of 12 V on each phase voltage. While this enough for the motor that came with the kit, this is not enough for an external motor which I am trying to power using a 48 V DC supply. So my question is whether the resolution of pwm gets modified automatically (according to the magnitude of dc bus) or do we have to externally change it so as to accommodate higher voltages than 12 V? If so, how do we change the pwm resolution?

2. Also how can we observe pwm frequency and change it as needed? I could not find any necessary file for doing this in the folder obtained from Github. Will we need Xilinx Vivado for doing that? So far I have been just using Xilinx SDSoC for the control.

Thanks

Andrei Errapart

  • Active Member
  • *
  • Posts: 25
Re: PI Control in foc.cpp
« Reply #4 on: July 10, 2019, 06:59:34 PM »
1. Do I have to build the project from scratch every time I make some changes to foc.h file? It takes about 30 minutes for the complete build process. Is there any shortcut to build only the incremental change?
Yes. There is no way around it.

2. Do I need to change the value of CPR in focserver.h file if I am using a different encoder? I changed the value in foc.h and sin_cos_table.h but don't know if "ppr" variable in focserver.h also needs to be changed.
CPR has to match the number of pulses per revolution of the encoder.
PPR has to match the number of poles of the motor.

3. Also if I want to change something in focserver.conf file (like the Kp and Ki values), do I need to build the project as usual or are there any extra steps involved as well?
Not really.

For temporary changes you can just edit the file in the running system and restart focserver by executing the following command on the console
Code: [Select]
/etc/init.d/focinit restart
For permanent changes, see the file "init.sh" on the SD card. There are commands to copy the file "focserver.conf", but they are commented out. Uncomment them. You can find the "init.sh" script in the repository at "focserver/files/sd_card/init.sh". Place your copy of the "focserver.conf" to the SD card and restart the board.

4. Is there a possibility to get the PCB sheet with the complete layout of the EDPS board? In the EDPS user manual, the basic block diagram is given but not the complete layout of the board.
Please take the trouble to send e-mail with that request to support@trenz-electronic.de . You might be asked additional questions.

Andrei Errapart

  • Active Member
  • *
  • Posts: 25
Re: PI Control in foc.cpp
« Reply #5 on: July 10, 2019, 08:27:36 PM »
1. The outputs of foc.cpp is the pwm pulse made by the three phase voltages: pwm = MAKE_DATA4(Van, Vbn, Vcn, 0). This means all the phase voltages are only occupying 16 bits each. Going by the resolution of pwm (=0.0003662), this means a maximum of 12 V on each phase voltage. While this enough for the motor that came with the kit, this is not enough for an external motor which I am trying to power using a 48 V DC supply. So my question is whether the resolution of pwm gets modified automatically (according to the magnitude of dc bus) or do we have to externally change it so as to accommodate higher voltages than 12 V? If so, how do we change the pwm resolution?
The conversion constant is valid only when the power supply voltage is 12V as well. The focserver doesn't automatically take into account that you have supplied 48V instead of 12V.

The conversion factor "pwm2V" is used in the UI only.

2. Also how can we observe pwm frequency and change it as needed? I could not find any necessary file for doing this in the folder obtained from Github. Will we need Xilinx Vivado for doing that? So far I have been just using Xilinx SDSoC for the control.
The PWM frequency is a design-time paramater of the PWM IP core block.

To change it, start the Vivado that came with Vivado SDSoC by starting "Xilinx\SDx\2017.1\Vivado\bin\vivado.bat" and open the corresponding platform design, for example, "IIoT-EDDP\SDSoC\platforms\arty_z7_10_foc\hw\vivado\arty_z7_10_foc.xpr"

By the way, when you change the PWM frequency, the actual resolution of the PWM changes; the IP core automatically scales the 16-bit input parameters to match the actual resolution of the PWM.

shivang1993

  • Active Member
  • *
  • Posts: 6
Re: PI Control in foc.cpp
« Reply #6 on: July 22, 2019, 10:39:28 PM »
Hey Andrei,

1. How can I save the output of a status register (for example Angle) in a file on my local pc while the motor is running?

2. I am trying to change the motor speed set point continuously by changing the register RPMSp in the serial console. Is there a way to automate this so that I do not have to keep changing it manually?

3. A couple of hardware blocks have been implemented as an IP core like the PWM core (zsys_axis_pwm_0_0). Can we modify the implementation in this IP Core? If so, what is the procedure?

4. This motor control was implemented using SDSoC but it looks like everything can be implemented using Vivado HLS as well by integrating all the IP cores given in "IIoT-EDDP\HLS\ARTY_Z7_FULL". While I could find all the IP Cores individually, I could not locate the .xpr file which included all the IP cores together just like with SDSoC. So do you provide that particular file or do we have to integrate all the separate IP Cores in order to use Vivado to create the bitstream file. This would help us in avoiding the use of Xilinx SDSoC.

Thanks
Shivang