Example #1
0
    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
Example #2
0
    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
Example #3
0
    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