Exemplo n.º 1
0
        private void bt_show_maxtorque_capa_curve_Click(object sender, EventArgs e)
        {
            try
            {
                double Imax      = double.Parse(tb_Imax.Text);
                double Umax      = double.Parse(tb_Umax.Text);
                double max_speed = double.Parse(tb_maxSpeed.Text);
                MaxtorqueCapabilityCurve mtcc = buildMaxtorqueCapabilityCurve(50, Imax, Umax, max_speed);
                VoltageLimitCurve        vlc  = buildVoltageLimitCurve(50, Imax, Umax, max_speed);

                GraphWindow tc = new GraphWindow();
                tc.addData("Torque-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.maxtorques.ToArray()));
                tc.addData("Current-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.currents.Select(f => f.Magnitude).ToArray()));
                tc.addData("CurrentPhase-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.currents.Select(f => f.Phase).ToArray()));
                tc.addData("Voltage-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.voltages.Select(f => f.Magnitude).ToArray()));
                tc.addData("Power-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.power.ToArray()));
                tc.addData("Efficiency", new PointPairList(mtcc.speeds.ToArray(), mtcc.effs.ToArray()));
                tc.addData("Boundary-Torque-speed1", new PointPairList(vlc.speeds.ToArray(), vlc.torques.ToArray()));
                tc.addData("(iq,id)", new PointPairList(mtcc.currents.Select(f => f.d).ToArray(), mtcc.currents.Select(f => f.q).ToArray()));
                tc.addData("id-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.currents.Select(f => f.d).ToArray()));
                tc.addData("iq-speed", new PointPairList(mtcc.speeds.ToArray(), mtcc.currents.Select(f => f.q).ToArray()));

                tc.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }
Exemplo n.º 2
0
        private void bt_showmap_Click(object sender, EventArgs e)
        {
            bool   success = true;
            double Imax    = 0;

            success = success && double.TryParse(tb_Imax.Text, out Imax);
            double Umax = 0;

            success = success && double.TryParse(tb_Umax.Text, out Umax);
            double max_speed = 0;

            success = success && double.TryParse(tb_maxSpeed.Text, out max_speed);

            string config = string.Format("{0},{1},{2}", Imax, Umax, max_speed);

            MapType maptype = MapType.power;

            Enum.TryParse <MapType>(comboBox_maptype.Text, true, out maptype);

            if (!success)
            {
                MessageBox.Show("Error parse text to double");
                return;
            }

            var mtpa = buildTableMaxtorquePerAmple();

            int    n  = 100;
            double x0 = 0;
            double x1 = max_speed;
            double y0 = 0;
            double y1 = mtpa.GetMaxTorqueWithCurrentMagnitude(Imax);

            if (last_config != config)
            {
                effMap      = buildEfficiencyMap(50, 100, Imax, Umax, max_speed);
                last_config = config;
            }

            var    data  = effMap.power;
            string title = "Power (W)";

            switch (maptype)
            {
            case MapType.power:
                data  = effMap.power;
                title = "Power (W)";
                break;

            case MapType.efficiency:
                data  = effMap.efficiency;
                title = "Efficiency (%)";
                break;

            case MapType.windingloss:
                data  = effMap.windingloss;
                title = "Winding loss (W)";
                break;

            case MapType.rotor_coreloss:
                data  = effMap.rotor_coreloss;
                title = "Rotor core loss (W)";
                break;

            case MapType.stator_coreloss:
                data  = effMap.stator_coreloss;
                title = "Stator loss (W)";
                break;

            case MapType.coreloss:
                data  = effMap.coreloss;
                title = "Core loss (W)";
                break;

            case MapType.total_loss:
                data  = effMap.totalloss;
                title = "Total loss (W)";
                break;

            case MapType.voltage:
                data  = effMap.voltage;
                title = "Voltage (V)";
                break;

            case MapType.current:
                data  = effMap.current;
                title = "Current (A)";
                break;

            case MapType.beta:
                data  = effMap.beta;
                title = "Beta (degree)";
                break;

            case MapType.Ld:
                data  = effMap.Ld;
                title = "Ld (mH)";
                break;

            case MapType.Lq:
                data  = effMap.Lq;
                title = "Ld (mH)";
                break;

            default:
                break;
            }

            double fmin = double.MaxValue;

            for (int i = 0; i < data.GetLength(0); i++)
            {
                for (int j = 0; j < data.GetLength(1); j++)
                {
                    if (data[i, j] >= 0 && fmin > data[i, j])
                    {
                        fmin = data[i, j];
                    }
                }
            }

            var model = new PlotModel
            {
                Title = title,
            };

            model.Axes.Add(new LinearColorAxis
            {
                Position  = AxisPosition.Right,
                Palette   = OxyPalettes.Jet(500),
                HighColor = OxyColors.Gray,
                LowColor  = OxyColors.White,
                Minimum   = fmin,
                //Maximum = 100,
                Title = title
            });

            model.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Bottom,
                Title    = "Speed",
                //MajorGridlineStyle = LineStyle.Solid,
                //MinorGridlineStyle = LineStyle.Solid,
                //MajorGridlineColor = OxyColor.FromAColor(40, c),
                //MinorGridlineColor = OxyColor.FromAColor(20, c)
            });

            model.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Left,
                Title    = "Torque",
                //AbsoluteMinimum = 0,
                //Minimum = 0,
                //MajorGridlineStyle = LineStyle.Solid,
                //MinorGridlineStyle = LineStyle.Solid,
                //MajorGridlineColor = OxyColor.FromAColor(40, c),
                //MinorGridlineColor = OxyColor.FromAColor(20, c)
            });

            var hms = new HeatMapSeries
            {
                X0          = x0,
                X1          = x1,
                Y0          = y0,
                Y1          = y1,
                Data        = data,
                Interpolate = true,
            };

            model.Series.Add(hms);

            // contour
            var cs = new ContourSeries
            {
                //Color = OxyColors.Gray,
                //FontSize = 12,
                //ContourLevelStep = double.NaN,
                //LabelBackground = OxyColors.White,
                ColumnCoordinates = effMap.speed_points,
                RowCoordinates    = effMap.torque_points,
                Data = data,
            };

            if (cs.Data == effMap.efficiency)
            {
                cs.ContourLevels = new double[] { 0, 20, 40, 60, 80, 90, 91, 92, 93, 94, 95, 95.2, 95.4, 95.6, 95.8, 96, 96.2, 97, 98, 99 };
                model.Series.Add(cs);
            }

            // max-torque capability curve
            MaxtorqueCapabilityCurve mtcc = buildMaxtorqueCapabilityCurve(100, Imax, Umax, max_speed);
            var mtcc_series = new LineSeries()
            {
                LineStyle       = LineStyle.Solid,
                Color           = OxyColor.FromArgb(255, 0, 0, 0),
                StrokeThickness = 3,
            };

            for (int i = 0; i < mtcc.speeds.Count; i++)
            {
                mtcc_series.Points.Add(new OxyPlot.DataPoint(mtcc.speeds[i], mtcc.maxtorques[i]));
            }
            model.Series.Add(mtcc_series);

            // voltage limit curve 1
            VoltageLimitCurve vlc = buildVoltageLimitCurve(100, Imax, Umax, max_speed);
            var vlc_series        = new LineSeries()
            {
                LineStyle       = LineStyle.Dash,
                StrokeThickness = 1,
            };

            for (int i = 0; i < vlc.speeds.Count; i++)
            {
                vlc_series.Points.Add(new OxyPlot.DataPoint(vlc.speeds[i], vlc.torques[i]));
            }
            model.Series.Add(vlc_series);

            plot.Model = model;
        }
Exemplo n.º 3
0
        private EfficiencyMap buildEfficiencyMap(int torque_count, int speed_count, double Imax, double Umax, double max_speed)
        {
            MaxtorqueCapabilityCurve mtcc = buildMaxtorqueCapabilityCurve(speed_count, Imax, Umax, max_speed);
            VoltageLimitCurve        vlc  = buildVoltageLimitCurve(speed_count, Imax, Umax, max_speed);

            var em = new EfficiencyMap()
            {
                // input
                Imax     = Imax,
                Umax     = Umax,
                MaxSpeed = max_speed,

                // axis
                speed_points  = new double[speed_count + 1],
                torque_points = new double[torque_count + 1],

                // value
                power           = new double[speed_count + 1, torque_count + 1],
                windingloss     = new double[speed_count + 1, torque_count + 1],
                rotor_coreloss  = new double[speed_count + 1, torque_count + 1],
                stator_coreloss = new double[speed_count + 1, torque_count + 1],
                coreloss        = new double[speed_count + 1, torque_count + 1],
                totalloss       = new double[speed_count + 1, torque_count + 1],
                efficiency      = new double[speed_count + 1, torque_count + 1],

                voltage = new double[speed_count + 1, torque_count + 1],
                current = new double[speed_count + 1, torque_count + 1],
                beta    = new double[speed_count + 1, torque_count + 1],
                Ld      = new double[speed_count + 1, torque_count + 1],
                Lq      = new double[speed_count + 1, torque_count + 1],
            };

            em.power.Fill2D(double.NaN);
            em.windingloss.Fill2D(double.NaN);
            em.rotor_coreloss.Fill2D(double.NaN);
            em.stator_coreloss.Fill2D(double.NaN);
            em.coreloss.Fill2D(double.NaN);
            em.totalloss.Fill2D(double.NaN);
            em.efficiency.Fill2D(double.NaN);

            em.voltage.Fill2D(double.NaN);
            em.current.Fill2D(double.NaN);
            em.beta.Fill2D(double.NaN);
            em.Ld.Fill2D(double.NaN);
            em.Lq.Fill2D(double.NaN);

            var    mtpa  = buildTableMaxtorquePerAmple();
            double max_t = mtpa.GetMaxTorqueWithCurrentMagnitude(Imax);

            LinearSpline torqueCapabilityLimit = LinearSpline.Interpolate(mtcc.speeds, mtcc.maxtorques);

            for (int i = 0; i < speed_count + 1; i++)
            {
                for (int j = 0; j < torque_count + 1; j++)
                {
                    // speed
                    double speed = max_speed * i / speed_count;
                    em.speed_points[i] = speed;

                    // torque
                    double t = max_t * j / torque_count;
                    em.torque_points[j] = t;
                    double max_possible_torque = torqueCapabilityLimit.Interpolate(speed);
                    if (t > max_possible_torque)
                    {
                        continue;
                    }

                    // speed limit 1
                    double speed1 = vlc.GetMaxSpeedForTorque(t);

                    APointData data = null;

                    if (t == 0)
                    {
                        data = calculatePointdata(0, 0, speed);
                    }
                    // zone 1
                    else if (speed <= speed1)
                    {
                        Fdq idq = mtpa.GetCurrentForTorque(t);
                        if (double.IsNaN(idq.d) || double.IsNaN(idq.q))
                        {
                            data = null;
                        }
                        else
                        {
                            data = calculatePointdata(idq.d, idq.q, speed);
                        }
                    }
                    else
                    {
                        Fdq idq = getCurrentForZone2(t, speed, Imax, Umax);
                        if (double.IsNaN(idq.d) || double.IsNaN(idq.q))
                        {
                            data = null;
                        }
                        else
                        {
                            data = calculatePointdata(idq.d, idq.q, speed);
                        }
                    }

                    if (data != null)
                    {
                        em.rotor_coreloss[i, j]  = data.rotorloss;
                        em.stator_coreloss[i, j] = data.statorloss;
                        em.coreloss[i, j]        = data.rotorloss + data.statorloss;
                        em.windingloss[i, j]     = data.copperloss;
                        em.totalloss[i, j]       = data.copperloss + data.rotorloss + data.statorloss;
                        em.power[i, j]           = data.power;
                        em.efficiency[i, j]      = 100 * data.power / (data.power + em.totalloss[i, j]);

                        em.voltage[i, j] = data.voltage;
                        em.current[i, j] = data.current;
                        em.beta[i, j]    = data.beta;
                        em.Ld[i, j]      = double.IsNaN(data.Ld) || data.Ld < 0 ? -0.0001 : data.Ld * 1000; //to mH
                        em.Lq[i, j]      = double.IsNaN(data.Ld) || data.Ld < 0 ? -0.0001 : data.Lq * 1000; //to mH
                    }
                }
            }

            return(em);
        }
Exemplo n.º 4
0
        private MaxtorqueCapabilityCurve buildMaxtorqueCapabilityCurve(int count = 50, double Imax = 55, double Umax = 140, double max_speed = 6000)
        {
            var mtpa = buildTableMaxtorquePerAmple();

            MaxtorqueCapabilityCurve mtcc = new MaxtorqueCapabilityCurve()
            {
                Imax     = Imax,
                Umax     = Umax,
                MaxSpeed = max_speed,
            };

            // Look for beta to get max torque

            double max_t = mtpa.GetMaxTorqueWithCurrentMagnitude(Imax);
            Fdq    idq   = mtpa.GetCurrentForTorque(max_t);

            // Create PointPairList
            // look for speed1
            var speed1 = Brent.FindRoot(s =>
            {
                var data_ = calculatePointdata(idq.d, idq.q, s);
                var u_    = Math.Sqrt(data_.ud * data_.ud + data_.uq * data_.uq);
                return(u_ - Umax);
            }, 100, max_speed, 1e-3);

            // speed by speed
            int count1 = (int)(speed1 / max_speed * count) + 1;
            int count2 = count - count1;

            for (int i = 1; i < count1 + 1; i++)
            {
                double speed = speed1 * i / count1;

                var data = calculatePointdata(idq.d, idq.q, speed);

                mtcc.speeds.Add(speed);
                mtcc.maxtorques.Add(data.torque);
                mtcc.currents.Add(idq);
                mtcc.voltages.Add(new Fdq()
                {
                    d = data.ud, q = data.uq
                });
                mtcc.power.Add(data.power);
                mtcc.effs.Add(data.efficiency);
            }

            double t = max_t;

            for (int i = 1; i < count2 + 1; i++)
            {
                double speed = speed1 + (max_speed - speed1) * i / count2;

                // find beta which make U=Umax
                //double beta = 0;
                //bool success = Brent.TryFindRoot(b =>
                //{
                //    var data_ = calculatePointdata(Imax * Math.Cos(b * Math.PI / 180), Imax * Math.Sin(b * Math.PI / 180), speed);
                //    var u_ = Math.Sqrt(data_.ud * data_.ud + data_.uq * data_.uq);
                //    return u_ - Umax;
                //}, 100, 180, 1e-5, 100, out beta);

                // Here:
                // Find Id,Iq that bring max torque at speed
                // it is intersect of circle Imax and ellipse Umax/w if Imax < ellipse center (-psiM/Ld)
                // or ellipse center itself if Imax > ellipse center

                Fdq  idq2  = default(Fdq);
                bool found = false;

                var vle = buildVoltageLimitEllipse(speed, 1000, Imax, Umax);

                var maxtorque_point = vle.curve[vle.maxtorque_point];
                var minid_point     = vle.curve[vle.minid_point];

                if (maxtorque_point.Magnitude <= Imax)
                {
                    idq2 = new Fdq {
                        d = maxtorque_point.d, q = maxtorque_point.q
                    };
                    found = true;
                }
                else if (minid_point.Magnitude > Imax) //Imax out of ellipse
                {
                    found = false;
                }
                else
                {
                    var range = Enumerable.Range(0, vle.maxtorque_point);

                    LinearSpline spline = LinearSpline.Interpolate(range.Select(k => vle.curve[k].Magnitude), range.Select(k => vle.curve[k].d));
                    double       id     = spline.Interpolate(Imax);
                    double       iq     = Math.Sqrt(Imax * Imax - id * id);
                    idq2 = new Fdq {
                        d = id, q = iq
                    };
                    found = true;
                }

                if (found)
                {
                    //double id = idq2.d;//Imax * Math.Cos(beta * Math.PI / 180);
                    //double iq = idq2.q;//Imax * Math.Sin(beta * Math.PI / 180);
                    var data = calculatePointdata(idq2.d, idq2.q, speed);

                    mtcc.speeds.Add(speed);
                    mtcc.maxtorques.Add(data.torque);
                    mtcc.currents.Add(idq2);
                    mtcc.voltages.Add(new Fdq()
                    {
                        d = data.ud, q = data.uq
                    });
                    mtcc.power.Add(data.power);
                    mtcc.effs.Add(data.efficiency);
                }
            }

            return(mtcc);
        }