Newer
Older
*
* Developed by Graz University of Technology,
* Institute of Internal Combustion Engines and Thermodynamics,
* Institute of Technical Informatics
*
* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
* by the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use VECTO except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
*
* Unless required by applicable law or agreed to in writing, VECTO
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* Authors:
* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System;
using System.Collections.Generic;

Markus Quaritsch
committed
using System.IO;
using System.Linq;
using NUnit.Framework;
using TUGraz.VectoCommon.InputData;

Markus Quaritsch
committed
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.FileIO.JSON;
using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;

Markus Quaritsch
committed
using TUGraz.VectoCore.InputData.Reader;
using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;

Markus Quaritsch
committed
using TUGraz.VectoCore.Tests.Utils;
using TUGraz.VectoCore.Utils;

Markus Quaritsch
committed
using Point = TUGraz.VectoCommon.Utils.Point;
namespace TUGraz.VectoCore.Tests.Models.Declaration
{
public class ShiftPolygonTest
{
public void RunBeforeAnyTests()
{
Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
}
public void IntersectShiftLines1()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var transformed = new[] {
new Point(8, 0),
new Point(8, 8),
new Point(18, 22)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
}
}
public void IntersectShiftLines2()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var transformed = new[] {
new Point(8, 0),
new Point(8, 6),
new Point(18, 14)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 7.6),
new Point(20, 15.6),
};
var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
}
result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
}
}
public void IntersectShiftLines3()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var transformed = new[] {
new Point(8, 0),
new Point(8, 4),
new Point(18, 22)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 7.6),
new Point(13, 13),
new Point(20, 20),
};
var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
}
result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
}
}
public void IntersectShiftLines4()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var transformed = new[] {
new Point(8, 0),
new Point(8, 12),
new Point(18, 16)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(14.6666, 14.6666),
new Point(20, 16.8),
};
var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift);
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
}
[TestCase]
public void LimitShiftlines1()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var limit = new[] {
new Point(8, 0),
new Point(8, 20)
};
var expected = new[] {
new Point(8, 0),
new Point(8, 20)
};
var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
}
[TestCase]
public void LimitShiftlines2()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var limit = new[] {
new Point(15, 0),
new Point(15, 20)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(15, 15),
new Point(15, 20),
};
var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
}
[TestCase]
public void LimitShiftlines3()
{
var upShift = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var limit = new[] {
new Point(25, 0),
new Point(25, 20)
};
var expected = new[] {
new Point(10, 0),
new Point(10, 10),
new Point(20, 20),
};
var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit);
Assert.AreEqual(expected.Length, result.Length);
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
}
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
public void ShiftPolygonFldMarginTest()
{
var engineFld = new[] {
new Point(8, 10),
new Point(9, 11),
new Point(10, 11.5),
new Point(11, 12),
new Point(12, 12.5),
new Point(13, 13),
new Point(14, 13.5),
new Point(15, 14),
new Point(16, 14.5),
new Point(17, 15),
new Point(18, 16.5),
new Point(19, 18),
new Point(20, 19.5),
new Point(21, 21),
new Point(22, 22.5),
};
var expected = new[] {
new Point(8, 9.8),
new Point(9, 10.78),
new Point(10, 11.27),
new Point(11, 11.76),
new Point(12, 12.25),
new Point(13, 12.74),
new Point(14, 13.23),
new Point(15, 13.72),
new Point(16, 14.21),
new Point(17, 14.7),
new Point(18, 16.17),
new Point(19, 17.64),
new Point(20, 19.11),
new Point(21, 20.58),
new Point(22, 22.05),
};
var result =
DeclarationData.Gearbox.ShiftPolygonFldMargin(
engineFld.Select(
p =>

Markus Quaritsch
committed
new EngineFullLoadCurve.FullLoadCurveEntry() {
EngineSpeed = p.X.SI<PerSecond>(),
TorqueFullLoad = p.Y.SI<NewtonMeter>()
}).ToList(),
23.SI<PerSecond>());
foreach (var tuple in expected.Zip(result, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
}
}
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
public void CorrectDownShiftByEngineFldTest()
{
var downshift = Edge.Create(new Point(10, 10), new Point(22, 20));
var engineFldCorr = new[] {
new Point(8, 9.8),
new Point(9, 10.78),
new Point(10, 11.27),
new Point(11, 11.76),
new Point(12, 12.25),
new Point(13, 12.74),
new Point(14, 13.23),
new Point(15, 13.72),
new Point(16, 14.21),
new Point(17, 14.7),
new Point(18, 16.17),
new Point(19, 17.64),
new Point(20, 19.11),
new Point(21, 20.58),
new Point(22, 22.05),
};
var corrected = DeclarationData.Gearbox.MoveDownshiftBelowFld(downshift, engineFldCorr, 20.SI<NewtonMeter>());
Assert.AreEqual(10, corrected.P1.X, 1e-3);
Assert.AreEqual(8.86666, corrected.P1.Y, 1e-3);
Assert.AreEqual(23.36, corrected.P2.X, 1e-3);
Assert.AreEqual(20, corrected.P2.Y, 1e-3);
}
public void ComputeShiftPolygonDeclarationTest()
{
var engineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
var rdyn = 0.4882675.SI<Meter>();
var axlegearRatio = 2.59;
var expectedDownshift = new[] {
// Gear 1
new[] {
new Point(64.50736915, -352),
new Point(64.50736915, 970.37),
new Point(121.059, 2530),
},
// Gear 2
new[] {
new Point(64.50736915, -352),
new Point(64.50736915, 970.37),
new Point(121.059, 2530),
},
// Gear 3
new[] {
new Point(64.50736915, -352),
new Point(64.50736915, 970.37),
new Point(121.059, 2530),
},
};
var expectedUpshift = new[] {
// Gear 1
new[] {
new Point(136.9338946, -352),
new Point(136.9338946, 1281.30911),
new Point(201.7326, 2427.6748),
},
// Gear 2
new[] {
new Point(136.9338946, -352),
new Point(136.9338946, 1281.30911),
new Point(203.9530, 2466.9558),
},
// Gear 3
new[] {
new Point(136.9338946, -352),
new Point(136.9338946, 1281.30911),
//new Point(153.606666, 1893.19273),
new Point(201.3375, 2420.6842),
},
};
var dao = new DeclarationDataAdapter();
var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
var engineData = dao.CreateEngineData(new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile),
null,

Markus Quaritsch
committed
gearboxData, new List<ITorqueLimitInputData>());
var shiftPolygons = new List<ShiftPolygon>();

Markus Quaritsch
committed
for (var i = 0; i < gearboxData.Gears.Count; i++) {
shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(GearboxType.AMT, i,
engineData.FullLoadCurves[(uint)(i + 1)],

Markus Quaritsch
committed
gearboxData.Gears,
engineData, axlegearRatio, rdyn));
}
for (var i = 0; i < Math.Min(gearboxData.Gears.Count, expectedDownshift.Length); i++) {
foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
}
foreach (var tuple in expectedUpshift[i].Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
}
}
Assert.AreEqual(0, shiftPolygons.First().Downshift.Count);
Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
}
[TestCase]
public void ComputeShiftPolygonATDeclarationTest()
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
{
var engineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
var rdyn = 0.4882675.SI<Meter>();
var axlegearRatio = 2.59;
var expectedDownshift = new[] {
new Point(73.3038, -352),
new Point(73.3038, 2530),
};
var expectedUpshift = new[] {
new Point(94.2478, -352),
new Point(94.2478, 0),
new Point(123.0457, 2530),
};
var dao = new DeclarationDataAdapter();
var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
var engineData = dao.CreateEngineData(new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile),
null,
gearboxData, new List<ITorqueLimitInputData>());
var shiftPolygons = new List<ShiftPolygon>();
for (var i = 0; i < gearboxData.Gears.Count; i++) {
shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(GearboxType.ATSerial, i,
engineData.FullLoadCurves[(uint)(i + 1)],
gearboxData.Gears,
engineData, axlegearRatio, rdyn));
}
for (var i = 0; i < gearboxData.Gears.Count; i++) {
foreach (var tuple in expectedDownshift.Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
}
foreach (var tuple in expectedUpshift.Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
}
}
Assert.AreEqual(0, shiftPolygons.First().Downshift.Count);
Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
}
public void ComputeShiftPolygonDeclarationTestConfidentialEngine()
//var engineFldFile = @"E:\QUAM\Downloads\EngineFLD\Map_375c_BB1390_modTUG_R49_375c_BB1386.vfld";
//var engineFldFile = @"E:\QUAM\tmp\scania_fullload_shiftpolygon-test.csv";
//var gearboxFile = @"E:\QUAM\Downloads\TUG_dev_gbx\TUG_dev\GRS905R.vgbx";
var engineFldFile = @"E:\QUAM\Downloads\attachment\Models_Declaration-mode\Overdrive\text\VENG_330kW_GENERIC.vfld";
var gearboxFile = @"E:\QUAM\Downloads\attachment\Models_Declaration-mode\Overdrive\text\VGBX_AMT_12_overdr_DECL.vgbx";

Markus Quaritsch
committed
//@"TestData\Components\40t_Long_Haul_Truck.vgbx";
if (!File.Exists(engineFldFile)) {
Assert.Inconclusive("Confidential File not found. Test cannot run without file.");
var rdyn = DeclarationData.Wheels.Lookup("315/70 R22.5").DynamicTyreRadius; //0.4882675.SI<Meter>();
//var axlegearRatio = 3.71; //2.31; // 3.71; //2.59;

Markus Quaritsch
committed
var gearboxData = new JSONGearboxDataV6(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
var axlegearRatio = gearboxData.Ratio;
var engineData = new CombustionEngineData() {

Markus Quaritsch
committed
var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>();

Markus Quaritsch
committed
fullLoadCurves[0] = FullLoadCurveReader.ReadFromFile(engineFldFile, true);

Markus Quaritsch
committed
fullLoadCurves[0].EngineData = engineData;
for (uint i = 1; i <= gearboxData.Gears.Count; i++) {
fullLoadCurves[i] = AbstractSimulationDataAdapter.IntersectFullLoadCurves(fullLoadCurves[0],
gearboxData.Gears[(int)(i - 1)].MaxTorque);
}
engineData.FullLoadCurves = fullLoadCurves;
var shiftPolygons = new List<ShiftPolygon>();
var downshiftTransformed = new List<List<Point>>();
var downshiftOrig = new List<List<Point>>();
var upshiftOrig = new List<List<Point>>();
for (var i = 0; i < gearboxData.Gears.Count; i++) {
shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(GearboxType.AMT, i, fullLoadCurves[(uint)(i + 1)],
gearboxData.Gears,
engineData, axlegearRatio, rdyn));
List<Point> tmp1, tmp2, tmp3;

Markus Quaritsch
committed

Markus Quaritsch
committed
ShiftPolygonComparison.ComputShiftPolygonPoints(i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,
engineData, axlegearRatio, rdyn, out tmp1, out tmp2, out tmp3);
upshiftOrig.Add(tmp1);
downshiftTransformed.Add(tmp2);

Markus Quaritsch
committed
ShiftPolygonDrawer.DrawShiftPolygons(Path.GetDirectoryName(gearboxFile), fullLoadCurves, shiftPolygons,
Path.Combine(Path.GetDirectoryName(gearboxFile), "Shiftlines.png"),
DeclarationData.Gearbox.TruckMaxAllowedSpeed / rdyn * axlegearRatio * gearboxData.Gears.Last().Ratio, upshiftOrig,
downshiftTransformed, downshiftOrig);
var shiftLines = "";
var gear = 1;
foreach (var shiftPolygon in shiftPolygons) {
shiftLines += "Gear " + gear + "\n";
shiftLines += "Upshift\n";
foreach (var shiftPolygonEntry in shiftPolygon.Upshift) {
shiftLines += string.Format("{0} {1}\n", shiftPolygonEntry.AngularSpeed.AsRPM, shiftPolygonEntry.Torque.Value());
}
shiftLines += "Downshift\n";
foreach (var shiftPolygonEntry in shiftPolygon.Downshift) {
shiftLines += string.Format("{0} {1}\n", shiftPolygonEntry.AngularSpeed.AsRPM, shiftPolygonEntry.Torque.Value());
}
}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
[TestCase]
public void ComputeShiftPolygonDeclarationTestConfidentialXMLJob()
{
var jobFile = @"E:\QUAM\Downloads\upshifts-missing_over-revving\FL_curve_orig.xml";
if (!File.Exists(jobFile)) {
Assert.Inconclusive("Confidential File not found. Test cannot run without file.");
}
var job = new XMLDeclarationInputDataProvider(jobFile, true);
var gearboxData = job.JobInputData.Vehicle.GearboxInputData;
var idlespeed = VectoMath.Max(
job.JobInputData.Vehicle.EngineIdleSpeed, job.JobInputData.Vehicle.EngineInputData.IdleSpeed);
var dao = new DeclarationDataAdapter();
var engineData = dao.CreateEngineData(
job.JobInputData.Vehicle.EngineInputData, idlespeed, gearboxData, job.JobInputData.Vehicle.TorqueLimits);
var axlegearRatio = job.JobInputData.Vehicle.AxleGearInputData.Ratio;
var rdyn = job.JobInputData.Vehicle.Axles.Where(x => x.AxleType == AxleType.VehicleDriven)
.Select(x => DeclarationData.Wheels.Lookup(x.Tyre.Dimension)).Average(x => x.DynamicTyreRadius.Value())
.SI<Meter>();
var fullLoadCurves = engineData.FullLoadCurves;
var gearboxFile = jobFile;
var shiftPolygons = new List<ShiftPolygon>();
var downshiftTransformed = new List<List<Point>>();
var downshiftOrig = new List<List<Point>>();
var upshiftOrig = new List<List<Point>>();
for (var i = 0; i < gearboxData.Gears.Count; i++) {
shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(GearboxType.AMT, i, fullLoadCurves[(uint)(i + 1)],
gearboxData.Gears,
engineData, axlegearRatio, rdyn));
List<Point> tmp1, tmp2, tmp3;
ShiftPolygonComparison.ComputShiftPolygonPoints(i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,
engineData, axlegearRatio, rdyn, out tmp1, out tmp2, out tmp3);
upshiftOrig.Add(tmp1);
downshiftTransformed.Add(tmp2);
downshiftOrig.Add(tmp3);
}
ShiftPolygonDrawer.DrawShiftPolygons(Path.GetDirectoryName(gearboxFile), fullLoadCurves, shiftPolygons,
Path.Combine(Path.GetDirectoryName(gearboxFile), "Shiftlines.png"),
DeclarationData.Gearbox.TruckMaxAllowedSpeed / rdyn * axlegearRatio * gearboxData.Gears.Last().Ratio, upshiftOrig,
downshiftTransformed, downshiftOrig);
var shiftLines = "";
var gear = 1;
foreach (var shiftPolygon in shiftPolygons) {
shiftLines += "Gear " + gear + "\n";
shiftLines += "Upshift\n";
foreach (var shiftPolygonEntry in shiftPolygon.Upshift) {
shiftLines += string.Format("{0} {1}\n", shiftPolygonEntry.AngularSpeed.AsRPM, shiftPolygonEntry.Torque.Value());
}
shiftLines += "Downshift\n";
foreach (var shiftPolygonEntry in shiftPolygon.Downshift) {
shiftLines += string.Format("{0} {1}\n", shiftPolygonEntry.AngularSpeed.AsRPM, shiftPolygonEntry.Torque.Value());
}
}
}

Markus Quaritsch
committed
[TestFixture]
public class ShiftPolygonComparison
{
const string BasePath = @"E:\QUAM\Workspace\Daten_INTERN\Testfahrzeuge\";

Markus Quaritsch
committed
[
TestCase(@"class2_12t_baseline\175kW_Diesel_example.vfld", @"class2_12t_baseline\delivery_12t_example.vgbx", 0.421,
4.18, 600),
TestCase(@"class2_12t_iaxle_long\175kW_Diesel_example.vfld", @"class2_12t_iaxle_long\delivery_12t_example.vgbx",
0.421, 2.85, 600),
TestCase(@"class2_12t_iaxle_short\175kW_Diesel_example.vfld", @"class2_12t_iaxle_short\delivery_12t_example.vgbx",
0.421, 5.33, 600),
TestCase(@"class2_12t_Pmax_high\220kW_Diesel_example.vfld", @"class2_12t_Pmax_high\delivery_12t_example_220kW.vgbx",
0.421, 4.18, 600),
TestCase(@"class2_12t_Pmax_low\130kW_Diesel_example.vfld", @"class2_12t_Pmax_low\delivery_12t_example.vgbx", 0.421,
4.18, 600),
TestCase(@"class5_40t_baseline\12L-324kW.vfld", @"class5_40t_baseline\tractor_12gear_example.vgbx", 0.421, 2.64,
600),

Markus Quaritsch
committed
TestCase(@"class5_40t_iaxle_long\12L-324kW.vfld", @"class5_40t_iaxle_long\tractor_12gear_example.vgbx", 0.421, 2.31,
600),
TestCase(@"class5_40t_iaxle_short\12L-324kW.vfld", @"class5_40t_iaxle_short\tractor_12gear_example.vgbx", 0.421,
3.71,

Markus Quaritsch
committed
600),
TestCase(@"class5_40t_Pmax_high\13-9-L-375kW.vfld", @"class5_40t_Pmax_high\tractor_12gear_example.vgbx", 0.421,
2.64, 600),
TestCase(@"class5_40t_Pmax_low\9-6-L_260kW.vfld", @"class5_40t_Pmax_low\tractor_12gear_example.vgbx", 0.421, 2.64,
600),
]
public void ComputeShiftPolygon(string engineFldFile, string gearboxFile, double rdyn, double axlegearRatio,
double idlingSpeed)
{
if (!Directory.Exists(BasePath)) {
Assert.Inconclusive("Confidential File not found. Test cannot run without file.");

Markus Quaritsch
committed
var gearboxData = new JSONGearboxDataV6(JSONInputDataFactory.ReadFile(Path.Combine(BasePath, gearboxFile)),
Path.Combine(BasePath, gearboxFile));

Markus Quaritsch
committed
var engineData = new CombustionEngineData() {
IdleSpeed = idlingSpeed.RPMtoRad(),
};

Markus Quaritsch
committed
var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>();

Markus Quaritsch
committed
fullLoadCurves[0] = FullLoadCurveReader.ReadFromFile(Path.Combine(BasePath, engineFldFile), true);

Markus Quaritsch
committed
fullLoadCurves[0].EngineData = engineData;
for (uint i = 1; i <= gearboxData.Gears.Count; i++) {
fullLoadCurves[i] = AbstractSimulationDataAdapter.IntersectFullLoadCurves(fullLoadCurves[0],
gearboxData.Gears[(int)(i - 1)].MaxTorque);
}
engineData.FullLoadCurves = fullLoadCurves;

Markus Quaritsch
committed
var shiftPolygons = new List<ShiftPolygon>();
var downshiftTransformed = new List<List<Point>>();
var upshiftOrig = new List<List<Point>>();

Markus Quaritsch
committed
for (var i = 0; i < gearboxData.Gears.Count; i++) {
shiftPolygons.Add(

Markus Quaritsch
committed
DeclarationData.Gearbox.ComputeShiftPolygon(gearboxData.Type, i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,

Markus Quaritsch
committed
engineData, axlegearRatio, rdyn.SI<Meter>())
List<Point> tmp1, tmp2, tmp3;

Markus Quaritsch
committed
ComputShiftPolygonPoints(i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,
engineData, axlegearRatio, rdyn.SI<Meter>(), out tmp1, out tmp2, out tmp3);
upshiftOrig.Add(tmp1);
downshiftTransformed.Add(tmp2);

Markus Quaritsch
committed
}
var imageFile = Path.GetDirectoryName(gearboxFile) + "_" + Path.GetFileNameWithoutExtension(gearboxFile) + "_" +
Path.GetFileNameWithoutExtension(engineFldFile) +
".png";

Markus Quaritsch
committed
ShiftPolygonDrawer.DrawShiftPolygons(Path.GetDirectoryName(gearboxFile), fullLoadCurves, shiftPolygons,

Markus Quaritsch
committed
imageFile,
DeclarationData.Gearbox.TruckMaxAllowedSpeed / rdyn.SI<Meter>() * axlegearRatio * gearboxData.Gears.Last().Ratio,
upshiftOrig, downshiftTransformed);
var str = "";
var g = 1;
foreach (var shiftPolygon in shiftPolygons) {
str += "Gear " + g + "\n";
str += "downshift\n";
foreach (var entry in shiftPolygon.Downshift) {
str += string.Format("{0} {1}\n", entry.AngularSpeed.AsRPM, entry.Torque.Value());
}
str += "upshift\n";
foreach (var entry in shiftPolygon.Upshift) {
str += string.Format("{0} {1}\n", entry.AngularSpeed.AsRPM, entry.Torque.Value());
}
g++;
}

Markus Quaritsch
committed
public static void ComputShiftPolygonPoints(int gear, EngineFullLoadCurve fullLoadCurve,
IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius,
out List<Point> upshiftOrig, out List<Point> downshiftTransformed, out List<Point> downshiftOrig)
{
var engineSpeed85kmhLastGear = DeclarationData.Gearbox.TruckMaxAllowedSpeed / dynamicTyreRadius * axlegearRatio *
gears[gears.Count - 1].Ratio;
//var engineSpeed85kmhSecondToLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 2], axlegearRatio,
// dynamicTyreRadius, engine);

Markus Quaritsch
committed
var nVHigh = VectoMath.Min(engineSpeed85kmhLastGear, engine.FullLoadCurves[0].RatedSpeed);
var diffRatio = gears[gears.Count - 2].Ratio / gears[gears.Count - 1].Ratio - 1;

Markus Quaritsch
committed
var maxDragTorque = fullLoadCurve.MaxDragTorque * 1.1;
var p1 = new Point(engine.IdleSpeed.Value() / 2, 0);
var p2 = new Point(engine.IdleSpeed.Value() * 1.1, 0);
var p3 = new Point(nVHigh.Value() * 0.9,

Markus Quaritsch
committed
fullLoadCurve.FullLoadStationaryTorque(nVHigh * 0.9).Value());
var p4 =
new Point((nVHigh * (1 + diffRatio / 3)).Value(), 0);

Markus Quaritsch
committed
var p5 = new Point(fullLoadCurve.N95hSpeed.Value(), fullLoadCurve.MaxTorque.Value());
var p6 = new Point(p2.X, VectoMath.Interpolate(p1, p3, p2.X));
var p7 = new Point(p4.X, VectoMath.Interpolate(p2, p5, p4.X));
downshiftOrig = new[] { p2, p6, p3 }.ToList();
//var fldMargin = ShiftPolygonFldMargin(fullLoadCurve.FullLoadEntries, nVHigh * 0.95);
//var downshiftCorr = MoveDownshiftBelowFld(Edge.Create(p6, p3), fldMargin, 1.1 * fullLoadCurve.MaxTorque);
upshiftOrig = new[] { p4, p7, p5 }.ToList();
downshiftTransformed = new List<Point>();
if (gear >= gears.Count - 1) {
return;
}
var gearRatio = gears[gear].Ratio / gears[gear + 1].Ratio;
var rpmMarginFactor = 1 + DeclarationData.Gearbox.ShiftPolygonRPMMargin / 100.0;
var p2p = new Point(p2.X * gearRatio * rpmMarginFactor, p2.Y / gearRatio);
var p3p = new Point(p3.X * gearRatio * rpmMarginFactor, p3.Y / gearRatio);
var p6p = new Point(p6.X * gearRatio * rpmMarginFactor, p6.Y / gearRatio);
var edgeP6pP3p = new Edge(p6p, p3p);
var p3pExt = new Point((1.1 * p5.Y - edgeP6pP3p.OffsetXY) / edgeP6pP3p.SlopeXY, 1.1 * p5.Y);
downshiftTransformed = new[] { p2p, p6p, p3pExt }.ToList();

Markus Quaritsch
committed
}
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
/// <summary>
/// VECTO-517 Shiftpolygon is considered invalid
/// </summary>
[TestCase]
public void ShiftCurve_ShiftPolygon_Validation_Test()
{
var vgbs = new[] {
"-50,685,1537",
"550,685,1537",
"678,763,1537",
"1080,1008,2092",
"1200,1081,2092",
"1200,1081,2092",
"3000,1081,2092"
};
var shiftPolygon =
ShiftPolygonReader.Create(
VectoCSVFile.ReadStream(
InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm] ", vgbs)));
var results = shiftPolygon.Validate(ExecutionMode.Engineering, GearboxType.MT, false);
Assert.IsFalse(results.Any(), string.Join("\n", results.Select(r => r.ErrorMessage)));
}
[
TestCase(false, 650, 400),
TestCase(true, 400, 500),
TestCase(false, 900, 400),
TestCase(false, 1200, 400),
TestCase(true, 600, 900),
TestCase(false, 1000, 900),
TestCase(false, 1200, 900),
TestCase(true, 300, 1300),
TestCase(true, 900, 1300),
TestCase(false, 1200, 1250),
TestCase(false, 1200, 1600),
]
public void IsLeftOf_Test(bool result, double speed, double torque)
{
var segment = Tuple.Create(
new ShiftPolygon.ShiftPolygonEntry(550.SI<NewtonMeter>(), 685.RPMtoRad()),
new ShiftPolygon.ShiftPolygonEntry(1200.SI<NewtonMeter>(), 1080.RPMtoRad())
Assert.AreEqual(result, ShiftPolygon.IsLeftOf(speed.RPMtoRad(), torque.SI<NewtonMeter>(), segment));
}

Markus Quaritsch
committed
}