def calculate(self, dt): self.Bemf = self.Ke * self.I[0] * self.Omega # Calculate current change in field coil if isnan(self.Vin[0]): self.I[0] = 0 else: dIf = (self.Vin[0] - self.I[0] * self.Rf) / self.Lf self.I[0] += dIf * dt # And in armature if isnan(self.Vin[1]): self.I[1] = 0 else: #dIa = (self.Va - self.Bemf - self.Ia*self.Ra) / self.La #self.Ia += dIa * dt self.I[1] = (self.Vin[1] - self.Bemf) / self.Ra self.T = self.Ke * self.I[0] * self.I[ 1] # Losses not taken into account -> mechanical power = electrical power # Calculate mechanical side Motor.calculate_mechanical(self, dt) #self.power = self.T * self.Omega return
def calculate(self, dt): self.Bemf = self.Ke * self.Omega # Calculate current change if isnan(self.Vin): self.I = 0 else: dI = (self.Vin - self.Bemf - self.I * self.R) / self.L self.I += dI * dt self.T = self.Ke * self.I # Losses not taken into account -> mechanical power = electrical power #self.P = self.Bemf * self.I # Calculate mechanical side Motor.calculate_mechanical(self, dt) return
def calculate(self, dt): alpha = 2.0 * 3.14159 / 3.0 # Coil interval in radians # Todo: calculate inductance variation due to salient poles, e.g. #La = self.Ld + self.Lq + (self.Lq - self.Ld) * cos(2*self.angle*self.polepairs + 3.14159/3.0) # todo: what are the phase angle offsets..? self.Vcommon = 0.0 nact = 0.0 for n in range(3): # Calculate common mode voltage if not isnan(self.Vin[n]): nact += 1.0 self.Vcommon += self.Vin[n] if nact != 0.0: self.Vcommon /= nact # Calculate effect of phases self.B = [0.0, 0.0, 0.0] dI = [0.0, 0.0, 0.0] self.T = 0.0 #ang = self.P * self.Theta + pi/6.0 # First coil position (electrical) TODO: Was like this ang = self.P * self.Theta for n in range(3): # Calculate magnetic flux at coil positions self.B[n] = self.Ke * sin(ang) # TODO: This was original... #self.B[n] = self.Ke * cos(ang) ang -= alpha # Next coil position (electrical) # Calculate back-emf at coil self.Bemf[n] = self.P * self.Omega * self.B[n] # If phase voltage is nan, then the phase is floating -> # force phase current to zero if isnan(self.Vin[n]): # Decrease other coil from which the current is flowing for k in range(3): if k != n and self.I[n] * self.I[k] < 0.0: self.I[k] += self.I[n] self.I[n] = 0 else: self.Vin[n] = self.Vin[n] - self.Vcommon dI[n] = (self.Vin[n] - self.Bemf[n] - self.R * self.I[n]) / self.Ld self.I[n] += dI[n] * dt # TODO: Force phase current sum to zero? isum = 0.0 for n in range(3): isum += self.I[n] if isum != 0.0: for n in range(3): if not isnan(self.Vin[n]): self.I[n] -= isum break # Add torque generated by each phase together for n in range(3): self.T += self.I[n] * self.B[n] # Calculate final torque self.T *= self.P # And calculate mechanical side Motor.calculate_mechanical(self, dt) # Handle HALL sensor outputs depending on rotor electrical angle # Accordign to https://e2e.ti.com/blogs_/b/motordrivecontrol/archive/2013/11/08/generate-your-own-commutation-table-trapezoidal-control-3-phase-bldc-motors-using-hall-sensors # TODO: Check if pi/6 offset is correct! ang = (self.P * self.Theta - pi / 6) % (2.0 * pi) if ang < pi: self.hall[0] = 1 else: self.hall[0] = 0 if ang >= (2.0 * pi / 3.0) and ang < (5.0 * pi / 3.0): self.hall[1] = 1 else: self.hall[1] = 0 if ang < (pi / 3.0) or ang >= (4.0 * pi / 3.0): self.hall[2] = 1 else: self.hall[2] = 0 return