diff --git a/Generic Vehicles/Declaration Mode/Class2_RigidTruck_4x2/Class2_RigidTruck.vveh b/Generic Vehicles/Declaration Mode/Class2_RigidTruck_4x2/Class2_RigidTruck.vveh index 6179011253332280b3e7654152587e72e0478675..4a182089b5854b495a0e1bd6b30381c5060cce0d 100644 --- a/Generic Vehicles/Declaration Mode/Class2_RigidTruck_4x2/Class2_RigidTruck.vveh +++ b/Generic Vehicles/Declaration Mode/Class2_RigidTruck_4x2/Class2_RigidTruck.vveh @@ -1,13 +1,14 @@ { "Header": { "CreatedBy": "", - "Date": "2017-06-22T11:15:06.0747543Z", + "Date": "2017-07-03T14:47:21.4326880Z", "AppVersion": "3", "FileVersion": 7 }, "Body": { "SavedInDeclMode": true, "VehCat": "RigidTruck", + "LegislativeClass": "N2", "CurbWeight": 4670.0, "CurbWeightExtra": 0.0, "Loading": 0.0, diff --git a/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor.vveh b/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor.vveh index 69fe6f0b805c94258cbf487159a0ecb6c7703994..1867c8867861d3b86e44d92250eae2809526c75a 100644 --- a/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor.vveh +++ b/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor.vveh @@ -1,13 +1,14 @@ { "Header": { "CreatedBy": "", - "Date": "2017-06-22T11:14:19.0107543Z", + "Date": "2017-07-03T14:47:35.9436880Z", "AppVersion": "3", "FileVersion": 7 }, "Body": { "SavedInDeclMode": true, "VehCat": "Tractor", + "LegislativeClass": "N3", "CurbWeight": 8229.0, "CurbWeightExtra": 0.0, "Loading": 0.0, diff --git a/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor_DECL.vecto b/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor_DECL.vecto index 9d8e26457327e1c6851c8282a8a9f9cd92d5660c..542e4626d43dac5b8a483403aed82ab9b8917914 100644 --- a/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor_DECL.vecto +++ b/Generic Vehicles/Declaration Mode/Class5_Tractor_4x2/Class5_Tractor_DECL.vecto @@ -1,7 +1,7 @@ { "Header": { - "CreatedBy": " ()", - "Date": "2016-10-13T10:08:21.7776564Z", + "CreatedBy": "", + "Date": "2017-07-03T14:47:43.6586880Z", "AppVersion": "3", "FileVersion": 3 }, @@ -51,12 +51,6 @@ ] } ], - "StartStop": { - "Enabled": false, - "MaxSpeed": 5.0, - "MinTime": 5.0, - "Delay": 5.0 - }, "OverSpeedEcoRoll": { "Mode": "Overspeed", "MinSpeed": 50.0, diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_6x2/Class9_RigidTruck.vveh b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_6x2/Class9_RigidTruck.vveh index d2a3b50e5b25192b95786e2a5f5f36c21ef45db0..3bd49af68ee95788da316d6944aaf949686f4910 100644 --- a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_6x2/Class9_RigidTruck.vveh +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_6x2/Class9_RigidTruck.vveh @@ -1,13 +1,14 @@ { "Header": { "CreatedBy": "", - "Date": "2017-06-22T11:16:11.6047543Z", + "Date": "2017-07-03T14:48:16.7076880Z", "AppVersion": "3", "FileVersion": 7 }, "Body": { "SavedInDeclMode": true, "VehCat": "RigidTruck", + "LegislativeClass": "N3", "CurbWeight": 9300.0, "CurbWeightExtra": 0.0, "Loading": 0.0, diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/APT-S Generic TqMax1200.vgbx b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/APT-S Generic TqMax1200.vgbx new file mode 100644 index 0000000000000000000000000000000000000000..e87c262e7982995d539eb34372e0a09429b8c8c1 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/APT-S Generic TqMax1200.vgbx @@ -0,0 +1,82 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2017-06-28T08:04:09.4161407Z", + "AppVersion": "3", + "FileVersion": 6 + }, + "Body": { + "SavedInDeclMode": true, + "ModelName": "APT-S Generic TqMax1200", + "Inertia": 0.0, + "TracInt": 0.0, + "Gears": [ + { + "Ratio": 6.5, + "LossMap": "Axle_i6-5.vtlm" + }, + { + "Ratio": 3.49, + "LossMap": "Gear_1_i=3-49.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 1.86, + "LossMap": "Gear_2_i=1-86.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 1.41, + "LossMap": "Gear_3_i=1-41.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 1.0, + "LossMap": "Gear_4_i=1.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 0.75, + "LossMap": "Gear_5_i=0-75.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + }, + { + "Ratio": 0.65, + "LossMap": "Gear_6_i=0-65.vtlm", + "ShiftPolygon": "", + "MaxTorque": "", + "MaxSpeed": "" + } + ], + "TqReserve": 20.0, + "ShiftTime": 1.5, + "StartTqReserve": 20.0, + "StartSpeed": 1.3, + "StartAcc": 0.6, + "GearboxType": "ATSerial", + "TorqueConverter": { + "Enabled": true, + "File": "TorqueConverter_Serial_TqMax1200.vtcc", + "RefRPM": 999.99999999999989, + "Inertia": 1.3, + "MaxTCSpeed": 5000.0, + "ShiftPolygon": "", + "CLUpshiftMinAcceleration": 0.0, + "CCUpshiftMinAcceleration": 0.0 + }, + "DownshiftAfterUpshiftDelay": 10.0, + "UpshiftAfterDownshiftDelay": 10.0, + "UpshiftMinAcceleration": 0.1, + "PowershiftShiftTime": 0.8 + } +} \ No newline at end of file diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Axle_i6-5.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Axle_i6-5.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..27aedb86e849e955ffe7dc23e03d35f0bba112c4 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Axle_i6-5.vtlm @@ -0,0 +1,771 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,31.9587628865979,31.9587628865979 +0,70.4203013481364,31.9587628865979 +0,110.071371927042,33.1482950039651 +0,149.722442505948,34.3378271213323 +0,189.373513084853,35.5273592386995 +0,268.675654242665,37.9064234734338 +0,347.977795400476,40.2854877081681 +0,506.582077716098,45.0436161776368 +0,665.186360031721,49.8017446471055 +0,823.790642347343,54.5598731165741 +0,982.394924662966,59.3180015860429 +0,1140.99920697859,64.0761300555115 +0,1299.60348929421,68.8342585249803 +0,1458.20777160983,73.5923869944488 +0,1616.81205392546,78.3505154639175 +0,1934.0206185567,87.866772402855 +0,2251.22918318795,97.3830293417923 +0,2568.43774781919,106.89928628073 +0,2885.64631245044,116.415543219667 +0,3202.85487708168,125.931800158604 +0,3520.06344171293,135.448057097542 +0,3837.27200634417,144.964314036479 +0,4154.48057097542,154.480570975416 +0,4471.68913560666,163.996827914354 +0,4788.89770023791,173.513084853291 +0,5106.10626486915,183.029341792229 +0,5423.3148295004,192.545598731166 +0,5740.52339413164,202.061855670103 +0,6057.73195876289,211.578112609041 +0,6374.94052339413,221.094369547978 +0,6692.14908802538,230.610626486916 +0,7009.35765265662,240.126883425853 +0,7326.56621728787,249.64314036479 +0,7643.77478191911,259.159397303728 +0,7960.98334655036,268.675654242665 +325,31.9587628865979,31.9587628865979 +325,70.4203013481364,31.9587628865979 +325,110.071371927042,33.1482950039651 +325,149.722442505948,34.3378271213323 +325,189.373513084853,35.5273592386995 +325,268.675654242665,37.9064234734338 +325,347.977795400476,40.2854877081681 +325,506.582077716098,45.0436161776368 +325,665.186360031721,49.8017446471055 +325,823.790642347343,54.5598731165741 +325,982.394924662966,59.3180015860429 +325,1140.99920697859,64.0761300555115 +325,1299.60348929421,68.8342585249803 +325,1458.20777160983,73.5923869944488 +325,1616.81205392546,78.3505154639175 +325,1934.0206185567,87.866772402855 +325,2251.22918318795,97.3830293417923 +325,2568.43774781919,106.89928628073 +325,2885.64631245044,116.415543219667 +325,3202.85487708168,125.931800158604 +325,3520.06344171293,135.448057097542 +325,3837.27200634417,144.964314036479 +325,4154.48057097542,154.480570975416 +325,4471.68913560666,163.996827914354 +325,4788.89770023791,173.513084853291 +325,5106.10626486915,183.029341792229 +325,5423.3148295004,192.545598731166 +325,5740.52339413164,202.061855670103 +325,6057.73195876289,211.578112609041 +325,6374.94052339413,221.094369547978 +325,6692.14908802538,230.610626486916 +325,7009.35765265662,240.126883425853 +325,7326.56621728787,249.64314036479 +325,7643.77478191911,259.159397303728 +325,7960.98334655036,268.675654242665 +650,31.9587628865979,31.9587628865979 +650,70.4203013481364,31.9587628865979 +650,110.071371927042,33.1482950039651 +650,149.722442505948,34.3378271213323 +650,189.373513084853,35.5273592386995 +650,268.675654242665,37.9064234734338 +650,347.977795400476,40.2854877081681 +650,506.582077716098,45.0436161776368 +650,665.186360031721,49.8017446471055 +650,823.790642347343,54.5598731165741 +650,982.394924662966,59.3180015860429 +650,1140.99920697859,64.0761300555115 +650,1299.60348929421,68.8342585249803 +650,1458.20777160983,73.5923869944488 +650,1616.81205392546,78.3505154639175 +650,1934.0206185567,87.866772402855 +650,2251.22918318795,97.3830293417923 +650,2568.43774781919,106.89928628073 +650,2885.64631245044,116.415543219667 +650,3202.85487708168,125.931800158604 +650,3520.06344171293,135.448057097542 +650,3837.27200634417,144.964314036479 +650,4154.48057097542,154.480570975416 +650,4471.68913560666,163.996827914354 +650,4788.89770023791,173.513084853291 +650,5106.10626486915,183.029341792229 +650,5423.3148295004,192.545598731166 +650,5740.52339413164,202.061855670103 +650,6057.73195876289,211.578112609041 +650,6374.94052339413,221.094369547978 +650,6692.14908802538,230.610626486916 +650,7009.35765265662,240.126883425853 +650,7326.56621728787,249.64314036479 +650,7643.77478191911,259.159397303728 +650,7960.98334655036,268.675654242665 +975,31.9587628865979,31.9587628865979 +975,70.4203013481364,31.9587628865979 +975,110.071371927042,33.1482950039651 +975,149.722442505948,34.3378271213323 +975,189.373513084853,35.5273592386995 +975,268.675654242665,37.9064234734338 +975,347.977795400476,40.2854877081681 +975,506.582077716098,45.0436161776368 +975,665.186360031721,49.8017446471055 +975,823.790642347343,54.5598731165741 +975,982.394924662966,59.3180015860429 +975,1140.99920697859,64.0761300555115 +975,1299.60348929421,68.8342585249803 +975,1458.20777160983,73.5923869944488 +975,1616.81205392546,78.3505154639175 +975,1934.0206185567,87.866772402855 +975,2251.22918318795,97.3830293417923 +975,2568.43774781919,106.89928628073 +975,2885.64631245044,116.415543219667 +975,3202.85487708168,125.931800158604 +975,3520.06344171293,135.448057097542 +975,3837.27200634417,144.964314036479 +975,4154.48057097542,154.480570975416 +975,4471.68913560666,163.996827914354 +975,4788.89770023791,173.513084853291 +975,5106.10626486915,183.029341792229 +975,5423.3148295004,192.545598731166 +975,5740.52339413164,202.061855670103 +975,6057.73195876289,211.578112609041 +975,6374.94052339413,221.094369547978 +975,6692.14908802538,230.610626486916 +975,7009.35765265662,240.126883425853 +975,7326.56621728787,249.64314036479 +975,7643.77478191911,259.159397303728 +975,7960.98334655036,268.675654242665 +1300,31.9587628865979,31.9587628865979 +1300,70.4203013481364,31.9587628865979 +1300,110.071371927042,33.1482950039651 +1300,149.722442505948,34.3378271213323 +1300,189.373513084853,35.5273592386995 +1300,268.675654242665,37.9064234734338 +1300,347.977795400476,40.2854877081681 +1300,506.582077716098,45.0436161776368 +1300,665.186360031721,49.8017446471055 +1300,823.790642347343,54.5598731165741 +1300,982.394924662966,59.3180015860429 +1300,1140.99920697859,64.0761300555115 +1300,1299.60348929421,68.8342585249803 +1300,1458.20777160983,73.5923869944488 +1300,1616.81205392546,78.3505154639175 +1300,1934.0206185567,87.866772402855 +1300,2251.22918318795,97.3830293417923 +1300,2568.43774781919,106.89928628073 +1300,2885.64631245044,116.415543219667 +1300,3202.85487708168,125.931800158604 +1300,3520.06344171293,135.448057097542 +1300,3837.27200634417,144.964314036479 +1300,4154.48057097542,154.480570975416 +1300,4471.68913560666,163.996827914354 +1300,4788.89770023791,173.513084853291 +1300,5106.10626486915,183.029341792229 +1300,5423.3148295004,192.545598731166 +1300,5740.52339413164,202.061855670103 +1300,6057.73195876289,211.578112609041 +1300,6374.94052339413,221.094369547978 +1300,6692.14908802538,230.610626486916 +1300,7009.35765265662,240.126883425853 +1300,7326.56621728787,249.64314036479 +1300,7643.77478191911,259.159397303728 +1300,7960.98334655036,268.675654242665 +1625,31.9587628865979,31.9587628865979 +1625,70.4203013481364,31.9587628865979 +1625,110.071371927042,33.1482950039651 +1625,149.722442505948,34.3378271213323 +1625,189.373513084853,35.5273592386995 +1625,268.675654242665,37.9064234734338 +1625,347.977795400476,40.2854877081681 +1625,506.582077716098,45.0436161776368 +1625,665.186360031721,49.8017446471055 +1625,823.790642347343,54.5598731165741 +1625,982.394924662966,59.3180015860429 +1625,1140.99920697859,64.0761300555115 +1625,1299.60348929421,68.8342585249803 +1625,1458.20777160983,73.5923869944488 +1625,1616.81205392546,78.3505154639175 +1625,1934.0206185567,87.866772402855 +1625,2251.22918318795,97.3830293417923 +1625,2568.43774781919,106.89928628073 +1625,2885.64631245044,116.415543219667 +1625,3202.85487708168,125.931800158604 +1625,3520.06344171293,135.448057097542 +1625,3837.27200634417,144.964314036479 +1625,4154.48057097542,154.480570975416 +1625,4471.68913560666,163.996827914354 +1625,4788.89770023791,173.513084853291 +1625,5106.10626486915,183.029341792229 +1625,5423.3148295004,192.545598731166 +1625,5740.52339413164,202.061855670103 +1625,6057.73195876289,211.578112609041 +1625,6374.94052339413,221.094369547978 +1625,6692.14908802538,230.610626486916 +1625,7009.35765265662,240.126883425853 +1625,7326.56621728787,249.64314036479 +1625,7643.77478191911,259.159397303728 +1625,7960.98334655036,268.675654242665 +1950,31.9587628865979,31.9587628865979 +1950,70.4203013481364,31.9587628865979 +1950,110.071371927042,33.1482950039651 +1950,149.722442505948,34.3378271213323 +1950,189.373513084853,35.5273592386995 +1950,268.675654242665,37.9064234734338 +1950,347.977795400476,40.2854877081681 +1950,506.582077716098,45.0436161776368 +1950,665.186360031721,49.8017446471055 +1950,823.790642347343,54.5598731165741 +1950,982.394924662966,59.3180015860429 +1950,1140.99920697859,64.0761300555115 +1950,1299.60348929421,68.8342585249803 +1950,1458.20777160983,73.5923869944488 +1950,1616.81205392546,78.3505154639175 +1950,1934.0206185567,87.866772402855 +1950,2251.22918318795,97.3830293417923 +1950,2568.43774781919,106.89928628073 +1950,2885.64631245044,116.415543219667 +1950,3202.85487708168,125.931800158604 +1950,3520.06344171293,135.448057097542 +1950,3837.27200634417,144.964314036479 +1950,4154.48057097542,154.480570975416 +1950,4471.68913560666,163.996827914354 +1950,4788.89770023791,173.513084853291 +1950,5106.10626486915,183.029341792229 +1950,5423.3148295004,192.545598731166 +1950,5740.52339413164,202.061855670103 +1950,6057.73195876289,211.578112609041 +1950,6374.94052339413,221.094369547978 +1950,6692.14908802538,230.610626486916 +1950,7009.35765265662,240.126883425853 +1950,7326.56621728787,249.64314036479 +1950,7643.77478191911,259.159397303728 +1950,7960.98334655036,268.675654242665 +2275,31.9587628865979,31.9587628865979 +2275,70.4203013481364,31.9587628865979 +2275,110.071371927042,33.1482950039651 +2275,149.722442505948,34.3378271213323 +2275,189.373513084853,35.5273592386995 +2275,268.675654242665,37.9064234734338 +2275,347.977795400476,40.2854877081681 +2275,506.582077716098,45.0436161776368 +2275,665.186360031721,49.8017446471055 +2275,823.790642347343,54.5598731165741 +2275,982.394924662966,59.3180015860429 +2275,1140.99920697859,64.0761300555115 +2275,1299.60348929421,68.8342585249803 +2275,1458.20777160983,73.5923869944488 +2275,1616.81205392546,78.3505154639175 +2275,1934.0206185567,87.866772402855 +2275,2251.22918318795,97.3830293417923 +2275,2568.43774781919,106.89928628073 +2275,2885.64631245044,116.415543219667 +2275,3202.85487708168,125.931800158604 +2275,3520.06344171293,135.448057097542 +2275,3837.27200634417,144.964314036479 +2275,4154.48057097542,154.480570975416 +2275,4471.68913560666,163.996827914354 +2275,4788.89770023791,173.513084853291 +2275,5106.10626486915,183.029341792229 +2275,5423.3148295004,192.545598731166 +2275,5740.52339413164,202.061855670103 +2275,6057.73195876289,211.578112609041 +2275,6374.94052339413,221.094369547978 +2275,6692.14908802538,230.610626486916 +2275,7009.35765265662,240.126883425853 +2275,7326.56621728787,249.64314036479 +2275,7643.77478191911,259.159397303728 +2275,7960.98334655036,268.675654242665 +2600,31.9587628865979,31.9587628865979 +2600,70.4203013481364,31.9587628865979 +2600,110.071371927042,33.1482950039651 +2600,149.722442505948,34.3378271213323 +2600,189.373513084853,35.5273592386995 +2600,268.675654242665,37.9064234734338 +2600,347.977795400476,40.2854877081681 +2600,506.582077716098,45.0436161776368 +2600,665.186360031721,49.8017446471055 +2600,823.790642347343,54.5598731165741 +2600,982.394924662966,59.3180015860429 +2600,1140.99920697859,64.0761300555115 +2600,1299.60348929421,68.8342585249803 +2600,1458.20777160983,73.5923869944488 +2600,1616.81205392546,78.3505154639175 +2600,1934.0206185567,87.866772402855 +2600,2251.22918318795,97.3830293417923 +2600,2568.43774781919,106.89928628073 +2600,2885.64631245044,116.415543219667 +2600,3202.85487708168,125.931800158604 +2600,3520.06344171293,135.448057097542 +2600,3837.27200634417,144.964314036479 +2600,4154.48057097542,154.480570975416 +2600,4471.68913560666,163.996827914354 +2600,4788.89770023791,173.513084853291 +2600,5106.10626486915,183.029341792229 +2600,5423.3148295004,192.545598731166 +2600,5740.52339413164,202.061855670103 +2600,6057.73195876289,211.578112609041 +2600,6374.94052339413,221.094369547978 +2600,6692.14908802538,230.610626486916 +2600,7009.35765265662,240.126883425853 +2600,7326.56621728787,249.64314036479 +2600,7643.77478191911,259.159397303728 +2600,7960.98334655036,268.675654242665 +2925,31.9587628865979,31.9587628865979 +2925,70.4203013481364,31.9587628865979 +2925,110.071371927042,33.1482950039651 +2925,149.722442505948,34.3378271213323 +2925,189.373513084853,35.5273592386995 +2925,268.675654242665,37.9064234734338 +2925,347.977795400476,40.2854877081681 +2925,506.582077716098,45.0436161776368 +2925,665.186360031721,49.8017446471055 +2925,823.790642347343,54.5598731165741 +2925,982.394924662966,59.3180015860429 +2925,1140.99920697859,64.0761300555115 +2925,1299.60348929421,68.8342585249803 +2925,1458.20777160983,73.5923869944488 +2925,1616.81205392546,78.3505154639175 +2925,1934.0206185567,87.866772402855 +2925,2251.22918318795,97.3830293417923 +2925,2568.43774781919,106.89928628073 +2925,2885.64631245044,116.415543219667 +2925,3202.85487708168,125.931800158604 +2925,3520.06344171293,135.448057097542 +2925,3837.27200634417,144.964314036479 +2925,4154.48057097542,154.480570975416 +2925,4471.68913560666,163.996827914354 +2925,4788.89770023791,173.513084853291 +2925,5106.10626486915,183.029341792229 +2925,5423.3148295004,192.545598731166 +2925,5740.52339413164,202.061855670103 +2925,6057.73195876289,211.578112609041 +2925,6374.94052339413,221.094369547978 +2925,6692.14908802538,230.610626486916 +2925,7009.35765265662,240.126883425853 +2925,7326.56621728787,249.64314036479 +2925,7643.77478191911,259.159397303728 +2925,7960.98334655036,268.675654242665 +3250,31.9587628865979,31.9587628865979 +3250,70.4203013481364,31.9587628865979 +3250,110.071371927042,33.1482950039651 +3250,149.722442505948,34.3378271213323 +3250,189.373513084853,35.5273592386995 +3250,268.675654242665,37.9064234734338 +3250,347.977795400476,40.2854877081681 +3250,506.582077716098,45.0436161776368 +3250,665.186360031721,49.8017446471055 +3250,823.790642347343,54.5598731165741 +3250,982.394924662966,59.3180015860429 +3250,1140.99920697859,64.0761300555115 +3250,1299.60348929421,68.8342585249803 +3250,1458.20777160983,73.5923869944488 +3250,1616.81205392546,78.3505154639175 +3250,1934.0206185567,87.866772402855 +3250,2251.22918318795,97.3830293417923 +3250,2568.43774781919,106.89928628073 +3250,2885.64631245044,116.415543219667 +3250,3202.85487708168,125.931800158604 +3250,3520.06344171293,135.448057097542 +3250,3837.27200634417,144.964314036479 +3250,4154.48057097542,154.480570975416 +3250,4471.68913560666,163.996827914354 +3250,4788.89770023791,173.513084853291 +3250,5106.10626486915,183.029341792229 +3250,5423.3148295004,192.545598731166 +3250,5740.52339413164,202.061855670103 +3250,6057.73195876289,211.578112609041 +3250,6374.94052339413,221.094369547978 +3250,6692.14908802538,230.610626486916 +3250,7009.35765265662,240.126883425853 +3250,7326.56621728787,249.64314036479 +3250,7643.77478191911,259.159397303728 +3250,7960.98334655036,268.675654242665 +0,-31.9587628865979,31.9587628865979 +0,-70.4203013481364,31.9587628865979 +0,-110.071371927042,33.1482950039651 +0,-149.722442505948,34.3378271213323 +0,-189.373513084853,35.5273592386995 +0,-268.675654242665,37.9064234734338 +0,-347.977795400476,40.2854877081681 +0,-506.582077716098,45.0436161776368 +0,-665.186360031721,49.8017446471055 +0,-823.790642347343,54.5598731165741 +0,-982.394924662966,59.3180015860429 +0,-1140.99920697859,64.0761300555115 +0,-1299.60348929421,68.8342585249803 +0,-1458.20777160983,73.5923869944488 +0,-1616.81205392546,78.3505154639175 +0,-1934.0206185567,87.866772402855 +0,-2251.22918318795,97.3830293417923 +0,-2568.43774781919,106.89928628073 +0,-2885.64631245044,116.415543219667 +0,-3202.85487708168,125.931800158604 +0,-3520.06344171293,135.448057097542 +0,-3837.27200634417,144.964314036479 +0,-4154.48057097542,154.480570975416 +0,-4471.68913560666,163.996827914354 +0,-4788.89770023791,173.513084853291 +0,-5106.10626486915,183.029341792229 +0,-5423.3148295004,192.545598731166 +0,-5740.52339413164,202.061855670103 +0,-6057.73195876289,211.578112609041 +0,-6374.94052339413,221.094369547978 +0,-6692.14908802538,230.610626486916 +0,-7009.35765265662,240.126883425853 +0,-7326.56621728787,249.64314036479 +0,-7643.77478191911,259.159397303728 +0,-7960.98334655036,268.675654242665 +325,-31.9587628865979,31.9587628865979 +325,-70.4203013481364,31.9587628865979 +325,-110.071371927042,33.1482950039651 +325,-149.722442505948,34.3378271213323 +325,-189.373513084853,35.5273592386995 +325,-268.675654242665,37.9064234734338 +325,-347.977795400476,40.2854877081681 +325,-506.582077716098,45.0436161776368 +325,-665.186360031721,49.8017446471055 +325,-823.790642347343,54.5598731165741 +325,-982.394924662966,59.3180015860429 +325,-1140.99920697859,64.0761300555115 +325,-1299.60348929421,68.8342585249803 +325,-1458.20777160983,73.5923869944488 +325,-1616.81205392546,78.3505154639175 +325,-1934.0206185567,87.866772402855 +325,-2251.22918318795,97.3830293417923 +325,-2568.43774781919,106.89928628073 +325,-2885.64631245044,116.415543219667 +325,-3202.85487708168,125.931800158604 +325,-3520.06344171293,135.448057097542 +325,-3837.27200634417,144.964314036479 +325,-4154.48057097542,154.480570975416 +325,-4471.68913560666,163.996827914354 +325,-4788.89770023791,173.513084853291 +325,-5106.10626486915,183.029341792229 +325,-5423.3148295004,192.545598731166 +325,-5740.52339413164,202.061855670103 +325,-6057.73195876289,211.578112609041 +325,-6374.94052339413,221.094369547978 +325,-6692.14908802538,230.610626486916 +325,-7009.35765265662,240.126883425853 +325,-7326.56621728787,249.64314036479 +325,-7643.77478191911,259.159397303728 +325,-7960.98334655036,268.675654242665 +650,-31.9587628865979,31.9587628865979 +650,-70.4203013481364,31.9587628865979 +650,-110.071371927042,33.1482950039651 +650,-149.722442505948,34.3378271213323 +650,-189.373513084853,35.5273592386995 +650,-268.675654242665,37.9064234734338 +650,-347.977795400476,40.2854877081681 +650,-506.582077716098,45.0436161776368 +650,-665.186360031721,49.8017446471055 +650,-823.790642347343,54.5598731165741 +650,-982.394924662966,59.3180015860429 +650,-1140.99920697859,64.0761300555115 +650,-1299.60348929421,68.8342585249803 +650,-1458.20777160983,73.5923869944488 +650,-1616.81205392546,78.3505154639175 +650,-1934.0206185567,87.866772402855 +650,-2251.22918318795,97.3830293417923 +650,-2568.43774781919,106.89928628073 +650,-2885.64631245044,116.415543219667 +650,-3202.85487708168,125.931800158604 +650,-3520.06344171293,135.448057097542 +650,-3837.27200634417,144.964314036479 +650,-4154.48057097542,154.480570975416 +650,-4471.68913560666,163.996827914354 +650,-4788.89770023791,173.513084853291 +650,-5106.10626486915,183.029341792229 +650,-5423.3148295004,192.545598731166 +650,-5740.52339413164,202.061855670103 +650,-6057.73195876289,211.578112609041 +650,-6374.94052339413,221.094369547978 +650,-6692.14908802538,230.610626486916 +650,-7009.35765265662,240.126883425853 +650,-7326.56621728787,249.64314036479 +650,-7643.77478191911,259.159397303728 +650,-7960.98334655036,268.675654242665 +975,-31.9587628865979,31.9587628865979 +975,-70.4203013481364,31.9587628865979 +975,-110.071371927042,33.1482950039651 +975,-149.722442505948,34.3378271213323 +975,-189.373513084853,35.5273592386995 +975,-268.675654242665,37.9064234734338 +975,-347.977795400476,40.2854877081681 +975,-506.582077716098,45.0436161776368 +975,-665.186360031721,49.8017446471055 +975,-823.790642347343,54.5598731165741 +975,-982.394924662966,59.3180015860429 +975,-1140.99920697859,64.0761300555115 +975,-1299.60348929421,68.8342585249803 +975,-1458.20777160983,73.5923869944488 +975,-1616.81205392546,78.3505154639175 +975,-1934.0206185567,87.866772402855 +975,-2251.22918318795,97.3830293417923 +975,-2568.43774781919,106.89928628073 +975,-2885.64631245044,116.415543219667 +975,-3202.85487708168,125.931800158604 +975,-3520.06344171293,135.448057097542 +975,-3837.27200634417,144.964314036479 +975,-4154.48057097542,154.480570975416 +975,-4471.68913560666,163.996827914354 +975,-4788.89770023791,173.513084853291 +975,-5106.10626486915,183.029341792229 +975,-5423.3148295004,192.545598731166 +975,-5740.52339413164,202.061855670103 +975,-6057.73195876289,211.578112609041 +975,-6374.94052339413,221.094369547978 +975,-6692.14908802538,230.610626486916 +975,-7009.35765265662,240.126883425853 +975,-7326.56621728787,249.64314036479 +975,-7643.77478191911,259.159397303728 +975,-7960.98334655036,268.675654242665 +1300,-31.9587628865979,31.9587628865979 +1300,-70.4203013481364,31.9587628865979 +1300,-110.071371927042,33.1482950039651 +1300,-149.722442505948,34.3378271213323 +1300,-189.373513084853,35.5273592386995 +1300,-268.675654242665,37.9064234734338 +1300,-347.977795400476,40.2854877081681 +1300,-506.582077716098,45.0436161776368 +1300,-665.186360031721,49.8017446471055 +1300,-823.790642347343,54.5598731165741 +1300,-982.394924662966,59.3180015860429 +1300,-1140.99920697859,64.0761300555115 +1300,-1299.60348929421,68.8342585249803 +1300,-1458.20777160983,73.5923869944488 +1300,-1616.81205392546,78.3505154639175 +1300,-1934.0206185567,87.866772402855 +1300,-2251.22918318795,97.3830293417923 +1300,-2568.43774781919,106.89928628073 +1300,-2885.64631245044,116.415543219667 +1300,-3202.85487708168,125.931800158604 +1300,-3520.06344171293,135.448057097542 +1300,-3837.27200634417,144.964314036479 +1300,-4154.48057097542,154.480570975416 +1300,-4471.68913560666,163.996827914354 +1300,-4788.89770023791,173.513084853291 +1300,-5106.10626486915,183.029341792229 +1300,-5423.3148295004,192.545598731166 +1300,-5740.52339413164,202.061855670103 +1300,-6057.73195876289,211.578112609041 +1300,-6374.94052339413,221.094369547978 +1300,-6692.14908802538,230.610626486916 +1300,-7009.35765265662,240.126883425853 +1300,-7326.56621728787,249.64314036479 +1300,-7643.77478191911,259.159397303728 +1300,-7960.98334655036,268.675654242665 +1625,-31.9587628865979,31.9587628865979 +1625,-70.4203013481364,31.9587628865979 +1625,-110.071371927042,33.1482950039651 +1625,-149.722442505948,34.3378271213323 +1625,-189.373513084853,35.5273592386995 +1625,-268.675654242665,37.9064234734338 +1625,-347.977795400476,40.2854877081681 +1625,-506.582077716098,45.0436161776368 +1625,-665.186360031721,49.8017446471055 +1625,-823.790642347343,54.5598731165741 +1625,-982.394924662966,59.3180015860429 +1625,-1140.99920697859,64.0761300555115 +1625,-1299.60348929421,68.8342585249803 +1625,-1458.20777160983,73.5923869944488 +1625,-1616.81205392546,78.3505154639175 +1625,-1934.0206185567,87.866772402855 +1625,-2251.22918318795,97.3830293417923 +1625,-2568.43774781919,106.89928628073 +1625,-2885.64631245044,116.415543219667 +1625,-3202.85487708168,125.931800158604 +1625,-3520.06344171293,135.448057097542 +1625,-3837.27200634417,144.964314036479 +1625,-4154.48057097542,154.480570975416 +1625,-4471.68913560666,163.996827914354 +1625,-4788.89770023791,173.513084853291 +1625,-5106.10626486915,183.029341792229 +1625,-5423.3148295004,192.545598731166 +1625,-5740.52339413164,202.061855670103 +1625,-6057.73195876289,211.578112609041 +1625,-6374.94052339413,221.094369547978 +1625,-6692.14908802538,230.610626486916 +1625,-7009.35765265662,240.126883425853 +1625,-7326.56621728787,249.64314036479 +1625,-7643.77478191911,259.159397303728 +1625,-7960.98334655036,268.675654242665 +1950,-31.9587628865979,31.9587628865979 +1950,-70.4203013481364,31.9587628865979 +1950,-110.071371927042,33.1482950039651 +1950,-149.722442505948,34.3378271213323 +1950,-189.373513084853,35.5273592386995 +1950,-268.675654242665,37.9064234734338 +1950,-347.977795400476,40.2854877081681 +1950,-506.582077716098,45.0436161776368 +1950,-665.186360031721,49.8017446471055 +1950,-823.790642347343,54.5598731165741 +1950,-982.394924662966,59.3180015860429 +1950,-1140.99920697859,64.0761300555115 +1950,-1299.60348929421,68.8342585249803 +1950,-1458.20777160983,73.5923869944488 +1950,-1616.81205392546,78.3505154639175 +1950,-1934.0206185567,87.866772402855 +1950,-2251.22918318795,97.3830293417923 +1950,-2568.43774781919,106.89928628073 +1950,-2885.64631245044,116.415543219667 +1950,-3202.85487708168,125.931800158604 +1950,-3520.06344171293,135.448057097542 +1950,-3837.27200634417,144.964314036479 +1950,-4154.48057097542,154.480570975416 +1950,-4471.68913560666,163.996827914354 +1950,-4788.89770023791,173.513084853291 +1950,-5106.10626486915,183.029341792229 +1950,-5423.3148295004,192.545598731166 +1950,-5740.52339413164,202.061855670103 +1950,-6057.73195876289,211.578112609041 +1950,-6374.94052339413,221.094369547978 +1950,-6692.14908802538,230.610626486916 +1950,-7009.35765265662,240.126883425853 +1950,-7326.56621728787,249.64314036479 +1950,-7643.77478191911,259.159397303728 +1950,-7960.98334655036,268.675654242665 +2275,-31.9587628865979,31.9587628865979 +2275,-70.4203013481364,31.9587628865979 +2275,-110.071371927042,33.1482950039651 +2275,-149.722442505948,34.3378271213323 +2275,-189.373513084853,35.5273592386995 +2275,-268.675654242665,37.9064234734338 +2275,-347.977795400476,40.2854877081681 +2275,-506.582077716098,45.0436161776368 +2275,-665.186360031721,49.8017446471055 +2275,-823.790642347343,54.5598731165741 +2275,-982.394924662966,59.3180015860429 +2275,-1140.99920697859,64.0761300555115 +2275,-1299.60348929421,68.8342585249803 +2275,-1458.20777160983,73.5923869944488 +2275,-1616.81205392546,78.3505154639175 +2275,-1934.0206185567,87.866772402855 +2275,-2251.22918318795,97.3830293417923 +2275,-2568.43774781919,106.89928628073 +2275,-2885.64631245044,116.415543219667 +2275,-3202.85487708168,125.931800158604 +2275,-3520.06344171293,135.448057097542 +2275,-3837.27200634417,144.964314036479 +2275,-4154.48057097542,154.480570975416 +2275,-4471.68913560666,163.996827914354 +2275,-4788.89770023791,173.513084853291 +2275,-5106.10626486915,183.029341792229 +2275,-5423.3148295004,192.545598731166 +2275,-5740.52339413164,202.061855670103 +2275,-6057.73195876289,211.578112609041 +2275,-6374.94052339413,221.094369547978 +2275,-6692.14908802538,230.610626486916 +2275,-7009.35765265662,240.126883425853 +2275,-7326.56621728787,249.64314036479 +2275,-7643.77478191911,259.159397303728 +2275,-7960.98334655036,268.675654242665 +2600,-31.9587628865979,31.9587628865979 +2600,-70.4203013481364,31.9587628865979 +2600,-110.071371927042,33.1482950039651 +2600,-149.722442505948,34.3378271213323 +2600,-189.373513084853,35.5273592386995 +2600,-268.675654242665,37.9064234734338 +2600,-347.977795400476,40.2854877081681 +2600,-506.582077716098,45.0436161776368 +2600,-665.186360031721,49.8017446471055 +2600,-823.790642347343,54.5598731165741 +2600,-982.394924662966,59.3180015860429 +2600,-1140.99920697859,64.0761300555115 +2600,-1299.60348929421,68.8342585249803 +2600,-1458.20777160983,73.5923869944488 +2600,-1616.81205392546,78.3505154639175 +2600,-1934.0206185567,87.866772402855 +2600,-2251.22918318795,97.3830293417923 +2600,-2568.43774781919,106.89928628073 +2600,-2885.64631245044,116.415543219667 +2600,-3202.85487708168,125.931800158604 +2600,-3520.06344171293,135.448057097542 +2600,-3837.27200634417,144.964314036479 +2600,-4154.48057097542,154.480570975416 +2600,-4471.68913560666,163.996827914354 +2600,-4788.89770023791,173.513084853291 +2600,-5106.10626486915,183.029341792229 +2600,-5423.3148295004,192.545598731166 +2600,-5740.52339413164,202.061855670103 +2600,-6057.73195876289,211.578112609041 +2600,-6374.94052339413,221.094369547978 +2600,-6692.14908802538,230.610626486916 +2600,-7009.35765265662,240.126883425853 +2600,-7326.56621728787,249.64314036479 +2600,-7643.77478191911,259.159397303728 +2600,-7960.98334655036,268.675654242665 +2925,-31.9587628865979,31.9587628865979 +2925,-70.4203013481364,31.9587628865979 +2925,-110.071371927042,33.1482950039651 +2925,-149.722442505948,34.3378271213323 +2925,-189.373513084853,35.5273592386995 +2925,-268.675654242665,37.9064234734338 +2925,-347.977795400476,40.2854877081681 +2925,-506.582077716098,45.0436161776368 +2925,-665.186360031721,49.8017446471055 +2925,-823.790642347343,54.5598731165741 +2925,-982.394924662966,59.3180015860429 +2925,-1140.99920697859,64.0761300555115 +2925,-1299.60348929421,68.8342585249803 +2925,-1458.20777160983,73.5923869944488 +2925,-1616.81205392546,78.3505154639175 +2925,-1934.0206185567,87.866772402855 +2925,-2251.22918318795,97.3830293417923 +2925,-2568.43774781919,106.89928628073 +2925,-2885.64631245044,116.415543219667 +2925,-3202.85487708168,125.931800158604 +2925,-3520.06344171293,135.448057097542 +2925,-3837.27200634417,144.964314036479 +2925,-4154.48057097542,154.480570975416 +2925,-4471.68913560666,163.996827914354 +2925,-4788.89770023791,173.513084853291 +2925,-5106.10626486915,183.029341792229 +2925,-5423.3148295004,192.545598731166 +2925,-5740.52339413164,202.061855670103 +2925,-6057.73195876289,211.578112609041 +2925,-6374.94052339413,221.094369547978 +2925,-6692.14908802538,230.610626486916 +2925,-7009.35765265662,240.126883425853 +2925,-7326.56621728787,249.64314036479 +2925,-7643.77478191911,259.159397303728 +2925,-7960.98334655036,268.675654242665 +3250,-31.9587628865979,31.9587628865979 +3250,-70.4203013481364,31.9587628865979 +3250,-110.071371927042,33.1482950039651 +3250,-149.722442505948,34.3378271213323 +3250,-189.373513084853,35.5273592386995 +3250,-268.675654242665,37.9064234734338 +3250,-347.977795400476,40.2854877081681 +3250,-506.582077716098,45.0436161776368 +3250,-665.186360031721,49.8017446471055 +3250,-823.790642347343,54.5598731165741 +3250,-982.394924662966,59.3180015860429 +3250,-1140.99920697859,64.0761300555115 +3250,-1299.60348929421,68.8342585249803 +3250,-1458.20777160983,73.5923869944488 +3250,-1616.81205392546,78.3505154639175 +3250,-1934.0206185567,87.866772402855 +3250,-2251.22918318795,97.3830293417923 +3250,-2568.43774781919,106.89928628073 +3250,-2885.64631245044,116.415543219667 +3250,-3202.85487708168,125.931800158604 +3250,-3520.06344171293,135.448057097542 +3250,-3837.27200634417,144.964314036479 +3250,-4154.48057097542,154.480570975416 +3250,-4471.68913560666,163.996827914354 +3250,-4788.89770023791,173.513084853291 +3250,-5106.10626486915,183.029341792229 +3250,-5423.3148295004,192.545598731166 +3250,-5740.52339413164,202.061855670103 +3250,-6057.73195876289,211.578112609041 +3250,-6374.94052339413,221.094369547978 +3250,-6692.14908802538,230.610626486916 +3250,-7009.35765265662,240.126883425853 +3250,-7326.56621728787,249.64314036479 +3250,-7643.77478191911,259.159397303728 +3250,-7960.98334655036,268.675654242665 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Class_9_RigidTruck_AT_Decl.vecto b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Class_9_RigidTruck_AT_Decl.vecto new file mode 100644 index 0000000000000000000000000000000000000000..7b6c7a4813b944438dd1e05049ff2bdd27a7b164 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Class_9_RigidTruck_AT_Decl.vecto @@ -0,0 +1,61 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2017-07-03T12:21:05.6496880Z", + "AppVersion": "3", + "FileVersion": 3 + }, + "Body": { + "SavedInDeclMode": true, + "EngineOnlyMode": false, + "VehicleFile": "RigidTruck_6x2.vveh", + "EngineFile": "Engine_220kW.veng", + "GearboxFile": "APT-S Generic TqMax1200.vgbx", + "AuxiliaryAssembly": "Classic", + "AuxiliaryVersion": "CLASSIC", + "AdvancedAuxiliaryFilePath": "", + "Aux": [ + { + "ID": "FAN", + "Type": "Fan", + "Technology": [ + "Belt driven or driven via transm. - Electronically controlled visco clutch" + ] + }, + { + "ID": "STP", + "Type": "Steering pump", + "Technology": [ + "Fixed displacement" + ] + }, + { + "ID": "AC", + "Type": "HVAC", + "Technology": [ + "Default" + ] + }, + { + "ID": "ES", + "Type": "Electric System", + "Technology": [ + "Standard technology" + ] + }, + { + "ID": "PS", + "Type": "Pneumatic System", + "Technology": [ + "Medium Supply 2-stage + ESS + AMS" + ] + } + ], + "OverSpeedEcoRoll": { + "Mode": "Overspeed", + "MinSpeed": 50.0, + "OverSpeed": 5.0, + "UnderSpeed": 5.0 + } + } +} \ No newline at end of file diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.veng b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.veng new file mode 100644 index 0000000000000000000000000000000000000000..2518101cee6f75f8dc94e86f60994e441dfa5ce1 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.veng @@ -0,0 +1,28 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2017-06-28T08:27:38.7951297Z", + "AppVersion": "3", + "FileVersion": 4 + }, + "Body": { + "SavedInDeclMode": true, + "ModelName": "Generic 220kW 7.7l Engine", + "Displacement": "7700", + "IdlingSpeed": 600.0, + "Inertia": 3.789, + "WHTC-Urban": 1.03, + "WHTC-Rural": 1.01, + "WHTC-Motorway": 1.0, + "WHTC-Engineering": 1.03, + "ColdHotBalancingFactor": 1.0, + "CFRegPer": 1.0, + "CFNCV": 1.0, + "RatedPower": 220000.0, + "RatedSpeed": 2200.0, + "MaxTorque": 1200.0, + "FuelType": "DieselCI", + "FullLoadCurve": "Engine_220kW.vfld", + "FuelMap": "Engine_220kW.vmap" + } +} \ No newline at end of file diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vfld b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vfld new file mode 100644 index 0000000000000000000000000000000000000000..1950d7635e43cc30c5a10f139625041e43d2c61d --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vfld @@ -0,0 +1,13 @@ +engine speed [1/min],full load torque [Nm],motoring torque [Nm] +600,600,-43.579 +800,836,-53.659 +1000,1069.521218,-62.025357 +1200,1200,-73.94288 +1400,1200,-85.2547035 +1600,1200,-96.566527 +1800,1123.617983,-103.414737 +2000,1037.521525,-110.72677 +2200,953.9486854,-124.56264 +2400,815.3547523,-134.718847 +2500,711.2927252,-139.183674 +2600,0,-145.132532 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vmap b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vmap new file mode 100644 index 0000000000000000000000000000000000000000..7ae025ef1f2a8fd8d8e070eb5dcf42ecb49be07b --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Engine_220kW.vmap @@ -0,0 +1,147 @@ +engine speed [rpm],torque [Nm],fuel consumption [g/h] +600,-44.579,0 +600,0,638 +600,70,1601.24 +600,100,2020.04 +600,200,3330.70588235294 +600,300,4651.64 +600,400,5962.41176470588 +600,500,7979.12 +600,600,10025.1176470588 +800,-54.659,0 +800,0,914.256225905983 +800,70,1862.23669744703 +800,100,2367.74806976117 +800,200,4006.78510458877 +800,300,5667.98318630181 +800,400,7335.34723841065 +800,500,9511.01908700806 +800,600,11650.650968045 +800,700,13773.9770410575 +800,800,15797.4270742006 +800,836,16529.9195199215 +1000,-63.6310565,0 +1000,0,1190.51245181197 +1000,70,2123.23339489406 +1000,100,2715.45613952235 +1000,200,4682.86432682459 +1000,300,6684.32637260363 +1000,400,8708.28271211541 +1000,500,11042.9181740161 +1000,600,13276.1842890311 +1000,700,15477.7580036837 +1000,800,17682.6776778131 +1000,900,19910.3154481575 +1000,1000,22137.4733292159 +1000,1070,23687.7506196206 +1200,-74.94288,0 +1200,0,1466.76867771795 +1200,70,2384.23009234109 +1200,100,3063.16420928352 +1200,200,5358.94354906042 +1200,300,7700.66955890544 +1200,400,10081.2181858202 +1200,500,12574.8172610242 +1200,600,14901.7176100172 +1200,700,17181.5389663098 +1200,800,19567.9282814255 +1200,900,21988.5025840009 +1200,1000,24410.5499938238 +1200,1100,26818.115111918 +1200,1200,29600.8460156484 +1400,-86.2547035,0 +1400,0,1943.23102011723 +1400,70,2867.47013233511 +1400,100,3660.89882141199 +1400,200,6305.66552427192 +1400,300,9033.22733052332 +1400,400,11786.0215181328 +1400,500,14469.4815362731 +1400,600,17183.3279696788 +1400,700,20019.0117898106 +1400,800,22833.0135382571 +1400,900,25503.8101180654 +1400,1000,28133.1269579571 +1400,1100,30822.6887344662 +1400,1200,33616.5017759808 +1600,-97.566527,0 +1600,0,2390.6835686806 +1600,70,3375.40160192783 +1600,100,4270.71119614809 +1600,200,7255.07651021562 +1600,300,10395.2548568878 +1600,400,13532.5784663098 +1600,500,16706.5392692034 +1600,600,19830.2452028337 +1600,700,22960.5043452122 +1600,800,26109.440635472 +1600,900,29158.7021558733 +1600,1000,32050.2297249921 +1600,1100,35223.8264822578 +1600,1200,38415.2311208446 +1800,-104.414737,0 +1800,0,2890.45579554627 +1800,70,3985.0324218874 +1800,100,4965.43037801527 +1800,200,8233.42356510818 +1800,300,11783.4265584525 +1800,400,15307.0860504043 +1800,500,18849.1633858464 +1800,600,22267.4693346934 +1800,700,25749.1637322378 +1800,800,29389.5619094482 +1800,900,32951.6548737928 +1800,1000,36567.9831510803 +1800,1100,40354.8768962419 +1800,1124,41263.456024854 +2000,-111.72677,0 +2000,0,3496.10145365531 +2000,70,4806.78887658531 +2000,100,5854.50681474508 +2000,200,9346.90740755971 +2000,300,13318.196653646 +2000,400,17192.1593059257 +2000,500,21141.1017187055 +2000,600,25063.6902845325 +2000,700,28933.7283892341 +2000,800,33033.1981895635 +2000,900,37186.4876337875 +2000,1000,41216.6584804945 +2000,1038,42697.6298262953 +2200,-125.56264,0 +2200,0,4247.17502566154 +2200,70,5534.02108620948 +2200,100,6687.77342580669 +2200,200,10533.6121100547 +2200,300,14853.0183929775 +2200,400,19148.399769035 +2200,500,23390.9892034139 +2200,600,27829.4437635697 +2200,700,32500.7462334357 +2200,800,37123.6305457812 +2200,900,41612.3079508872 +2200,955,44050.2046085433 +2400,-135.718847,0 +2400,0,4945.09679719305 +2400,70,6234.18143404208 +2400,100,7525.65706479749 +2400,200,11830.6027591525 +2400,300,16443.4719386838 +2400,400,21308.1934105712 +2400,500,26325.659943101 +2400,600,31335.4206079209 +2400,700,36716.1939552295 +2400,800,42106.7959841282 +2400,815,42844.1063139178 +2500,-140.183674,0 +2500,0,5337.86693039768 +2500,70,6286.75667605001 +2500,100,7731.92699872726 +2500,200,12386.9152267725 +2500,300,17232.6104469567 +2500,400,22335.9931616381 +2500,500,27944.5498150782 +2500,600,33199.9206079209 +2500,710,39388.7795567867 +2600,-146.132532,0 +2600,0,5534.251997 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_1_i=3-49.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_1_i=3-49.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..5e25d590800c006073435dc6f634f14e0848cbb4 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_1_i=3-49.vtlm @@ -0,0 +1,202 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,56 +0,400,64 +0,600,72 +0,900,84 +0,1200,96 +0,1600,112 +0,2000,128 +0,2500,148 +600,0,48 +600,200,56 +600,400,64 +600,600,72 +600,900,84 +600,1200,96 +600,1600,112 +600,2000,128 +600,2500,148 +900,0,57 +900,200,65 +900,400,73 +900,600,81 +900,900,93 +900,1200,105 +900,1600,121 +900,2000,137 +900,2500,157 +1200,0,66 +1200,200,74 +1200,400,82 +1200,600,90 +1200,900,102 +1200,1200,114 +1200,1600,130 +1200,2000,146 +1200,2500,166 +1600,0,78 +1600,200,86 +1600,400,94 +1600,600,102 +1600,900,114 +1600,1200,126 +1600,1600,142 +1600,2000,158 +1600,2500,178 +2000,0,90 +2000,200,98 +2000,400,106 +2000,600,114 +2000,900,126 +2000,1200,138 +2000,1600,154 +2000,2000,170 +2000,2500,190 +2500,0,105 +2500,200,113 +2500,400,121 +2500,600,129 +2500,900,141 +2500,1200,153 +2500,1600,169 +2500,2000,185 +2500,2500,205 +3000,0,120 +3000,200,128 +3000,400,136 +3000,600,144 +3000,900,156 +3000,1200,168 +3000,1600,184 +3000,2000,200 +3000,2500,220 +600,0,48 +600,-200,56 +600,-400,64 +600,-600,72 +600,-900,84 +600,-1200,96 +600,-1600,112 +600,-2000,128 +600,-2500,148 +900,0,57 +900,-200,65 +900,-400,73 +900,-600,81 +900,-900,93 +900,-1200,105 +900,-1600,121 +900,-2000,137 +900,-2500,157 +1200,0,66 +1200,-200,74 +1200,-400,82 +1200,-600,90 +1200,-900,102 +1200,-1200,114 +1200,-1600,130 +1200,-2000,146 +1200,-2500,166 +1600,0,78 +1600,-200,86 +1600,-400,94 +1600,-600,102 +1600,-900,114 +1600,-1200,126 +1600,-1600,142 +1600,-2000,158 +1600,-2500,178 +2000,0,90 +2000,-200,98 +2000,-400,106 +2000,-600,114 +2000,-900,126 +2000,-1200,138 +2000,-1600,154 +2000,-2000,170 +2000,-2500,190 +2500,0,105 +2500,-200,113 +2500,-400,121 +2500,-600,129 +2500,-900,141 +2500,-1200,153 +2500,-1600,169 +2500,-2000,185 +2500,-2500,205 +3000,0,120 +3000,-200,128 +3000,-400,136 +3000,-600,144 +3000,-900,156 +3000,-1200,168 +3000,-1600,184 +3000,-2000,200 +3000,-2500,220 +1300,2610,66 +1300,2842,71 +1500,-812,46 +1500,-348,37 +1500,0,13 +1500,58,16 +1500,290,21 +1500,522,26 +1500,754,30 +1500,986,35 +1500,1218,39 +1500,1450,44 +1500,1682,49 +1500,1914,53 +1500,2146,58 +1500,2378,63 +1500,2610,67 +1500,2842,72 +1700,-812,49 +1700,-348,39 +1700,0,14 +1700,58,17 +1700,290,22 +1700,522,27 +1700,754,31 +1700,986,36 +1700,1218,41 +1700,1450,45 +1700,1682,50 +1700,1914,55 +1700,2146,59 +1700,2378,64 +1700,2610,68 +1700,2842,73 +1900,-812,51 +1900,-348,42 +1900,0,15 +1900,58,19 +1900,290,23 +1900,522,28 +1900,754,32 +1900,986,37 +1900,1218,42 +1900,1450,46 +1900,1682,51 +1900,1914,56 +1900,2146,60 +1900,2378,65 +1900,2610,70 +1900,2842,74 +2100,-812,53 +2100,-348,44 +2100,0,16 +2100,58,20 +2100,290,24 +2100,522,29 +2100,754,34 +2100,986,38 +2100,1218,43 +2100,1450,48 +2100,1682,52 +2100,1914,57 +2100,2146,61 +2100,2378,66 +2100,2610,71 +2100,2842,75 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_2_i=1-86.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_2_i=1-86.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..1cdc06160aa4dcdfe6fcf5775fc18e4c5fa943ff --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_2_i=1-86.vtlm @@ -0,0 +1,136 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,56 +0,400,64 +0,600,72 +0,900,84 +0,1200,96 +0,1600,112 +0,2000,128 +0,2500,148 +600,0,48 +600,200,56 +600,400,64 +600,600,72 +600,900,84 +600,1200,96 +600,1600,112 +600,2000,128 +600,2500,148 +900,0,57 +900,200,65 +900,400,73 +900,600,81 +900,900,93 +900,1200,105 +900,1600,121 +900,2000,137 +900,2500,157 +1200,0,66 +1200,200,74 +1200,400,82 +1200,600,90 +1200,900,102 +1200,1200,114 +1200,1600,130 +1200,2000,146 +1200,2500,166 +1600,0,78 +1600,200,86 +1600,400,94 +1600,600,102 +1600,900,114 +1600,1200,126 +1600,1600,142 +1600,2000,158 +1600,2500,178 +2000,0,90 +2000,200,98 +2000,400,106 +2000,600,114 +2000,900,126 +2000,1200,138 +2000,1600,154 +2000,2000,170 +2000,2500,190 +2500,0,105 +2500,200,113 +2500,400,121 +2500,600,129 +2500,900,141 +2500,1200,153 +2500,1600,169 +2500,2000,185 +2500,2500,205 +3000,0,120 +3000,200,128 +3000,400,136 +3000,600,144 +3000,900,156 +3000,1200,168 +3000,1600,184 +3000,2000,200 +3000,2500,220 +600,0,48 +600,-200,56 +600,-400,64 +600,-600,72 +600,-900,84 +600,-1200,96 +600,-1600,112 +600,-2000,128 +600,-2500,148 +900,0,57 +900,-200,65 +900,-400,73 +900,-600,81 +900,-900,93 +900,-1200,105 +900,-1600,121 +900,-2000,137 +900,-2500,157 +1200,0,66 +1200,-200,74 +1200,-400,82 +1200,-600,90 +1200,-900,102 +1200,-1200,114 +1200,-1600,130 +1200,-2000,146 +1200,-2500,166 +1600,0,78 +1600,-200,86 +1600,-400,94 +1600,-600,102 +1600,-900,114 +1600,-1200,126 +1600,-1600,142 +1600,-2000,158 +1600,-2500,178 +2000,0,90 +2000,-200,98 +2000,-400,106 +2000,-600,114 +2000,-900,126 +2000,-1200,138 +2000,-1600,154 +2000,-2000,170 +2000,-2500,190 +2500,0,105 +2500,-200,113 +2500,-400,121 +2500,-600,129 +2500,-900,141 +2500,-1200,153 +2500,-1600,169 +2500,-2000,185 +2500,-2500,205 +3000,0,120 +3000,-200,128 +3000,-400,136 +3000,-600,144 +3000,-900,156 +3000,-1200,168 +3000,-1600,184 +3000,-2000,200 +3000,-2500,220 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_3_i=1-41.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_3_i=1-41.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..1cdc06160aa4dcdfe6fcf5775fc18e4c5fa943ff --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_3_i=1-41.vtlm @@ -0,0 +1,136 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,56 +0,400,64 +0,600,72 +0,900,84 +0,1200,96 +0,1600,112 +0,2000,128 +0,2500,148 +600,0,48 +600,200,56 +600,400,64 +600,600,72 +600,900,84 +600,1200,96 +600,1600,112 +600,2000,128 +600,2500,148 +900,0,57 +900,200,65 +900,400,73 +900,600,81 +900,900,93 +900,1200,105 +900,1600,121 +900,2000,137 +900,2500,157 +1200,0,66 +1200,200,74 +1200,400,82 +1200,600,90 +1200,900,102 +1200,1200,114 +1200,1600,130 +1200,2000,146 +1200,2500,166 +1600,0,78 +1600,200,86 +1600,400,94 +1600,600,102 +1600,900,114 +1600,1200,126 +1600,1600,142 +1600,2000,158 +1600,2500,178 +2000,0,90 +2000,200,98 +2000,400,106 +2000,600,114 +2000,900,126 +2000,1200,138 +2000,1600,154 +2000,2000,170 +2000,2500,190 +2500,0,105 +2500,200,113 +2500,400,121 +2500,600,129 +2500,900,141 +2500,1200,153 +2500,1600,169 +2500,2000,185 +2500,2500,205 +3000,0,120 +3000,200,128 +3000,400,136 +3000,600,144 +3000,900,156 +3000,1200,168 +3000,1600,184 +3000,2000,200 +3000,2500,220 +600,0,48 +600,-200,56 +600,-400,64 +600,-600,72 +600,-900,84 +600,-1200,96 +600,-1600,112 +600,-2000,128 +600,-2500,148 +900,0,57 +900,-200,65 +900,-400,73 +900,-600,81 +900,-900,93 +900,-1200,105 +900,-1600,121 +900,-2000,137 +900,-2500,157 +1200,0,66 +1200,-200,74 +1200,-400,82 +1200,-600,90 +1200,-900,102 +1200,-1200,114 +1200,-1600,130 +1200,-2000,146 +1200,-2500,166 +1600,0,78 +1600,-200,86 +1600,-400,94 +1600,-600,102 +1600,-900,114 +1600,-1200,126 +1600,-1600,142 +1600,-2000,158 +1600,-2500,178 +2000,0,90 +2000,-200,98 +2000,-400,106 +2000,-600,114 +2000,-900,126 +2000,-1200,138 +2000,-1600,154 +2000,-2000,170 +2000,-2500,190 +2500,0,105 +2500,-200,113 +2500,-400,121 +2500,-600,129 +2500,-900,141 +2500,-1200,153 +2500,-1600,169 +2500,-2000,185 +2500,-2500,205 +3000,0,120 +3000,-200,128 +3000,-400,136 +3000,-600,144 +3000,-900,156 +3000,-1200,168 +3000,-1600,184 +3000,-2000,200 +3000,-2500,220 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_4_i=1.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_4_i=1.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..36365e666f12b3e1f9083aaf6dc653069c1e92f3 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_4_i=1.vtlm @@ -0,0 +1,136 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,50 +0,400,52 +0,600,54 +0,900,57 +0,1200,60 +0,1600,64 +0,2000,68 +0,2500,73 +600,0,48 +600,200,50 +600,400,52 +600,600,54 +600,900,57 +600,1200,60 +600,1600,64 +600,2000,68 +600,2500,73 +900,0,57 +900,200,59 +900,400,61 +900,600,63 +900,900,66 +900,1200,69 +900,1600,73 +900,2000,77 +900,2500,82 +1200,0,66 +1200,200,68 +1200,400,70 +1200,600,72 +1200,900,75 +1200,1200,78 +1200,1600,82 +1200,2000,86 +1200,2500,91 +1600,0,78 +1600,200,80 +1600,400,82 +1600,600,84 +1600,900,87 +1600,1200,90 +1600,1600,94 +1600,2000,98 +1600,2500,103 +2000,0,90 +2000,200,92 +2000,400,94 +2000,600,96 +2000,900,99 +2000,1200,102 +2000,1600,106 +2000,2000,110 +2000,2500,115 +2500,0,105 +2500,200,107 +2500,400,109 +2500,600,111 +2500,900,114 +2500,1200,117 +2500,1600,121 +2500,2000,125 +2500,2500,130 +3000,0,120 +3000,200,122 +3000,400,124 +3000,600,126 +3000,900,129 +3000,1200,132 +3000,1600,136 +3000,2000,140 +3000,2500,145 +600,0,48 +600,-200,50 +600,-400,52 +600,-600,54 +600,-900,57 +600,-1200,60 +600,-1600,64 +600,-2000,68 +600,-2500,73 +900,0,57 +900,-200,59 +900,-400,61 +900,-600,63 +900,-900,66 +900,-1200,69 +900,-1600,73 +900,-2000,77 +900,-2500,82 +1200,0,66 +1200,-200,68 +1200,-400,70 +1200,-600,72 +1200,-900,75 +1200,-1200,78 +1200,-1600,82 +1200,-2000,86 +1200,-2500,91 +1600,0,78 +1600,-200,80 +1600,-400,82 +1600,-600,84 +1600,-900,87 +1600,-1200,90 +1600,-1600,94 +1600,-2000,98 +1600,-2500,103 +2000,0,90 +2000,-200,92 +2000,-400,94 +2000,-600,96 +2000,-900,99 +2000,-1200,102 +2000,-1600,106 +2000,-2000,110 +2000,-2500,115 +2500,0,105 +2500,-200,107 +2500,-400,109 +2500,-600,111 +2500,-900,114 +2500,-1200,117 +2500,-1600,121 +2500,-2000,125 +2500,-2500,130 +3000,0,120 +3000,-200,122 +3000,-400,124 +3000,-600,126 +3000,-900,129 +3000,-1200,132 +3000,-1600,136 +3000,-2000,140 +3000,-2500,145 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_5_i=0-75.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_5_i=0-75.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..1cdc06160aa4dcdfe6fcf5775fc18e4c5fa943ff --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_5_i=0-75.vtlm @@ -0,0 +1,136 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,56 +0,400,64 +0,600,72 +0,900,84 +0,1200,96 +0,1600,112 +0,2000,128 +0,2500,148 +600,0,48 +600,200,56 +600,400,64 +600,600,72 +600,900,84 +600,1200,96 +600,1600,112 +600,2000,128 +600,2500,148 +900,0,57 +900,200,65 +900,400,73 +900,600,81 +900,900,93 +900,1200,105 +900,1600,121 +900,2000,137 +900,2500,157 +1200,0,66 +1200,200,74 +1200,400,82 +1200,600,90 +1200,900,102 +1200,1200,114 +1200,1600,130 +1200,2000,146 +1200,2500,166 +1600,0,78 +1600,200,86 +1600,400,94 +1600,600,102 +1600,900,114 +1600,1200,126 +1600,1600,142 +1600,2000,158 +1600,2500,178 +2000,0,90 +2000,200,98 +2000,400,106 +2000,600,114 +2000,900,126 +2000,1200,138 +2000,1600,154 +2000,2000,170 +2000,2500,190 +2500,0,105 +2500,200,113 +2500,400,121 +2500,600,129 +2500,900,141 +2500,1200,153 +2500,1600,169 +2500,2000,185 +2500,2500,205 +3000,0,120 +3000,200,128 +3000,400,136 +3000,600,144 +3000,900,156 +3000,1200,168 +3000,1600,184 +3000,2000,200 +3000,2500,220 +600,0,48 +600,-200,56 +600,-400,64 +600,-600,72 +600,-900,84 +600,-1200,96 +600,-1600,112 +600,-2000,128 +600,-2500,148 +900,0,57 +900,-200,65 +900,-400,73 +900,-600,81 +900,-900,93 +900,-1200,105 +900,-1600,121 +900,-2000,137 +900,-2500,157 +1200,0,66 +1200,-200,74 +1200,-400,82 +1200,-600,90 +1200,-900,102 +1200,-1200,114 +1200,-1600,130 +1200,-2000,146 +1200,-2500,166 +1600,0,78 +1600,-200,86 +1600,-400,94 +1600,-600,102 +1600,-900,114 +1600,-1200,126 +1600,-1600,142 +1600,-2000,158 +1600,-2500,178 +2000,0,90 +2000,-200,98 +2000,-400,106 +2000,-600,114 +2000,-900,126 +2000,-1200,138 +2000,-1600,154 +2000,-2000,170 +2000,-2500,190 +2500,0,105 +2500,-200,113 +2500,-400,121 +2500,-600,129 +2500,-900,141 +2500,-1200,153 +2500,-1600,169 +2500,-2000,185 +2500,-2500,205 +3000,0,120 +3000,-200,128 +3000,-400,136 +3000,-600,144 +3000,-900,156 +3000,-1200,168 +3000,-1600,184 +3000,-2000,200 +3000,-2500,220 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_6_i=0-65.vtlm b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_6_i=0-65.vtlm new file mode 100644 index 0000000000000000000000000000000000000000..1cdc06160aa4dcdfe6fcf5775fc18e4c5fa943ff --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/Gear_6_i=0-65.vtlm @@ -0,0 +1,136 @@ +Input Speed [1/min], Input Torque [Nm], Torque Loss [Nm] +0,0,48 +0,200,56 +0,400,64 +0,600,72 +0,900,84 +0,1200,96 +0,1600,112 +0,2000,128 +0,2500,148 +600,0,48 +600,200,56 +600,400,64 +600,600,72 +600,900,84 +600,1200,96 +600,1600,112 +600,2000,128 +600,2500,148 +900,0,57 +900,200,65 +900,400,73 +900,600,81 +900,900,93 +900,1200,105 +900,1600,121 +900,2000,137 +900,2500,157 +1200,0,66 +1200,200,74 +1200,400,82 +1200,600,90 +1200,900,102 +1200,1200,114 +1200,1600,130 +1200,2000,146 +1200,2500,166 +1600,0,78 +1600,200,86 +1600,400,94 +1600,600,102 +1600,900,114 +1600,1200,126 +1600,1600,142 +1600,2000,158 +1600,2500,178 +2000,0,90 +2000,200,98 +2000,400,106 +2000,600,114 +2000,900,126 +2000,1200,138 +2000,1600,154 +2000,2000,170 +2000,2500,190 +2500,0,105 +2500,200,113 +2500,400,121 +2500,600,129 +2500,900,141 +2500,1200,153 +2500,1600,169 +2500,2000,185 +2500,2500,205 +3000,0,120 +3000,200,128 +3000,400,136 +3000,600,144 +3000,900,156 +3000,1200,168 +3000,1600,184 +3000,2000,200 +3000,2500,220 +600,0,48 +600,-200,56 +600,-400,64 +600,-600,72 +600,-900,84 +600,-1200,96 +600,-1600,112 +600,-2000,128 +600,-2500,148 +900,0,57 +900,-200,65 +900,-400,73 +900,-600,81 +900,-900,93 +900,-1200,105 +900,-1600,121 +900,-2000,137 +900,-2500,157 +1200,0,66 +1200,-200,74 +1200,-400,82 +1200,-600,90 +1200,-900,102 +1200,-1200,114 +1200,-1600,130 +1200,-2000,146 +1200,-2500,166 +1600,0,78 +1600,-200,86 +1600,-400,94 +1600,-600,102 +1600,-900,114 +1600,-1200,126 +1600,-1600,142 +1600,-2000,158 +1600,-2500,178 +2000,0,90 +2000,-200,98 +2000,-400,106 +2000,-600,114 +2000,-900,126 +2000,-1200,138 +2000,-1600,154 +2000,-2000,170 +2000,-2500,190 +2500,0,105 +2500,-200,113 +2500,-400,121 +2500,-600,129 +2500,-900,141 +2500,-1200,153 +2500,-1600,169 +2500,-2000,185 +2500,-2500,205 +3000,0,120 +3000,-200,128 +3000,-400,136 +3000,-600,144 +3000,-900,156 +3000,-1200,168 +3000,-1600,184 +3000,-2000,200 +3000,-2500,220 diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/RigidTruck_6x2.vveh b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/RigidTruck_6x2.vveh new file mode 100644 index 0000000000000000000000000000000000000000..9abad02504a0b58c3636ef26ba0220b74bb50d2e --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/RigidTruck_6x2.vveh @@ -0,0 +1,70 @@ +{ + "Header": { + "CreatedBy": "", + "Date": "2017-07-03T14:48:36.5106880Z", + "AppVersion": "3", + "FileVersion": 7 + }, + "Body": { + "SavedInDeclMode": true, + "VehCat": "RigidTruck", + "LegislativeClass": "N3", + "CurbWeight": 7750.0, + "CurbWeightExtra": 0.0, + "Loading": 0.0, + "MassMax": 26.0, + "rdyn": 0.0, + "CdCorrMode": "CdofVdecl", + "CdCorrFile": "", + "Retarder": { + "Type": "None", + "Ratio": 1.0, + "File": "" + }, + "Angledrive": { + "Type": "None", + "Ratio": "NaN", + "LossMap": "" + }, + "PTO": { + "Type": "only the drive shaft of the PTO - shift claw, synchronizer, sliding gearwheel", + "LossMap": "", + "Cycle": "" + }, + "TorqueLimits": {}, + "IdlingSpeed": 0.0, + "AxleConfig": { + "Type": "6x2", + "Axles": [ + { + "Inertia": 14.9, + "Wheels": "315/70 R22.5", + "AxleWeightShare": 0.0, + "TwinTyres": false, + "RRCISO": 0.0055, + "FzISO": 33350.0, + "Type": "VehicleNonDriven" + }, + { + "Inertia": 14.9, + "Wheels": "315/70 R22.5", + "AxleWeightShare": 0.0, + "TwinTyres": true, + "RRCISO": 0.0055, + "FzISO": 33350.0, + "Type": "VehicleDriven" + }, + { + "Inertia": 14.9, + "Wheels": "315/70 R22.5", + "AxleWeightShare": 0.0, + "TwinTyres": false, + "RRCISO": 0.0055, + "FzISO": 33350.0, + "Type": "VehicleNonDriven" + } + ] + }, + "CdA": 5.8 + } +} \ No newline at end of file diff --git a/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/TorqueConverter_Serial_TqMax1200.vtcc b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/TorqueConverter_Serial_TqMax1200.vtcc new file mode 100644 index 0000000000000000000000000000000000000000..e96d65d4c14370fdda7fb7f432bd1400685cb056 --- /dev/null +++ b/Generic Vehicles/Declaration Mode/Class9_RigidTruck_AT_6x2/TorqueConverter_Serial_TqMax1200.vtcc @@ -0,0 +1,28 @@ +Speed Ratio, Torque Ratio, Input Torque at reference rpm +0,1.8,404.790015179626 +0.1,1.70555555555556,391.297014673638 +0.2,1.61111111111111,377.804014167651 +0.3,1.51666666666667,364.311013661663 +0.4,1.42222222222222,350.818013155675 +0.5,1.32777777777778,337.325012649688 +0.6,1.23333333333333,323.8320121437 +0.65,1.18611111111111,303.592511384719 +0.7,1.13888888888889,283.353010625738 +0.75,1.09166666666667,263.113509866757 +0.8,1.04444444444444,242.874009107775 +0.85,0.997222222222222,222.634508348794 +0.9,0.95,202.395007589813 +0.95,0.95,101.197503794907 +1,0.95,0 +1.1,0.9999,-40.34 +1.222,0.9998,-80.34 +1.375,0.9997,-136.11 +1.571,0.9996,-216.52 +1.833,0.9995,-335.19 +2.2,0.9994,-528.77 +2.5,0.9993,-721 +3,0.9992,-1122 +3.5,0.9991,-1648 +4,0.999,-2326 +4.5,0.9989,-3182 +5,0.9988,-4242 diff --git a/VECTO.sln b/VECTO.sln index f6601e5fd41736ec568ec48329b1322282b60441..f30c2893267063f9b98fb47c75a6305dbf38bf53 100644 --- a/VECTO.sln +++ b/VECTO.sln @@ -66,6 +66,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingCmd", "HashingCmd\Ha EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug PerformanceStats|Any CPU = Debug PerformanceStats|Any CPU + Debug PerformanceStats|x64 = Debug PerformanceStats|x64 + Debug PerformanceStats|x86 = Debug PerformanceStats|x86 + Debug PerformanceTrace|Any CPU = Debug PerformanceTrace|Any CPU + Debug PerformanceTrace|x64 = Debug PerformanceTrace|x64 + Debug PerformanceTrace|x86 = Debug PerformanceTrace|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 @@ -74,6 +80,16 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceStats|Any CPU.ActiveCfg = Release|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceStats|Any CPU.Build.0 = Release|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceStats|x86.ActiveCfg = Debug|x86 + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceStats|x86.Build.0 = Debug|x86 + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceTrace|x86.ActiveCfg = Debug|x86 + {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug PerformanceTrace|x86.Build.0 = Debug|x86 {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug|Any CPU.Build.0 = Debug|Any CPU {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -84,6 +100,12 @@ Global {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Release|x64.ActiveCfg = Release|Any CPU {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Release|x86.ActiveCfg = Release|x86 {AAC0F132-0A9F-45B3-B682-77AC9B24B352}.Release|x86.Build.0 = Release|x86 + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug|Any CPU.Build.0 = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -92,6 +114,14 @@ Global {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Release|Any CPU.Build.0 = Release|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Release|x64.ActiveCfg = Release|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Release|x86.ActiveCfg = Release|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -100,6 +130,12 @@ Global {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Release|Any CPU.Build.0 = Release|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Release|x64.ActiveCfg = Release|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Release|x86.ActiveCfg = Release|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -108,6 +144,14 @@ Global {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Release|Any CPU.Build.0 = Release|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Release|x64.ActiveCfg = Release|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Release|x86.ActiveCfg = Release|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -116,12 +160,24 @@ Global {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|Any CPU.Build.0 = Release|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|x64.ActiveCfg = Release|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|x86.ActiveCfg = Release|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|x64.ActiveCfg = Debug|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Debug|x86.ActiveCfg = Debug|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|Any CPU.ActiveCfg = Release|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|x64.ActiveCfg = Release|Any CPU {E23B3A9B-62E7-4476-849E-EEF1C3804A2F}.Release|x86.ActiveCfg = Release|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -130,6 +186,14 @@ Global {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Release|Any CPU.Build.0 = Release|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Release|x64.ActiveCfg = Release|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Release|x86.ActiveCfg = Release|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug|Any CPU.Build.0 = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -138,6 +202,14 @@ Global {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Release|Any CPU.Build.0 = Release|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Release|x64.ActiveCfg = Release|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Release|x86.ActiveCfg = Release|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug|Any CPU.Build.0 = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -146,6 +218,14 @@ Global {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Release|Any CPU.Build.0 = Release|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Release|x64.ActiveCfg = Release|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Release|x86.ActiveCfg = Release|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug|Any CPU.Build.0 = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -154,6 +234,14 @@ Global {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Release|Any CPU.Build.0 = Release|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Release|x64.ActiveCfg = Release|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Release|x86.ActiveCfg = Release|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceStats|Any CPU.Build.0 = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceTrace|Any CPU.Build.0 = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug|Any CPU.Build.0 = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -162,6 +250,12 @@ Global {E8B0B447-1A54-4BEC-A160-AF0017000781}.Release|Any CPU.Build.0 = Release|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Release|x64.ActiveCfg = Release|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Release|x86.ActiveCfg = Release|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug|Any CPU.Build.0 = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -170,6 +264,12 @@ Global {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|Any CPU.Build.0 = Release|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|x64.ActiveCfg = Release|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|x86.ActiveCfg = Release|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -178,6 +278,12 @@ Global {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Release|Any CPU.Build.0 = Release|Any CPU {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Release|x64.ActiveCfg = Release|Any CPU {A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Release|x86.ActiveCfg = Release|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug|Any CPU.Build.0 = Debug|Any CPU {49F0275A-4517-49FA-859E-77279B9C8B18}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -186,6 +292,12 @@ Global {49F0275A-4517-49FA-859E-77279B9C8B18}.Release|Any CPU.Build.0 = Release|Any CPU {49F0275A-4517-49FA-859E-77279B9C8B18}.Release|x64.ActiveCfg = Release|Any CPU {49F0275A-4517-49FA-859E-77279B9C8B18}.Release|x86.ActiveCfg = Release|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|Any CPU.Build.0 = Debug|Any CPU {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -194,6 +306,12 @@ Global {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|Any CPU.Build.0 = Release|Any CPU {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|x64.ActiveCfg = Release|Any CPU {512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|x86.ActiveCfg = Release|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -202,6 +320,12 @@ Global {D959CB7C-F514-4F5E-9C33-684D0012474B}.Release|Any CPU.Build.0 = Release|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Release|x64.ActiveCfg = Release|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Release|x86.ActiveCfg = Release|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -210,6 +334,12 @@ Global {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|Any CPU.Build.0 = Release|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|x64.ActiveCfg = Release|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|x86.ActiveCfg = Release|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug|Any CPU.Build.0 = Debug|Any CPU {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -218,6 +348,12 @@ Global {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Release|Any CPU.Build.0 = Release|Any CPU {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Release|x64.ActiveCfg = Release|Any CPU {749F150A-F974-46DC-A1E2-F4153C54FC0D}.Release|x86.ActiveCfg = Release|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -226,6 +362,12 @@ Global {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|Any CPU.Build.0 = Release|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|x64.ActiveCfg = Release|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|x86.ActiveCfg = Release|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -234,6 +376,12 @@ Global {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Release|Any CPU.Build.0 = Release|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Release|x64.ActiveCfg = Release|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Release|x86.ActiveCfg = Release|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -242,6 +390,12 @@ Global {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Release|Any CPU.Build.0 = Release|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Release|x64.ActiveCfg = Release|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Release|x86.ActiveCfg = Release|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug|Any CPU.Build.0 = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -250,6 +404,12 @@ Global {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Release|Any CPU.Build.0 = Release|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Release|x64.ActiveCfg = Release|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Release|x86.ActiveCfg = Release|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug|Any CPU.Build.0 = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -258,6 +418,12 @@ Global {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Release|Any CPU.Build.0 = Release|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Release|x64.ActiveCfg = Release|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Release|x86.ActiveCfg = Release|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceStats|Any CPU.ActiveCfg = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceStats|x64.ActiveCfg = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceStats|x86.ActiveCfg = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceTrace|Any CPU.ActiveCfg = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceTrace|x64.ActiveCfg = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug PerformanceTrace|x86.ActiveCfg = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug|Any CPU.Build.0 = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/VECTO/GUI/GearboxForm.vb b/VECTO/GUI/GearboxForm.vb index ce627dd40915b78c8d2e58edd4715bf7225c11da..e7444abdc5ac65f7600b80ec8b50e088306854f6 100644 --- a/VECTO/GUI/GearboxForm.vb +++ b/VECTO/GUI/GearboxForm.vb @@ -129,7 +129,7 @@ Public Class GearboxForm Private Sub ToolStripBtOpen_Click(sender As Object, e As EventArgs) Handles ToolStripBtOpen.Click If GearboxFileBrowser.OpenDialog(_gbxFile) Then Try - OpenGbx(GearboxFileBrowser.Files(0)) + OpenGbx(GearboxFileBrowser.Files(0), VehicleCategory.RigidTruck) Catch ex As Exception MsgBox("Failed to open Gearbox File: " + ex.Message) End Try @@ -231,7 +231,7 @@ Public Class GearboxForm End Sub 'Open file - Public Sub OpenGbx(file As String) + Public Sub OpenGbx(file As String, vehicleCategory As VehicleCategory) If ChangeCheckCancel() Then Exit Sub @@ -240,6 +240,8 @@ Public Class GearboxForm Dim gearbox As IGearboxEngineeringInputData = inputData.GearboxInputData Dim axlegear As IAxleGearInputData = inputData.AxleGearInputData + _vehicleCategory = vehicleCategory + If Cfg.DeclMode <> gearbox.SavedInDeclarationMode Then Select Case WrongMode() Case 1 @@ -521,7 +523,8 @@ Public Class GearboxForm If LvGears.Items.Count > 2 Then Dim ratio1 As Double = LvGears.Items.Item(1).SubItems(GearboxTbl.Ratio).Text.ToDouble(0) Dim ratio2 As Double = LvGears.Items.Item(2).SubItems(GearboxTbl.Ratio).Text.ToDouble(0) - If ratio1 / ratio2 >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold Then + + If ratio1 / ratio2 >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold(_vehicleCategory) Then text = "Torque converter is used in 1st and 2nd gear" Else text = "Torque converter is used in 1st gear only" @@ -693,6 +696,7 @@ Public Class GearboxForm #Region "Open File Context Menu" Private _contextMenuFiles As String() + Private _vehicleCategory As VehicleCategory Private Sub OpenFiles(ParamArray files() As String) diff --git a/VECTO/GUI/MainForm.Designer.vb b/VECTO/GUI/MainForm.Designer.vb index 74c4c9b3838a7b7c3d2d38c03c2a89a1caec507d..bea024c9f0a7009523dd6109cb5d464aacace9b0 100644 --- a/VECTO/GUI/MainForm.Designer.vb +++ b/VECTO/GUI/MainForm.Designer.vb @@ -114,6 +114,7 @@ Partial Class MainForm Me.OpenInGraphWindowToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() Me.ShowInFolderToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components) + Me.cbActVmod = New System.Windows.Forms.CheckBox() Me.StatusBAR.SuspendLayout() Me.TabControl1.SuspendLayout() Me.TabPageGEN.SuspendLayout() @@ -383,10 +384,11 @@ Partial Class MainForm ' 'GroupBox3 ' + Me.GroupBox3.Controls.Add(Me.cbActVmod) Me.GroupBox3.Controls.Add(Me.cbValidateRunData) Me.GroupBox3.Location = New System.Drawing.Point(3, 177) Me.GroupBox3.Name = "GroupBox3" - Me.GroupBox3.Size = New System.Drawing.Size(173, 64) + Me.GroupBox3.Size = New System.Drawing.Size(173, 110) Me.GroupBox3.TabIndex = 18 Me.GroupBox3.TabStop = False Me.GroupBox3.Text = "Misc" @@ -680,52 +682,52 @@ Partial Class MainForm ' Me.GENEditorToolStripMenuItem1.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_VECTO Me.GENEditorToolStripMenuItem1.Name = "GENEditorToolStripMenuItem1" - Me.GENEditorToolStripMenuItem1.Size = New System.Drawing.Size(170, 22) + Me.GENEditorToolStripMenuItem1.Size = New System.Drawing.Size(151, 22) Me.GENEditorToolStripMenuItem1.Text = "Job Editor" ' 'VEHEditorToolStripMenuItem ' Me.VEHEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_VEH Me.VEHEditorToolStripMenuItem.Name = "VEHEditorToolStripMenuItem" - Me.VEHEditorToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.VEHEditorToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.VEHEditorToolStripMenuItem.Text = "Vehicle Editor" ' 'EngineEditorToolStripMenuItem ' Me.EngineEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_ENG Me.EngineEditorToolStripMenuItem.Name = "EngineEditorToolStripMenuItem" - Me.EngineEditorToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.EngineEditorToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.EngineEditorToolStripMenuItem.Text = "Engine Editor" ' 'GearboxEditorToolStripMenuItem ' Me.GearboxEditorToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_GBX Me.GearboxEditorToolStripMenuItem.Name = "GearboxEditorToolStripMenuItem" - Me.GearboxEditorToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.GearboxEditorToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.GearboxEditorToolStripMenuItem.Text = "Gearbox Editor" ' 'GraphToolStripMenuItem ' Me.GraphToolStripMenuItem.Image = Global.TUGraz.VECTO.My.Resources.Resources.F_Graph Me.GraphToolStripMenuItem.Name = "GraphToolStripMenuItem" - Me.GraphToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.GraphToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.GraphToolStripMenuItem.Text = "Graph" ' 'ToolStripSeparator6 ' Me.ToolStripSeparator6.Name = "ToolStripSeparator6" - Me.ToolStripSeparator6.Size = New System.Drawing.Size(167, 6) + Me.ToolStripSeparator6.Size = New System.Drawing.Size(148, 6) ' 'OpenLogToolStripMenuItem ' Me.OpenLogToolStripMenuItem.Name = "OpenLogToolStripMenuItem" - Me.OpenLogToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.OpenLogToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.OpenLogToolStripMenuItem.Text = "Open Log" ' 'SettingsToolStripMenuItem ' Me.SettingsToolStripMenuItem.Name = "SettingsToolStripMenuItem" - Me.SettingsToolStripMenuItem.Size = New System.Drawing.Size(170, 22) + Me.SettingsToolStripMenuItem.Size = New System.Drawing.Size(151, 22) Me.SettingsToolStripMenuItem.Text = "Settings" ' 'ToolStripDrDnBtInfo @@ -801,6 +803,15 @@ Partial Class MainForm Me.ShowInFolderToolStripMenuItem.Size = New System.Drawing.Size(173, 22) Me.ShowInFolderToolStripMenuItem.Text = "Show in Folder" ' + 'cbActVmod + ' + Me.cbActVmod.Location = New System.Drawing.Point(6, 41) + Me.cbActVmod.Name = "cbActVmod" + Me.cbActVmod.Size = New System.Drawing.Size(161, 63) + Me.cbActVmod.TabIndex = 18 + Me.cbActVmod.Text = "Output values in vmod at beginning and end of simulation interval (EXPERT!)" + Me.cbActVmod.UseVisualStyleBackColor = True + ' 'MainForm ' Me.AcceptButton = Me.btStartV3 @@ -930,5 +941,6 @@ Partial Class MainForm Friend WithEvents ShowInFolderMenuItem As System.Windows.Forms.ToolStripMenuItem Friend WithEvents GroupBox3 As System.Windows.Forms.GroupBox Friend WithEvents cbValidateRunData As System.Windows.Forms.CheckBox + Friend WithEvents cbActVmod As System.Windows.Forms.CheckBox End Class diff --git a/VECTO/GUI/MainForm.vb b/VECTO/GUI/MainForm.vb index 9b9b7d3b381dddfe6db2d36fb579d4b1bfd4cf76..57879211bbf75bc316787681377b3c3fd0406db0 100644 --- a/VECTO/GUI/MainForm.vb +++ b/VECTO/GUI/MainForm.vb @@ -341,7 +341,7 @@ Imports TUGraz.VectoCore.OutputData.FileIO GearboxForm.BringToFront() End If Try - GearboxForm.OpenGbx(file) + GearboxForm.OpenGbx(file, VehicleCategory.RigidTruck) Catch ex As Exception MsgBox("Failed to open Gearbox File: " + ex.Message) End Try @@ -970,6 +970,7 @@ Imports TUGraz.VectoCore.OutputData.FileIO runsFactory.WriteModalResults = Cfg.ModOut runsFactory.ModalResults1Hz = Cfg.Mod1Hz runsFactory.Validate = cbValidateRunData.Checked + runsFactory.ActualModalData = cbActVmod.Checked For Each runId As Integer In jobContainer.AddRuns(runsFactory) fileWriters.Add(runId, fileWriter) diff --git a/VECTO/GUI/VectoJobForm.vb b/VECTO/GUI/VectoJobForm.vb index ba1a4fc34c90668aba3c5713d010bb9b89658b17..0863126db6e867e1dd55e8b86071fec98d863f33 100644 --- a/VECTO/GUI/VectoJobForm.vb +++ b/VECTO/GUI/VectoJobForm.vb @@ -296,8 +296,20 @@ Public Class VectoJobForm If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal GearboxForm.BringToFront() End If + Dim vehicleType As VehicleCategory Try - If Not Trim(f) = "" Then GearboxForm.OpenGbx(f) + If Not Trim(f) = "" Then + Dim vehInput As IVehicleDeclarationInputData = + CType(JSONInputDataFactory.ReadComponentData(FileRepl(TbVEH.Text, GetPath(VectoFile))), + IEngineeringInputDataProvider).VehicleInputData + vehicleType = vehInput.VehicleCategory + End If + + Catch ex As Exception + vehicleType = VehicleCategory.RigidTruck + End Try + Try + If Not Trim(f) = "" Then GearboxForm.OpenGbx(f, vehicleType) Catch ex As Exception MsgBox("Failed to open Gearbox File: " + ex.Message) End Try @@ -680,7 +692,8 @@ Public Class VectoJobForm CbEngOnly.Checked = False - RdOff.Checked = True + 'RdOff.Checked = True + RdOverspeed.Checked = True CbLookAhead.Checked = True 'TbAlookahead.Text = "-0.5" TbOverspeed.Text = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed.AsKmph.ToGUIFormat() @@ -1299,7 +1312,7 @@ lbDlog: True) Catch End Try - If s0 Is Nothing Then + If Not s0.Found Then HDVclass = "-" Else HDVclass = s0.VehicleClass.GetClassNumber() @@ -1314,7 +1327,7 @@ lbDlog: End If - PicVehicle.Image = ConvPicPath(If(s0 Is Nothing, -1, HDVclass.ToInt()), False) _ + PicVehicle.Image = ConvPicPath(If(Not s0.Found, -1, HDVclass.ToInt()), False) _ 'Image.FromFile(cDeclaration.ConvPicPath(HDVclass, False)) TbHVCclass.Text = String.Format("HDV Class {0}", HDVclass) diff --git a/VECTO/GUI/VehicleAxleDialog.Designer.vb b/VECTO/GUI/VehicleAxleDialog.Designer.vb index e52ce1856dbf713453287ca26dc0225ae40e70c2..fccfd299c47df79b5bd4a178c574ad533e06a968 100644 --- a/VECTO/GUI/VehicleAxleDialog.Designer.vb +++ b/VECTO/GUI/VehicleAxleDialog.Designer.vb @@ -58,6 +58,7 @@ Partial Class VehicleAxleDialog Me.CbWheels = New System.Windows.Forms.ComboBox() Me.cbAxleType = New System.Windows.Forms.ComboBox() Me.Label11 = New System.Windows.Forms.Label() + Me.Label12 = New System.Windows.Forms.Label() Me.TableLayoutPanel1.SuspendLayout() Me.PnAxle.SuspendLayout() Me.SuspendLayout() @@ -149,7 +150,7 @@ Partial Class VehicleAxleDialog 'Label5 ' Me.Label5.AutoSize = True - Me.Label5.Location = New System.Drawing.Point(67, 119) + Me.Label5.Location = New System.Drawing.Point(67, 120) Me.Label5.Name = "Label5" Me.Label5.Size = New System.Drawing.Size(39, 13) Me.Label5.TabIndex = 1 @@ -158,7 +159,7 @@ Partial Class VehicleAxleDialog 'Label6 ' Me.Label6.AutoSize = True - Me.Label6.Location = New System.Drawing.Point(202, 91) + Me.Label6.Location = New System.Drawing.Point(202, 120) Me.Label6.Name = "Label6" Me.Label6.Size = New System.Drawing.Size(21, 13) Me.Label6.TabIndex = 1 @@ -273,6 +274,15 @@ Partial Class VehicleAxleDialog Me.Label11.TabIndex = 9 Me.Label11.Text = "Configuration" ' + 'Label12 + ' + Me.Label12.AutoSize = True + Me.Label12.Location = New System.Drawing.Point(202, 94) + Me.Label12.Name = "Label12" + Me.Label12.Size = New System.Drawing.Size(16, 13) + Me.Label12.TabIndex = 10 + Me.Label12.Text = "[-]" + ' 'VehicleAxleDialog ' Me.AcceptButton = Me.OK_Button @@ -280,6 +290,7 @@ Partial Class VehicleAxleDialog Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.CancelButton = Me.Cancel_Button Me.ClientSize = New System.Drawing.Size(467, 202) + Me.Controls.Add(Me.Label12) Me.Controls.Add(Me.Label11) Me.Controls.Add(Me.cbAxleType) Me.Controls.Add(Me.CbWheels) @@ -332,5 +343,6 @@ Partial Class VehicleAxleDialog Friend WithEvents CbWheels As ComboBox Friend WithEvents cbAxleType As System.Windows.Forms.ComboBox Friend WithEvents Label11 As System.Windows.Forms.Label + Friend WithEvents Label12 As System.Windows.Forms.Label End Class diff --git a/VECTO/GUI/VehicleForm.Designer.vb b/VECTO/GUI/VehicleForm.Designer.vb index 434ffb244dd4b7cf63ca4b8d08389bc58cd12eb2..f44fafcf25beb17007d3366f602452a28c7b0d9a 100644 --- a/VECTO/GUI/VehicleForm.Designer.vb +++ b/VECTO/GUI/VehicleForm.Designer.vb @@ -85,6 +85,7 @@ Partial Class VehicleForm Me.ColumnHeader1 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ColumnHeader3 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ColumnHeader4 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) + Me.ColumnHeader10 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) Me.ButAxlAdd = New System.Windows.Forms.Button() Me.PnWheelDiam = New System.Windows.Forms.Panel() Me.CbAxleConfig = New System.Windows.Forms.ComboBox() @@ -95,9 +96,6 @@ Partial Class VehicleForm Me.StatusStrip1 = New System.Windows.Forms.StatusStrip() Me.LbStatus = New System.Windows.Forms.ToolStripStatusLabel() Me.TbHDVclass = New System.Windows.Forms.TextBox() - Me.Label11 = New System.Windows.Forms.Label() - Me.TbLoadingMax = New System.Windows.Forms.TextBox() - Me.Label22 = New System.Windows.Forms.Label() Me.GroupBox1 = New System.Windows.Forms.GroupBox() Me.PnLoad = New System.Windows.Forms.Panel() Me.GrAirRes = New System.Windows.Forms.GroupBox() @@ -131,6 +129,11 @@ Partial Class VehicleForm Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components) Me.TabControl1 = New System.Windows.Forms.TabControl() Me.TabPage1 = New System.Windows.Forms.TabPage() + Me.GroupBox4 = New System.Windows.Forms.GroupBox() + Me.Panel1 = New System.Windows.Forms.Panel() + Me.tbVehIdlingSpeed = New System.Windows.Forms.TextBox() + Me.Label18 = New System.Windows.Forms.Label() + Me.Label19 = New System.Windows.Forms.Label() Me.TabPage2 = New System.Windows.Forms.TabPage() Me.TabPage3 = New System.Windows.Forms.TabPage() Me.lvTorqueLimits = New System.Windows.Forms.ListView() @@ -139,12 +142,7 @@ Partial Class VehicleForm Me.Label17 = New System.Windows.Forms.Label() Me.btDelMaxTorqueEntry = New System.Windows.Forms.Button() Me.btAddMaxTorqueEntry = New System.Windows.Forms.Button() - Me.ColumnHeader10 = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) - Me.GroupBox4 = New System.Windows.Forms.GroupBox() - Me.Panel1 = New System.Windows.Forms.Panel() - Me.tbVehIdlingSpeed = New System.Windows.Forms.TextBox() - Me.Label18 = New System.Windows.Forms.Label() - Me.Label19 = New System.Windows.Forms.Label() + Me.cbLegislativeClass = New System.Windows.Forms.ComboBox() Me.GroupBox6.SuspendLayout() Me.ToolStrip1.SuspendLayout() Me.GroupBox7.SuspendLayout() @@ -166,10 +164,10 @@ Partial Class VehicleForm CType(Me.PicVehicle, System.ComponentModel.ISupportInitialize).BeginInit() Me.TabControl1.SuspendLayout() Me.TabPage1.SuspendLayout() - Me.TabPage2.SuspendLayout() - Me.TabPage3.SuspendLayout() Me.GroupBox4.SuspendLayout() Me.Panel1.SuspendLayout() + Me.TabPage2.SuspendLayout() + Me.TabPage3.SuspendLayout() Me.SuspendLayout() ' 'Label1 @@ -239,7 +237,7 @@ Partial Class VehicleForm 'ButOK ' Me.ButOK.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.ButOK.Location = New System.Drawing.Point(431, 557) + Me.ButOK.Location = New System.Drawing.Point(431, 532) Me.ButOK.Name = "ButOK" Me.ButOK.Size = New System.Drawing.Size(75, 23) Me.ButOK.TabIndex = 5 @@ -250,7 +248,7 @@ Partial Class VehicleForm ' Me.ButCancel.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) Me.ButCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel - Me.ButCancel.Location = New System.Drawing.Point(512, 557) + Me.ButCancel.Location = New System.Drawing.Point(512, 532) Me.ButCancel.Name = "ButCancel" Me.ButCancel.Size = New System.Drawing.Size(75, 23) Me.ButCancel.TabIndex = 6 @@ -298,7 +296,7 @@ Partial Class VehicleForm ' Me.TbCdFile.Anchor = System.Windows.Forms.AnchorStyles.None Me.TbCdFile.Enabled = False - Me.TbCdFile.Location = New System.Drawing.Point(6, 68) + Me.TbCdFile.Location = New System.Drawing.Point(9, 65) Me.TbCdFile.Name = "TbCdFile" Me.TbCdFile.Size = New System.Drawing.Size(210, 20) Me.TbCdFile.TabIndex = 1 @@ -308,7 +306,7 @@ Partial Class VehicleForm Me.BtCdFileBrowse.Anchor = System.Windows.Forms.AnchorStyles.None Me.BtCdFileBrowse.Enabled = False Me.BtCdFileBrowse.Image = Global.TUGraz.VECTO.My.Resources.Resources.Open_icon - Me.BtCdFileBrowse.Location = New System.Drawing.Point(222, 65) + Me.BtCdFileBrowse.Location = New System.Drawing.Point(225, 62) Me.BtCdFileBrowse.Name = "BtCdFileBrowse" Me.BtCdFileBrowse.Size = New System.Drawing.Size(24, 24) Me.BtCdFileBrowse.TabIndex = 2 @@ -323,7 +321,7 @@ Partial Class VehicleForm Me.GroupBox6.Controls.Add(Me.TbCdFile) Me.GroupBox6.Location = New System.Drawing.Point(290, 70) Me.GroupBox6.Name = "GroupBox6" - Me.GroupBox6.Size = New System.Drawing.Size(281, 109) + Me.GroupBox6.Size = New System.Drawing.Size(281, 96) Me.GroupBox6.TabIndex = 5 Me.GroupBox6.TabStop = False Me.GroupBox6.Text = "Cross Wind Correction" @@ -333,7 +331,7 @@ Partial Class VehicleForm Me.BtCdFileOpen.Anchor = System.Windows.Forms.AnchorStyles.None Me.BtCdFileOpen.Enabled = False Me.BtCdFileOpen.Image = Global.TUGraz.VECTO.My.Resources.Resources.application_export_icon_small - Me.BtCdFileOpen.Location = New System.Drawing.Point(246, 65) + Me.BtCdFileOpen.Location = New System.Drawing.Point(249, 62) Me.BtCdFileOpen.Name = "BtCdFileOpen" Me.BtCdFileOpen.Size = New System.Drawing.Size(24, 24) Me.BtCdFileOpen.TabIndex = 3 @@ -343,7 +341,7 @@ Partial Class VehicleForm 'LbCdMode ' Me.LbCdMode.AutoSize = True - Me.LbCdMode.Location = New System.Drawing.Point(6, 48) + Me.LbCdMode.Location = New System.Drawing.Point(6, 47) Me.LbCdMode.Name = "LbCdMode" Me.LbCdMode.Size = New System.Drawing.Size(59, 13) Me.LbCdMode.TabIndex = 28 @@ -548,7 +546,7 @@ Partial Class VehicleForm Me.GroupBox8.Controls.Add(Me.ButAxlRem) Me.GroupBox8.Controls.Add(Me.LvRRC) Me.GroupBox8.Controls.Add(Me.ButAxlAdd) - Me.GroupBox8.Location = New System.Drawing.Point(7, 185) + Me.GroupBox8.Location = New System.Drawing.Point(6, 172) Me.GroupBox8.Name = "GroupBox8" Me.GroupBox8.Size = New System.Drawing.Size(564, 151) Me.GroupBox8.TabIndex = 2 @@ -624,6 +622,11 @@ Partial Class VehicleForm ' Me.ColumnHeader4.Text = "Inertia" ' + 'ColumnHeader10 + ' + Me.ColumnHeader10.Text = "Axle Type" + Me.ColumnHeader10.Width = 130 + ' 'ButAxlAdd ' Me.ButAxlAdd.Image = Global.TUGraz.VECTO.My.Resources.Resources.plus_circle_icon @@ -693,7 +696,7 @@ Partial Class VehicleForm 'StatusStrip1 ' Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.LbStatus}) - Me.StatusStrip1.Location = New System.Drawing.Point(0, 583) + Me.StatusStrip1.Location = New System.Drawing.Point(0, 558) Me.StatusStrip1.Name = "StatusStrip1" Me.StatusStrip1.Size = New System.Drawing.Size(599, 22) Me.StatusStrip1.SizingGrip = False @@ -716,33 +719,6 @@ Partial Class VehicleForm Me.TbHDVclass.TabStop = False Me.TbHDVclass.TextAlign = System.Windows.Forms.HorizontalAlignment.Center ' - 'Label11 - ' - Me.Label11.AutoSize = True - Me.Label11.Location = New System.Drawing.Point(89, 57) - Me.Label11.Name = "Label11" - Me.Label11.Size = New System.Drawing.Size(71, 13) - Me.Label11.TabIndex = 31 - Me.Label11.Text = "Max. Loading" - ' - 'TbLoadingMax - ' - Me.TbLoadingMax.Location = New System.Drawing.Point(166, 54) - Me.TbLoadingMax.Name = "TbLoadingMax" - Me.TbLoadingMax.ReadOnly = True - Me.TbLoadingMax.Size = New System.Drawing.Size(57, 20) - Me.TbLoadingMax.TabIndex = 2 - Me.TbLoadingMax.TabStop = False - ' - 'Label22 - ' - Me.Label22.AutoSize = True - Me.Label22.Location = New System.Drawing.Point(225, 57) - Me.Label22.Name = "Label22" - Me.Label22.Size = New System.Drawing.Size(25, 13) - Me.Label22.TabIndex = 24 - Me.Label22.Text = "[kg]" - ' 'GroupBox1 ' Me.GroupBox1.Controls.Add(Me.PnLoad) @@ -751,7 +727,7 @@ Partial Class VehicleForm Me.GroupBox1.Controls.Add(Me.Label14) Me.GroupBox1.Location = New System.Drawing.Point(6, 6) Me.GroupBox1.Name = "GroupBox1" - Me.GroupBox1.Size = New System.Drawing.Size(278, 120) + Me.GroupBox1.Size = New System.Drawing.Size(278, 104) Me.GroupBox1.TabIndex = 0 Me.GroupBox1.TabStop = False Me.GroupBox1.Text = "Weight / Loading" @@ -762,11 +738,8 @@ Partial Class VehicleForm Me.PnLoad.Controls.Add(Me.Label31) Me.PnLoad.Controls.Add(Me.TbLoad) Me.PnLoad.Controls.Add(Me.TbMassExtra) - Me.PnLoad.Controls.Add(Me.TbLoadingMax) Me.PnLoad.Controls.Add(Me.Label50) Me.PnLoad.Controls.Add(Me.Label46) - Me.PnLoad.Controls.Add(Me.Label22) - Me.PnLoad.Controls.Add(Me.Label11) Me.PnLoad.Location = New System.Drawing.Point(6, 43) Me.PnLoad.Name = "PnLoad" Me.PnLoad.Size = New System.Drawing.Size(256, 75) @@ -1048,7 +1021,7 @@ Partial Class VehicleForm Me.TabControl1.Location = New System.Drawing.Point(6, 173) Me.TabControl1.Name = "TabControl1" Me.TabControl1.SelectedIndex = 0 - Me.TabControl1.Size = New System.Drawing.Size(587, 376) + Me.TabControl1.Size = New System.Drawing.Size(587, 355) Me.TabControl1.TabIndex = 40 ' 'TabPage1 @@ -1062,11 +1035,57 @@ Partial Class VehicleForm Me.TabPage1.Location = New System.Drawing.Point(4, 22) Me.TabPage1.Name = "TabPage1" Me.TabPage1.Padding = New System.Windows.Forms.Padding(3) - Me.TabPage1.Size = New System.Drawing.Size(579, 350) + Me.TabPage1.Size = New System.Drawing.Size(579, 329) Me.TabPage1.TabIndex = 0 Me.TabPage1.Text = "General" Me.TabPage1.UseVisualStyleBackColor = True ' + 'GroupBox4 + ' + Me.GroupBox4.Controls.Add(Me.Panel1) + Me.GroupBox4.Location = New System.Drawing.Point(6, 116) + Me.GroupBox4.Name = "GroupBox4" + Me.GroupBox4.Size = New System.Drawing.Size(278, 50) + Me.GroupBox4.TabIndex = 2 + Me.GroupBox4.TabStop = False + Me.GroupBox4.Text = "Vehicle Idling Speed" + ' + 'Panel1 + ' + Me.Panel1.Controls.Add(Me.tbVehIdlingSpeed) + Me.Panel1.Controls.Add(Me.Label18) + Me.Panel1.Controls.Add(Me.Label19) + Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill + Me.Panel1.Location = New System.Drawing.Point(3, 16) + Me.Panel1.Name = "Panel1" + Me.Panel1.Size = New System.Drawing.Size(272, 31) + Me.Panel1.TabIndex = 0 + ' + 'tbVehIdlingSpeed + ' + Me.tbVehIdlingSpeed.Location = New System.Drawing.Point(169, 3) + Me.tbVehIdlingSpeed.Name = "tbVehIdlingSpeed" + Me.tbVehIdlingSpeed.Size = New System.Drawing.Size(57, 20) + Me.tbVehIdlingSpeed.TabIndex = 0 + ' + 'Label18 + ' + Me.Label18.AutoSize = True + Me.Label18.Location = New System.Drawing.Point(229, 6) + Me.Label18.Name = "Label18" + Me.Label18.Size = New System.Drawing.Size(30, 13) + Me.Label18.TabIndex = 24 + Me.Label18.Text = "[rpm]" + ' + 'Label19 + ' + Me.Label19.AutoSize = True + Me.Label19.Location = New System.Drawing.Point(69, 6) + Me.Label19.Name = "Label19" + Me.Label19.Size = New System.Drawing.Size(94, 13) + Me.Label19.TabIndex = 8 + Me.Label19.Text = "Engine Idle Speed" + ' 'TabPage2 ' Me.TabPage2.Controls.Add(Me.gbPTO) @@ -1075,7 +1094,7 @@ Partial Class VehicleForm Me.TabPage2.Location = New System.Drawing.Point(4, 22) Me.TabPage2.Name = "TabPage2" Me.TabPage2.Padding = New System.Windows.Forms.Padding(3) - Me.TabPage2.Size = New System.Drawing.Size(579, 350) + Me.TabPage2.Size = New System.Drawing.Size(579, 329) Me.TabPage2.TabIndex = 1 Me.TabPage2.Text = "Powertrain" Me.TabPage2.UseVisualStyleBackColor = True @@ -1088,7 +1107,7 @@ Partial Class VehicleForm Me.TabPage3.Controls.Add(Me.btAddMaxTorqueEntry) Me.TabPage3.Location = New System.Drawing.Point(4, 22) Me.TabPage3.Name = "TabPage3" - Me.TabPage3.Size = New System.Drawing.Size(579, 350) + Me.TabPage3.Size = New System.Drawing.Size(579, 329) Me.TabPage3.TabIndex = 2 Me.TabPage3.Text = "Torque Limits" Me.TabPage3.UseVisualStyleBackColor = True @@ -1147,56 +1166,14 @@ Partial Class VehicleForm Me.btAddMaxTorqueEntry.TabIndex = 4 Me.btAddMaxTorqueEntry.UseVisualStyleBackColor = True ' - 'ColumnHeader10 - ' - Me.ColumnHeader10.Text = "Axle Type" - Me.ColumnHeader10.Width = 130 - ' - 'GroupBox4 - ' - Me.GroupBox4.Controls.Add(Me.Panel1) - Me.GroupBox4.Location = New System.Drawing.Point(6, 129) - Me.GroupBox4.Name = "GroupBox4" - Me.GroupBox4.Size = New System.Drawing.Size(278, 50) - Me.GroupBox4.TabIndex = 2 - Me.GroupBox4.TabStop = False - Me.GroupBox4.Text = "Vehicle Idling Speed" - ' - 'Panel1 + 'cbLegislativeClass ' - Me.Panel1.Controls.Add(Me.tbVehIdlingSpeed) - Me.Panel1.Controls.Add(Me.Label18) - Me.Panel1.Controls.Add(Me.Label19) - Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill - Me.Panel1.Location = New System.Drawing.Point(3, 16) - Me.Panel1.Name = "Panel1" - Me.Panel1.Size = New System.Drawing.Size(272, 31) - Me.Panel1.TabIndex = 0 - ' - 'tbVehIdlingSpeed - ' - Me.tbVehIdlingSpeed.Location = New System.Drawing.Point(169, 3) - Me.tbVehIdlingSpeed.Name = "tbVehIdlingSpeed" - Me.tbVehIdlingSpeed.Size = New System.Drawing.Size(57, 20) - Me.tbVehIdlingSpeed.TabIndex = 0 - ' - 'Label18 - ' - Me.Label18.AutoSize = True - Me.Label18.Location = New System.Drawing.Point(229, 6) - Me.Label18.Name = "Label18" - Me.Label18.Size = New System.Drawing.Size(30, 13) - Me.Label18.TabIndex = 24 - Me.Label18.Text = "[rpm]" - ' - 'Label19 - ' - Me.Label19.AutoSize = True - Me.Label19.Location = New System.Drawing.Point(69, 6) - Me.Label19.Name = "Label19" - Me.Label19.Size = New System.Drawing.Size(94, 13) - Me.Label19.TabIndex = 8 - Me.Label19.Text = "Engine Idle Speed" + Me.cbLegislativeClass.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList + Me.cbLegislativeClass.FormattingEnabled = True + Me.cbLegislativeClass.Location = New System.Drawing.Point(219, 106) + Me.cbLegislativeClass.Name = "cbLegislativeClass" + Me.cbLegislativeClass.Size = New System.Drawing.Size(52, 21) + Me.cbLegislativeClass.TabIndex = 41 ' 'VehicleForm ' @@ -1204,7 +1181,8 @@ Partial Class VehicleForm Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.CancelButton = Me.ButCancel - Me.ClientSize = New System.Drawing.Size(599, 605) + Me.ClientSize = New System.Drawing.Size(599, 580) + Me.Controls.Add(Me.cbLegislativeClass) Me.Controls.Add(Me.TabControl1) Me.Controls.Add(Me.ButCancel) Me.Controls.Add(Me.ButOK) @@ -1257,12 +1235,12 @@ Partial Class VehicleForm CType(Me.PicVehicle, System.ComponentModel.ISupportInitialize).EndInit() Me.TabControl1.ResumeLayout(False) Me.TabPage1.ResumeLayout(False) - Me.TabPage2.ResumeLayout(False) - Me.TabPage3.ResumeLayout(False) - Me.TabPage3.PerformLayout() Me.GroupBox4.ResumeLayout(False) Me.Panel1.ResumeLayout(False) Me.Panel1.PerformLayout() + Me.TabPage2.ResumeLayout(False) + Me.TabPage3.ResumeLayout(False) + Me.TabPage3.PerformLayout() Me.ResumeLayout(False) Me.PerformLayout() @@ -1316,9 +1294,6 @@ Partial Class VehicleForm Friend WithEvents LbStatus As System.Windows.Forms.ToolStripStatusLabel Friend WithEvents CbAxleConfig As System.Windows.Forms.ComboBox Friend WithEvents TbHDVclass As System.Windows.Forms.TextBox - Friend WithEvents Label11 As System.Windows.Forms.Label - Friend WithEvents TbLoadingMax As System.Windows.Forms.TextBox - Friend WithEvents Label22 As System.Windows.Forms.Label Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox Friend WithEvents GrAirRes As System.Windows.Forms.GroupBox Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox @@ -1378,4 +1353,5 @@ Partial Class VehicleForm Friend WithEvents tbVehIdlingSpeed As System.Windows.Forms.TextBox Friend WithEvents Label18 As System.Windows.Forms.Label Friend WithEvents Label19 As System.Windows.Forms.Label + Friend WithEvents cbLegislativeClass As System.Windows.Forms.ComboBox End Class diff --git a/VECTO/GUI/VehicleForm.vb b/VECTO/GUI/VehicleForm.vb index d008a52fabb3359b17714b71a27ea7846d0aa628..25eea0c99f89e21704d0edf89ee250b679a84b78 100644 --- a/VECTO/GUI/VehicleForm.vb +++ b/VECTO/GUI/VehicleForm.vb @@ -59,7 +59,6 @@ Public Class VehicleForm 'Initialise form Private Sub VehicleFormLoad(sender As Object, e As EventArgs) Handles MyBase.Load - TbLoadingMax.Text = "-" PnLoad.Enabled = Not Cfg.DeclMode ButAxlAdd.Enabled = Not Cfg.DeclMode ButAxlRem.Enabled = Not Cfg.DeclMode @@ -103,6 +102,11 @@ Public Class VehicleForm cbPTOType.DisplayMember = "Label" cbPTOType.DataSource = DeclarationData.PTOTransmission.GetTechnologies.Select( Function(technology) New With {Key .Value = technology, .Label = technology}).ToList() + + cbLegislativeClass.ValueMember = "Value" + cbLegislativeClass.DisplayMember = "Label" + cbLegislativeClass.DataSource = [Enum].GetValues(GetType(LegislativeClass)) _ + .Cast(Of LegislativeClass).Select(Function(x) New With {Key .Value = x, .Label = x.GetLabel()}).Tolist() 'Items.AddRange(PtoTypeStrings.Values.Cast(Of Object).ToArray()) _changed = False @@ -128,13 +132,13 @@ Public Class VehicleForm Catch ' no segment found - ignore End Try - If Not s0 Is Nothing Then + If s0.Found Then _hdVclass = s0.VehicleClass.GetClassNumber() End If TbHDVclass.Text = _hdVclass - PicVehicle.Image = ConvPicPath(If(s0 Is Nothing, -1, _hdVclass.ToInt()), False) + PicVehicle.Image = ConvPicPath(If(Not s0.Found, -1, _hdVclass.ToInt()), False) End Sub @@ -156,7 +160,7 @@ Public Class VehicleForm Catch ' no segment found - ignore End Try - If Not s0 Is Nothing Then + If s0.found Then _hdVclass = s0.VehicleClass.GetClassNumber() Dim axleCount As Integer = s0.Missions(0).AxleWeightDistribution.Count() Dim i0 As Integer = LvRRC.Items.Count @@ -367,6 +371,7 @@ Public Class VehicleForm TbCdFile.Text = If(airdrag.CrosswindCorrectionMap Is Nothing, "", GetRelativePath(airdrag.CrosswindCorrectionMap.Source, basePath)) + cbLegislativeClass.SelectedValue = vehicle.LegislativeClass CbRtType.SelectedValue = retarder.Type TbRtRatio.Text = retarder.Ratio.ToGUIFormat() TbRtPath.Text = If(retarder.LossMap Is Nothing, "", GetRelativePath(retarder.LossMap.Source, basePath)) @@ -451,7 +456,7 @@ Public Class VehicleForm veh.Loading = TbLoad.Text.ToDouble(0) veh.CdA0 = If(String.IsNullOrWhiteSpace(TBcdA.Text), Double.NaN, TBcdA.Text.ToDouble(0)) - + veh.legClass = CType(cbLegislativeClass.SelectedValue, LegislativeClass) veh.DynamicTyreRadius = TBrdyn.Text.ToDouble(0) veh.CrossWindCorrectionMode = CType(CbCdMode.SelectedValue, CrossWindCorrectionMode) veh.CrossWindCorrectionFile.Init(GetPath(file), TbCdFile.Text) @@ -631,7 +636,6 @@ Public Class VehicleForm End Function Private Sub TBmass_TextChanged(sender As Object, e As EventArgs) Handles TbMass.TextChanged - SetMaxLoad() Change() End Sub @@ -649,12 +653,10 @@ Public Class VehicleForm End Sub Private Sub TbMassTrailer_TextChanged(sender As Object, e As EventArgs) Handles TbMassExtra.TextChanged - SetMaxLoad() Change() End Sub Private Sub TbMassMax_TextChanged(sender As Object, e As EventArgs) Handles TbMassMass.TextChanged - SetMaxLoad() Change() SetHdVclass() DeclInit() @@ -669,17 +671,6 @@ Public Class VehicleForm #End Region - 'Update maximum load when truck/trailer mass was changed - Private Sub SetMaxLoad() - If Not Cfg.DeclMode Then - If IsNumeric(TbMass.Text) And IsNumeric(TbMassExtra.Text) And IsNumeric(TbMassMass.Text) Then - TbLoadingMax.Text = CStr(CSng(TbMassMass.Text) * 1000 - CSng(TbMass.Text) - CSng(TbMassExtra.Text)) - Else - TbLoadingMax.Text = "" - End If - End If - End Sub - #Region "Axle Configuration" Private Sub ButAxlAdd_Click(sender As Object, e As EventArgs) Handles ButAxlAdd.Click diff --git a/VECTO/Input Files/Gearbox.vb b/VECTO/Input Files/Gearbox.vb index 86298b9f48af9c15df57585e367e3da18b6b32f8..e2b8f1ba39c5d71867055e137be4d48cd6049ad7 100644 --- a/VECTO/Input Files/Gearbox.vb +++ b/VECTO/Input Files/Gearbox.vb @@ -22,6 +22,7 @@ Imports TUGraz.VectoCore.InputData.FileIO.JSON Imports TUGraz.VectoCore.InputData.Impl Imports TUGraz.VectoCore.InputData.Reader Imports TUGraz.VectoCore.InputData.Reader.DataObjectAdapter +Imports TUGraz.VectoCore.Models.Declaration Imports TUGraz.VectoCore.Models.SimulationComponent.Data Imports TUGraz.VectoCore.Models.SimulationComponent.Data.Engine Imports TUGraz.VectoCore.Utils @@ -204,7 +205,13 @@ Public Class Gearbox IEngineeringInputDataProvider) 'Dim vehicle As IVehicleEngineeringInputData = inputData.VehicleInputData Dim engine As CombustionEngineData + Dim vehiclecategory As VehicleCategory Dim rdyn As Meter = 0.5.SI(Of Meter)() + Try + vehiclecategory = inputData.VehicleInputData.VehicleCategory + Catch ex As Exception + vehiclecategory = vehiclecategory.RigidTruck + End Try If mode = ExecutionMode.Declaration Then Dim doa As DeclarationDataAdapter = New DeclarationDataAdapter() @@ -214,9 +221,9 @@ Public Class Gearbox Catch engine = GetDefaultEngine(gearbox.Gears) End Try - + axlegearData = doa.CreateAxleGearData(gearbox, False) - gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, False) + gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, vehiclecategory, False) Else Dim doa As EngineeringDataAdapter = New EngineeringDataAdapter() Try @@ -226,7 +233,7 @@ Public Class Gearbox End Try axlegearData = doa.CreateAxleGearData(gearbox, True) - gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, True) + gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, vehiclecategory, True) End If Dim result As IList(Of ValidationResult) = diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb index cf4a0695ef2fe9b00a4f04d00f08bdee49387ab1..107f9dc7005a26797e1fe2c18aa4dda6632824ff 100644 --- a/VECTO/Input Files/Vehicle.vb +++ b/VECTO/Input Files/Vehicle.vb @@ -63,6 +63,7 @@ Public Class Vehicle Public ReadOnly PtoCycle As SubPath Public torqueLimitsList As List(Of ITorqueLimitInputData) Public VehicleidlingSpeed As PerSecond + Public legClass As LegislativeClass Public Sub New() @@ -323,9 +324,9 @@ Public Class Vehicle End Get End Property - Public ReadOnly Property LegislativeClass As String Implements IVehicleDeclarationInputData.LegislativeClass + Public ReadOnly Property LegislativeClass As LegislativeClass Implements IVehicleEngineeringInputData.LegislativeClass Get - Return "N3" + Return legClass End Get End Property diff --git a/VECTO/OutputData/JSONFileWriter.vb b/VECTO/OutputData/JSONFileWriter.vb index a5f76f078f9c783e6f8f7559e35e810e18bafb44..814a599beefeba5f3d7e0cb03220b0910f285bc7 100644 --- a/VECTO/OutputData/JSONFileWriter.vb +++ b/VECTO/OutputData/JSONFileWriter.vb @@ -202,6 +202,7 @@ Public Class JSONFileWriter Dim body As Dictionary(Of String, Object) = New Dictionary(Of String, Object) From { {"SavedInDeclMode", Cfg.DeclMode}, {"VehCat", vehicle.VehicleCategory.ToString()}, + {"LegislativeClass", vehicle.LegislativeClass.ToString()}, {"CurbWeight", vehicle.CurbMassChassis.Value()}, {"CurbWeightExtra", vehicle.CurbMassExtra.Value()}, {"Loading", vehicle.Loading.Value()}, diff --git a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs index 574c9a579db9b7aab3fd3745091b03e61c27f421..75060d28e6ee1a754cd0940625c1e97951e67dd2 100644 --- a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs +++ b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs @@ -29,400 +29,400 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCommon.InputData -{ - public interface IDeclarationJobInputData - { - bool SavedInDeclarationMode { get; } - - IVehicleDeclarationInputData Vehicle { get; } - - string JobName { get; } - } - - public interface IComponentInputData - { - DataSourceType SourceType { get; } - - string Source { get; } - - bool SavedInDeclarationMode { get; } - - string Manufacturer { get; } - - string Model { get; } - - string Date { get; } - - CertificationMethod CertificationMethod { get; } - - string CertificationNumber { get; } - - string DigestValue { get; } - } - - public interface IVehicleDeclarationInputData : IComponentInputData - { - string VIN { get; } - - string LegislativeClass { get; } - - /// <summary> - /// P036 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - VehicleCategory VehicleCategory { get; } - - /// <summary> - /// P037 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - AxleConfiguration AxleConfiguration { get; } - - /// <summary> - /// P038 Curb Weight Vehicle - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Kilogram CurbMassChassis { get; } - - /// <summary> - /// P041 Max. vehicle weight - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Kilogram GrossVehicleMassRating { get; } - - ///// <summary> - ///// P117 Powered axle tyres/rims - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //string Rim { get; } // deprecated - - IList<ITorqueLimitInputData> TorqueLimits { get; } - - /// <summary> - /// parameters for every axle - /// P044, P045, P046, P047, P048, P108 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - IList<IAxleDeclarationInputData> Axles { get; } - - string ManufacturerAddress { get; } - - PerSecond EngineIdleSpeed { get; } - } - - public interface IAirdragDeclarationInputData : IComponentInputData - { - /// <summary> - /// P146, P147 DragCoefficient * Cross Section Area - Rigid - /// cf. VECTO Input Parameters.xlsx - /// </summary> - SquareMeter AirDragArea { get; } // without trailer - } - - public interface IRetarderInputData : IComponentInputData - { - /// <summary> - /// P052 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - RetarderType Type { get; } - - /// <summary> - /// P053 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double Ratio { get; } - - /// <summary> - /// P054 - /// P057, P058 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData LossMap { get; } - } - - public interface IAngledriveInputData : IComponentInputData - { - /// <summary> - /// P180 - /// </summary> - AngledriveType Type { get; } - - /// <summary> - /// P176 - /// </summary> - double Ratio { get; } - - /// <summary> - /// P173, P174, P175 - /// </summary> - TableData LossMap { get; } - - /// <summary> - /// P177 - /// </summary> - double Efficiency { get; } - } - - public interface IAxleDeclarationInputData - { - /// <summary> - /// P108 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - string Wheels { get; } - - /// <summary> - /// P045 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - bool TwinTyres { get; } - - AxleType AxleType { get; } - - /// <summary> - /// P046 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double RollResistanceCoefficient { get; } - - /// <summary> - /// P047 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Newton TyreTestLoad { get; } - } - - public interface IGearboxDeclarationInputData : IComponentInputData - { - /// <summary> - /// P076 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - GearboxType Type { get; } - - /// <summary> - /// P078, P079, P077, P082, P145 (for every gear) - /// cf. VECTO Input Parameters.xlsx - /// </summary> - IList<ITransmissionInputData> Gears { get; } - - /// <summary> - /// P090, P091, P092, P127 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - ITorqueConverterDeclarationInputData TorqueConverter { get; } - } - - - public interface ITransmissionInputData - { - int Gear { get; } - - /// <summary> - /// P078 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double Ratio { get; } - - /// <summary> - /// P079 - /// P096, P097, P098 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData LossMap { get; } - - /// <summary> - /// P079 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double Efficiency { get; } - - ///// <summary> - ///// P145 - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //DataTable FullLoadCurve { get; } // deprecated - - /// <summary> - /// P157 - /// </summary> - NewtonMeter MaxTorque { get; } - - PerSecond MaxInputSpeed { get; } - - /// <summary> - /// P082 - /// P093, P094, P095 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData ShiftPolygon { get; } - - ///// <summary> - ///// P077 - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //bool HasTorqueConverter { get; } // DEPRECATED - } - - public interface IAxleGearInputData : IComponentInputData - { - /// <summary> - /// P078 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double Ratio { get; } - - /// <summary> - /// P079 - /// P096, P097, P098 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData LossMap { get; } - - /// <summary> - /// P079 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double Efficiency { get; } - - AxleLineType LineType { get; } - } - - public interface ITorqueConverterDeclarationInputData : IComponentInputData - { - /// <summary> - /// P091 - /// P099, P100, P101 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - // ReSharper disable once InconsistentNaming - TableData TCData { get; } - } - - public interface IEngineDeclarationInputData : IComponentInputData - { - /// <summary> - /// P061 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - CubicMeter Displacement { get; } - - /// <summary> - /// P063 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - PerSecond IdleSpeed { get; } - - /// <summary> - /// P111 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double WHTCMotorway { get; } - - /// <summary> - /// P110 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double WHTCRural { get; } - - /// <summary> - /// P109 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double WHTCUrban { get; } - - /// <summary> - /// P159 - /// </summary> - double ColdHotBalancingFactor { get; } - - double CorrectionFactorRegPer { get; } - - double CorrectionFactorNCV { get; } - - FuelType FuelType { get; } - - /// <summary> - /// P067 - /// P072, P073, P074 - /// cf. VECTO Input Parameters.xlsx - /// engine speed in rpm, torque in NM, fuel consumption in g/h - /// </summary> - TableData FuelConsumptionMap { get; } - - /// <summary> - /// P144 - /// P068, P069, P70, P71 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData FullLoadCurve { get; } - - Watt RatedPowerDeclared { get; } - - PerSecond RatedSpeedDeclared { get; } - - NewtonMeter MaxTorqueDeclared { get; } - } - - public interface IAuxiliariesDeclarationInputData - { - bool SavedInDeclarationMode { get; } - - IList<IAuxiliaryDeclarationInputData> Auxiliaries { get; } - } - - public interface ICycleData - { - string Name { get; } - - /// <summary> - /// P028, P029, P030, P031, P032, P119, P120, P121, P122, P123, P124, P125, P126 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData CycleData { get; } - } - - public interface IDriverDeclarationInputData - { - bool SavedInDeclarationMode { get; } - - IOverSpeedEcoRollDeclarationInputData OverSpeedEcoRoll { get; } - } - - public interface IOverSpeedEcoRollDeclarationInputData - { - /// <summary> - /// P015 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - DriverMode Mode { get; } - } - - public interface IAuxiliaryDeclarationInputData - { - /// <summary> - /// P005 Aux-Type - /// cf. VECTO Input Parameters.xlsx - /// </summary> - AuxiliaryType Type { get; } - - /// <summary> - /// P118 Aux-Technology - /// cf. VECTO Input Parameters.xlsx - /// </summary> - IList<string> Technology { get; } - } - - public interface ITorqueLimitInputData - { - int Gear { get; } - - NewtonMeter MaxTorque { get; } - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCommon.InputData +{ + public interface IDeclarationJobInputData + { + bool SavedInDeclarationMode { get; } + + IVehicleDeclarationInputData Vehicle { get; } + + string JobName { get; } + } + + public interface IComponentInputData + { + DataSourceType SourceType { get; } + + string Source { get; } + + bool SavedInDeclarationMode { get; } + + string Manufacturer { get; } + + string Model { get; } + + string Date { get; } + + CertificationMethod CertificationMethod { get; } + + string CertificationNumber { get; } + + string DigestValue { get; } + } + + public interface IVehicleDeclarationInputData : IComponentInputData + { + string VIN { get; } + + LegislativeClass LegislativeClass { get; } + + /// <summary> + /// P036 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + VehicleCategory VehicleCategory { get; } + + /// <summary> + /// P037 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + AxleConfiguration AxleConfiguration { get; } + + /// <summary> + /// P038 Curb Weight Vehicle + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Kilogram CurbMassChassis { get; } + + /// <summary> + /// P041 Max. vehicle weight + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Kilogram GrossVehicleMassRating { get; } + + ///// <summary> + ///// P117 Powered axle tyres/rims + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //string Rim { get; } // deprecated + + IList<ITorqueLimitInputData> TorqueLimits { get; } + + /// <summary> + /// parameters for every axle + /// P044, P045, P046, P047, P048, P108 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + IList<IAxleDeclarationInputData> Axles { get; } + + string ManufacturerAddress { get; } + + PerSecond EngineIdleSpeed { get; } + } + + public interface IAirdragDeclarationInputData : IComponentInputData + { + /// <summary> + /// P146, P147 DragCoefficient * Cross Section Area - Rigid + /// cf. VECTO Input Parameters.xlsx + /// </summary> + SquareMeter AirDragArea { get; } // without trailer + } + + public interface IRetarderInputData : IComponentInputData + { + /// <summary> + /// P052 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + RetarderType Type { get; } + + /// <summary> + /// P053 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double Ratio { get; } + + /// <summary> + /// P054 + /// P057, P058 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData LossMap { get; } + } + + public interface IAngledriveInputData : IComponentInputData + { + /// <summary> + /// P180 + /// </summary> + AngledriveType Type { get; } + + /// <summary> + /// P176 + /// </summary> + double Ratio { get; } + + /// <summary> + /// P173, P174, P175 + /// </summary> + TableData LossMap { get; } + + /// <summary> + /// P177 + /// </summary> + double Efficiency { get; } + } + + public interface IAxleDeclarationInputData + { + /// <summary> + /// P108 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + string Wheels { get; } + + /// <summary> + /// P045 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + bool TwinTyres { get; } + + AxleType AxleType { get; } + + /// <summary> + /// P046 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double RollResistanceCoefficient { get; } + + /// <summary> + /// P047 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Newton TyreTestLoad { get; } + } + + public interface IGearboxDeclarationInputData : IComponentInputData + { + /// <summary> + /// P076 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + GearboxType Type { get; } + + /// <summary> + /// P078, P079, P077, P082, P145 (for every gear) + /// cf. VECTO Input Parameters.xlsx + /// </summary> + IList<ITransmissionInputData> Gears { get; } + + /// <summary> + /// P090, P091, P092, P127 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + ITorqueConverterDeclarationInputData TorqueConverter { get; } + } + + + public interface ITransmissionInputData + { + int Gear { get; } + + /// <summary> + /// P078 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double Ratio { get; } + + /// <summary> + /// P079 + /// P096, P097, P098 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData LossMap { get; } + + /// <summary> + /// P079 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double Efficiency { get; } + + ///// <summary> + ///// P145 + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //DataTable FullLoadCurve { get; } // deprecated + + /// <summary> + /// P157 + /// </summary> + NewtonMeter MaxTorque { get; } + + PerSecond MaxInputSpeed { get; } + + /// <summary> + /// P082 + /// P093, P094, P095 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData ShiftPolygon { get; } + + ///// <summary> + ///// P077 + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //bool HasTorqueConverter { get; } // DEPRECATED + } + + public interface IAxleGearInputData : IComponentInputData + { + /// <summary> + /// P078 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double Ratio { get; } + + /// <summary> + /// P079 + /// P096, P097, P098 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData LossMap { get; } + + /// <summary> + /// P079 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double Efficiency { get; } + + AxleLineType LineType { get; } + } + + public interface ITorqueConverterDeclarationInputData : IComponentInputData + { + /// <summary> + /// P091 + /// P099, P100, P101 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + // ReSharper disable once InconsistentNaming + TableData TCData { get; } + } + + public interface IEngineDeclarationInputData : IComponentInputData + { + /// <summary> + /// P061 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + CubicMeter Displacement { get; } + + /// <summary> + /// P063 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + PerSecond IdleSpeed { get; } + + /// <summary> + /// P111 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double WHTCMotorway { get; } + + /// <summary> + /// P110 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double WHTCRural { get; } + + /// <summary> + /// P109 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double WHTCUrban { get; } + + /// <summary> + /// P159 + /// </summary> + double ColdHotBalancingFactor { get; } + + double CorrectionFactorRegPer { get; } + + double CorrectionFactorNCV { get; } + + FuelType FuelType { get; } + + /// <summary> + /// P067 + /// P072, P073, P074 + /// cf. VECTO Input Parameters.xlsx + /// engine speed in rpm, torque in NM, fuel consumption in g/h + /// </summary> + TableData FuelConsumptionMap { get; } + + /// <summary> + /// P144 + /// P068, P069, P70, P71 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData FullLoadCurve { get; } + + Watt RatedPowerDeclared { get; } + + PerSecond RatedSpeedDeclared { get; } + + NewtonMeter MaxTorqueDeclared { get; } + } + + public interface IAuxiliariesDeclarationInputData + { + bool SavedInDeclarationMode { get; } + + IList<IAuxiliaryDeclarationInputData> Auxiliaries { get; } + } + + public interface ICycleData + { + string Name { get; } + + /// <summary> + /// P028, P029, P030, P031, P032, P119, P120, P121, P122, P123, P124, P125, P126 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData CycleData { get; } + } + + public interface IDriverDeclarationInputData + { + bool SavedInDeclarationMode { get; } + + IOverSpeedEcoRollDeclarationInputData OverSpeedEcoRoll { get; } + } + + public interface IOverSpeedEcoRollDeclarationInputData + { + /// <summary> + /// P015 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + DriverMode Mode { get; } + } + + public interface IAuxiliaryDeclarationInputData + { + /// <summary> + /// P005 Aux-Type + /// cf. VECTO Input Parameters.xlsx + /// </summary> + AuxiliaryType Type { get; } + + /// <summary> + /// P118 Aux-Technology + /// cf. VECTO Input Parameters.xlsx + /// </summary> + IList<string> Technology { get; } + } + + public interface ITorqueLimitInputData + { + int Gear { get; } + + NewtonMeter MaxTorque { get; } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs index 843b776eb5f9803e06f9f05281624e63bb111287..4f9230a9f46510fd976786efaa6e352d69bb7f00 100644 --- a/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs +++ b/VectoCommon/VectoCommon/InputData/EngineeringInputData.cs @@ -29,340 +29,341 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCommon.InputData -{ - public interface IEngineeringJobInputData : IDeclarationJobInputData - { - new IVehicleEngineeringInputData Vehicle { get; } - - /// <summary> - /// P008 Cycles - /// cf. VECTO Input Parameters.xlsx - /// </summary> - IList<ICycleData> Cycles { get; } - - /// <summary> - /// P001 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - bool EngineOnlyMode { get; } - } - - public interface IVehicleEngineeringInputData : IVehicleDeclarationInputData - { - /// <summary> - /// P039 Curb Weight Extra Trailer/Body - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Kilogram CurbMassExtra { get; } - - /// <summary> - /// P040 Loading - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Kilogram Loading { get; } - - /// <summary> - /// parameters for every axle - /// P044, P045, P046, P047, P048, P108 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - new IList<IAxleEngineeringInputData> Axles { get; } - - /// <summary> - /// P049 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Meter DynamicTyreRadius { get; } - } - - public interface IAirdragEngineeringInputData : IAirdragDeclarationInputData - { - /// <summary> - /// P050 - Cross Wind Correction Mode - /// cf. VECTO Input Parameters.xlsx - /// </summary> - CrossWindCorrectionMode CrossWindCorrectionMode { get; } - - /// <summary> - /// P051 - /// P055, P056 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData CrosswindCorrectionMap { get; } - } - - public interface IPTOTransmissionInputData - { - /// <summary> - /// The transmission type for the constant pto transmission losses. - /// </summary> - string PTOTransmissionType { get; } - - /// <summary> - /// The PTO Loss map for idling losses of the "consumer" part. - /// </summary> - TableData PTOLossMap { get; } - - TableData PTOCycle { get; } - } - - public interface IAxleEngineeringInputData : IAxleDeclarationInputData - { - /// <summary> - /// P044 (0 - 1) - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double AxleWeightShare { get; } - - /// <summary> - /// P048 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - KilogramSquareMeter Inertia { get; } - } - - public interface IGearboxEngineeringInputData : IGearboxDeclarationInputData - { - /// <summary> - /// P080 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - KilogramSquareMeter Inertia { get; } - - /// <summary> - /// P081 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Second TractionInterruption { get; } - - /// <summary> - /// P086 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - Second MinTimeBetweenGearshift { get; } - - ///// <summary> - ///// P083 - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //bool EarlyShiftUp { get; } - - /// <summary> - /// P085 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double TorqueReserve { get; } - - /// <summary> - /// P087 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSecond StartSpeed { get; } - - /// <summary> - /// P088 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSquareSecond StartAcceleration { get; } - - /// <summary> - /// P089 - /// [%] (0-1) - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double StartTorqueReserve { get; } - - ///// <summary> - ///// P084 - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //bool SkipGears { get; } - - Second DownshiftAfterUpshiftDelay { get; } - - Second UpshiftAfterDownshiftDelay { get; } - - MeterPerSquareSecond UpshiftMinAcceleration { get; } - - Second PowershiftShiftTime { get; } - - new ITorqueConverterEngineeringInputData TorqueConverter { get; } - } - - public interface ITorqueConverterEngineeringInputData : ITorqueConverterDeclarationInputData - { - ///// <summary> - ///// P090 - ///// cf. VECTO Input Parameters.xlsx - ///// </summary> - //bool Enabled { get; } // deprecated - - /// <summary> - /// P092 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - // ReSharper disable once InconsistentNaming - PerSecond ReferenceRPM { get; } - - /// <summary> - /// P127 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - KilogramSquareMeter Inertia { get; } - - TableData ShiftPolygon { get; } - - PerSecond MaxInputSpeed { get; } - - /// <summary> - /// Min Acceleration after C->L upshifts. - /// </summary> - MeterPerSquareSecond CLUpshiftMinAcceleration { get; } - - /// <summary> - /// Min Acceleration after C->C upshifts. - /// </summary> - MeterPerSquareSecond CCUpshiftMinAcceleration { get; } - } - - public interface IEngineEngineeringInputData : IEngineDeclarationInputData - { - /// <summary> - /// P062 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - KilogramSquareMeter Inertia { get; } - - /// <summary> - /// P170 - /// </summary> - double WHTCEngineering { get; } - } - - public interface IAuxiliariesEngineeringInputData - { - IList<IAuxiliaryEngineeringInputData> Auxiliaries { get; } - - // Advanced Auxiliaries - AuxiliaryModel AuxiliaryAssembly { get; } - - string AuxiliaryVersion { get; } - - string AdvancedAuxiliaryFilePath { get; } - } - - public interface IDriverEngineeringInputData : IDriverDeclarationInputData - { - //new IStartStopEngineeringInputData StartStop { get; } - - new IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll { get; } - - /// <summary> - /// P009; P033, P034, P035 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData AccelerationCurve { get; } - - ILookaheadCoastingInputData Lookahead { get; } - } - - public interface IOverSpeedEcoRollEngineeringInputData : IOverSpeedEcoRollDeclarationInputData - { - /// <summary> - /// P016 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSecond MinSpeed { get; } - - /// <summary> - /// P017 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSecond OverSpeed { get; } - - /// <summary> - /// P018 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSecond UnderSpeed { get; } - } - - public interface ILookaheadCoastingInputData - { - /// <summary> - /// P019 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - bool Enabled { get; } - - /// <summary> - /// P020 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - //MeterPerSquareSecond Deceleration { get; } - /// <summary> - /// P021 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - MeterPerSecond MinSpeed { get; } - - double CoastingDecisionFactorOffset { get; } - - double CoastingDecisionFactorScaling { get; } - - double LookaheadDistanceFactor { get; } - - TableData CoastingDecisionFactorTargetSpeedLookup { get; } - - TableData CoastingDecisionFactorVelocityDropLookup { get; } - } - - public interface IAuxiliaryEngineeringInputData - { - /// <summary> - /// P006 Aux-ID - /// cf. VECTO Input Parameters.xlsx - /// </summary> - string ID { get; } - - /// <summary> - /// either mapping or constant - /// </summary> - AuxiliaryDemandType AuxiliaryType { get; } - - /// <summary> - /// P022 Aux-InputFile: transmission ratio - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double TransmissionRatio { get; } - - /// <summary> - /// P023 Aux-InputFile: efficiency to engine - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double EfficiencyToEngine { get; } - - /// <summary> - /// P024 Aux-InputFile: efficiency to supply - /// cf. VECTO Input Parameters.xlsx - /// </summary> - double EfficiencyToSupply { get; } - - /// <summary> - /// P025, P026, P027 Aux-InputFile: map - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData DemandMap { get; } - - /// <summary> - /// P178 - /// additional constant auxiliary load, similar to Padd; not specified in the cycle but as auxiliary - /// </summary> - Watt ConstantPowerDemand { get; } - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCommon.InputData +{ + public interface IEngineeringJobInputData : IDeclarationJobInputData + { + new IVehicleEngineeringInputData Vehicle { get; } + + /// <summary> + /// P008 Cycles + /// cf. VECTO Input Parameters.xlsx + /// </summary> + IList<ICycleData> Cycles { get; } + + /// <summary> + /// P001 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + bool EngineOnlyMode { get; } + } + + public interface IVehicleEngineeringInputData : IVehicleDeclarationInputData + { + + /// <summary> + /// P039 Curb Weight Extra Trailer/Body + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Kilogram CurbMassExtra { get; } + + /// <summary> + /// P040 Loading + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Kilogram Loading { get; } + + /// <summary> + /// parameters for every axle + /// P044, P045, P046, P047, P048, P108 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + new IList<IAxleEngineeringInputData> Axles { get; } + + /// <summary> + /// P049 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Meter DynamicTyreRadius { get; } + } + + public interface IAirdragEngineeringInputData : IAirdragDeclarationInputData + { + /// <summary> + /// P050 - Cross Wind Correction Mode + /// cf. VECTO Input Parameters.xlsx + /// </summary> + CrossWindCorrectionMode CrossWindCorrectionMode { get; } + + /// <summary> + /// P051 + /// P055, P056 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData CrosswindCorrectionMap { get; } + } + + public interface IPTOTransmissionInputData + { + /// <summary> + /// The transmission type for the constant pto transmission losses. + /// </summary> + string PTOTransmissionType { get; } + + /// <summary> + /// The PTO Loss map for idling losses of the "consumer" part. + /// </summary> + TableData PTOLossMap { get; } + + TableData PTOCycle { get; } + } + + public interface IAxleEngineeringInputData : IAxleDeclarationInputData + { + /// <summary> + /// P044 (0 - 1) + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double AxleWeightShare { get; } + + /// <summary> + /// P048 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + KilogramSquareMeter Inertia { get; } + } + + public interface IGearboxEngineeringInputData : IGearboxDeclarationInputData + { + /// <summary> + /// P080 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + KilogramSquareMeter Inertia { get; } + + /// <summary> + /// P081 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Second TractionInterruption { get; } + + /// <summary> + /// P086 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + Second MinTimeBetweenGearshift { get; } + + ///// <summary> + ///// P083 + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //bool EarlyShiftUp { get; } + + /// <summary> + /// P085 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double TorqueReserve { get; } + + /// <summary> + /// P087 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSecond StartSpeed { get; } + + /// <summary> + /// P088 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSquareSecond StartAcceleration { get; } + + /// <summary> + /// P089 + /// [%] (0-1) + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double StartTorqueReserve { get; } + + ///// <summary> + ///// P084 + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //bool SkipGears { get; } + + Second DownshiftAfterUpshiftDelay { get; } + + Second UpshiftAfterDownshiftDelay { get; } + + MeterPerSquareSecond UpshiftMinAcceleration { get; } + + Second PowershiftShiftTime { get; } + + new ITorqueConverterEngineeringInputData TorqueConverter { get; } + } + + public interface ITorqueConverterEngineeringInputData : ITorqueConverterDeclarationInputData + { + ///// <summary> + ///// P090 + ///// cf. VECTO Input Parameters.xlsx + ///// </summary> + //bool Enabled { get; } // deprecated + + /// <summary> + /// P092 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + // ReSharper disable once InconsistentNaming + PerSecond ReferenceRPM { get; } + + /// <summary> + /// P127 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + KilogramSquareMeter Inertia { get; } + + TableData ShiftPolygon { get; } + + PerSecond MaxInputSpeed { get; } + + /// <summary> + /// Min Acceleration after C->L upshifts. + /// </summary> + MeterPerSquareSecond CLUpshiftMinAcceleration { get; } + + /// <summary> + /// Min Acceleration after C->C upshifts. + /// </summary> + MeterPerSquareSecond CCUpshiftMinAcceleration { get; } + } + + public interface IEngineEngineeringInputData : IEngineDeclarationInputData + { + /// <summary> + /// P062 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + KilogramSquareMeter Inertia { get; } + + /// <summary> + /// P170 + /// </summary> + double WHTCEngineering { get; } + } + + public interface IAuxiliariesEngineeringInputData + { + IList<IAuxiliaryEngineeringInputData> Auxiliaries { get; } + + // Advanced Auxiliaries + AuxiliaryModel AuxiliaryAssembly { get; } + + string AuxiliaryVersion { get; } + + string AdvancedAuxiliaryFilePath { get; } + } + + public interface IDriverEngineeringInputData : IDriverDeclarationInputData + { + //new IStartStopEngineeringInputData StartStop { get; } + + new IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll { get; } + + /// <summary> + /// P009; P033, P034, P035 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData AccelerationCurve { get; } + + ILookaheadCoastingInputData Lookahead { get; } + } + + public interface IOverSpeedEcoRollEngineeringInputData : IOverSpeedEcoRollDeclarationInputData + { + /// <summary> + /// P016 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSecond MinSpeed { get; } + + /// <summary> + /// P017 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSecond OverSpeed { get; } + + /// <summary> + /// P018 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSecond UnderSpeed { get; } + } + + public interface ILookaheadCoastingInputData + { + /// <summary> + /// P019 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + bool Enabled { get; } + + /// <summary> + /// P020 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + //MeterPerSquareSecond Deceleration { get; } + /// <summary> + /// P021 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + MeterPerSecond MinSpeed { get; } + + double CoastingDecisionFactorOffset { get; } + + double CoastingDecisionFactorScaling { get; } + + double LookaheadDistanceFactor { get; } + + TableData CoastingDecisionFactorTargetSpeedLookup { get; } + + TableData CoastingDecisionFactorVelocityDropLookup { get; } + } + + public interface IAuxiliaryEngineeringInputData + { + /// <summary> + /// P006 Aux-ID + /// cf. VECTO Input Parameters.xlsx + /// </summary> + string ID { get; } + + /// <summary> + /// either mapping or constant + /// </summary> + AuxiliaryDemandType AuxiliaryType { get; } + + /// <summary> + /// P022 Aux-InputFile: transmission ratio + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double TransmissionRatio { get; } + + /// <summary> + /// P023 Aux-InputFile: efficiency to engine + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double EfficiencyToEngine { get; } + + /// <summary> + /// P024 Aux-InputFile: efficiency to supply + /// cf. VECTO Input Parameters.xlsx + /// </summary> + double EfficiencyToSupply { get; } + + /// <summary> + /// P025, P026, P027 Aux-InputFile: map + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData DemandMap { get; } + + /// <summary> + /// P178 + /// additional constant auxiliary load, similar to Padd; not specified in the cycle but as auxiliary + /// </summary> + Watt ConstantPowerDemand { get; } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/InputData/IInputDataProvider.cs b/VectoCommon/VectoCommon/InputData/IInputDataProvider.cs index 16cd627535b02621b2ef2a626409cdbcf3b095fa..836135d05d95e69cacff2f26dde7ec2169d3743a 100644 --- a/VectoCommon/VectoCommon/InputData/IInputDataProvider.cs +++ b/VectoCommon/VectoCommon/InputData/IInputDataProvider.cs @@ -29,65 +29,65 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Xml.Linq; - -namespace TUGraz.VectoCommon.InputData -{ - public interface IInputDataProvider {} - - public interface IDeclarationInputDataProvider : IInputDataProvider - { - IDeclarationJobInputData JobInputData(); - - IVehicleDeclarationInputData VehicleInputData { get; } - - IAirdragDeclarationInputData AirdragInputData { get; } - - IGearboxDeclarationInputData GearboxInputData { get; } - - ITorqueConverterDeclarationInputData TorqueConverterInputData { get; } - - IAxleGearInputData AxleGearInputData { get; } - - IAngledriveInputData AngledriveInputData { get; } - - IEngineDeclarationInputData EngineInputData { get; } - - IAuxiliariesDeclarationInputData AuxiliaryInputData(); - - IRetarderInputData RetarderInputData { get; } - - IDriverDeclarationInputData DriverInputData { get; } - - IPTOTransmissionInputData PTOTransmissionInputData { get; } - - XElement XMLHash { get; } - } - - public interface IEngineeringInputDataProvider : IInputDataProvider - { - IEngineeringJobInputData JobInputData(); - - IVehicleEngineeringInputData VehicleInputData { get; } - - IAirdragEngineeringInputData AirdragInputData { get; } - - IGearboxEngineeringInputData GearboxInputData { get; } - - ITorqueConverterEngineeringInputData TorqueConverterInputData { get; } - - IAxleGearInputData AxleGearInputData { get; } - - IAngledriveInputData AngledriveInputData { get; } - - IEngineEngineeringInputData EngineInputData { get; } - - IAuxiliariesEngineeringInputData AuxiliaryInputData(); - - IRetarderInputData RetarderInputData { get; } - - IDriverEngineeringInputData DriverInputData { get; } - - IPTOTransmissionInputData PTOTransmissionInputData { get; } - } +using System.Xml.Linq; + +namespace TUGraz.VectoCommon.InputData +{ + public interface IInputDataProvider {} + + public interface IDeclarationInputDataProvider : IInputDataProvider + { + IDeclarationJobInputData JobInputData(); + + IVehicleDeclarationInputData VehicleInputData { get; } + + IAirdragDeclarationInputData AirdragInputData { get; } + + IGearboxDeclarationInputData GearboxInputData { get; } + + ITorqueConverterDeclarationInputData TorqueConverterInputData { get; } + + IAxleGearInputData AxleGearInputData { get; } + + IAngledriveInputData AngledriveInputData { get; } + + IEngineDeclarationInputData EngineInputData { get; } + + IAuxiliariesDeclarationInputData AuxiliaryInputData(); + + IRetarderInputData RetarderInputData { get; } + + IDriverDeclarationInputData DriverInputData { get; } + + IPTOTransmissionInputData PTOTransmissionInputData { get; } + + XElement XMLHash { get; } + } + + public interface IEngineeringInputDataProvider : IInputDataProvider + { + IEngineeringJobInputData JobInputData(); + + IVehicleEngineeringInputData VehicleInputData { get; } + + IAirdragEngineeringInputData AirdragInputData { get; } + + IGearboxEngineeringInputData GearboxInputData { get; } + + ITorqueConverterEngineeringInputData TorqueConverterInputData { get; } + + IAxleGearInputData AxleGearInputData { get; } + + IAngledriveInputData AngledriveInputData { get; } + + IEngineEngineeringInputData EngineInputData { get; } + + IAuxiliariesEngineeringInputData AuxiliaryInputData(); + + IRetarderInputData RetarderInputData { get; } + + IDriverEngineeringInputData DriverInputData { get; } + + IPTOTransmissionInputData PTOTransmissionInputData { get; } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Models/AngledriveType.cs b/VectoCommon/VectoCommon/Models/AngledriveType.cs index 0dd942600798bcf91b1e4068d28cb1019afe9f0e..8f9a25d8ad946ceb9b53c5ed6de59aa69ced1c0f 100644 --- a/VectoCommon/VectoCommon/Models/AngledriveType.cs +++ b/VectoCommon/VectoCommon/Models/AngledriveType.cs @@ -29,45 +29,45 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; - -namespace TUGraz.VectoCommon.Models -{ - public enum AngledriveType - { - None, - SeparateAngledrive, - LossesIncludedInGearbox, - } - - public static class AngledriveTypeHelper - { - public static string GetLabel(this AngledriveType type) - { - switch (type) { - case AngledriveType.None: - return "None"; - case AngledriveType.SeparateAngledrive: - return "Separate Angledrive"; - case AngledriveType.LossesIncludedInGearbox: - return "Included in Transmission Loss Maps"; - default: - throw new ArgumentOutOfRangeException("AngledriveType", type, null); - } - } - - public static string ToXMLFormat(this AngledriveType type) - { - switch (type) { - case AngledriveType.None: - return "None"; - case AngledriveType.SeparateAngledrive: - return "Separate Angledrive"; - case AngledriveType.LossesIncludedInGearbox: - return "Losses included in Gearbox"; - default: - throw new ArgumentOutOfRangeException("Angledrive Type", type, null); - } - } - } +using System; + +namespace TUGraz.VectoCommon.Models +{ + public enum AngledriveType + { + None, + SeparateAngledrive, + LossesIncludedInGearbox, + } + + public static class AngledriveTypeHelper + { + public static string GetLabel(this AngledriveType type) + { + switch (type) { + case AngledriveType.None: + return "None"; + case AngledriveType.SeparateAngledrive: + return "Separate Angledrive"; + case AngledriveType.LossesIncludedInGearbox: + return "Included in Transmission Loss Maps"; + default: + throw new ArgumentOutOfRangeException("AngledriveType", type, null); + } + } + + public static string ToXMLFormat(this AngledriveType type) + { + switch (type) { + case AngledriveType.None: + return "None"; + case AngledriveType.SeparateAngledrive: + return "Separate Angledrive"; + case AngledriveType.LossesIncludedInGearbox: + return "Losses included in Gearbox"; + default: + throw new ArgumentOutOfRangeException("Angledrive Type", type, null); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Models/AxleConfiguration.cs b/VectoCommon/VectoCommon/Models/AxleConfiguration.cs index 19d6524dce6fbccbf49c362d0c4b673609e97fe1..c03fdd32d0404d68137a5da18f8d45679506ebd4 100644 --- a/VectoCommon/VectoCommon/Models/AxleConfiguration.cs +++ b/VectoCommon/VectoCommon/Models/AxleConfiguration.cs @@ -29,81 +29,101 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Diagnostics.CodeAnalysis; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCommon.Models -{ - [SuppressMessage("ReSharper", "InconsistentNaming")] - public enum AxleConfiguration - { - AxleConfig_4x2, - AxleConfig_4x4, - AxleConfig_6x2, - AxleConfig_6x4, - AxleConfig_6x6, - AxleConfig_8x2, - AxleConfig_8x4, - AxleConfig_8x6, - AxleConfig_8x8, - } - - public enum AxleType - { - VehicleDriven, - VehicleNonDriven, - Trailer - } - - public static class AxleTypeHelper - { - public static string GetLabel(this AxleType self) - { - switch (self) { - case AxleType.VehicleDriven: - return "Vehicle driven"; - case AxleType.VehicleNonDriven: - return "Vehicle non-driven"; - case AxleType.Trailer: - return "Trailer"; - default: - throw new ArgumentOutOfRangeException("self", self, null); - } - } - } - - public static class AxleConfigurationHelper - { - private const string Prefix = "AxleConfig_"; - - public static string GetName(this AxleConfiguration self) - { - return self.ToString().Replace(Prefix, ""); - } - - public static AxleConfiguration Parse(string typeString) - { - return (Prefix + typeString).ParseEnum<AxleConfiguration>(); - } - - public static int NumAxles(this AxleConfiguration self) - { - switch (self) { - case AxleConfiguration.AxleConfig_4x2: - case AxleConfiguration.AxleConfig_4x4: - return 2; - case AxleConfiguration.AxleConfig_6x2: - case AxleConfiguration.AxleConfig_6x4: - case AxleConfiguration.AxleConfig_6x6: - return 3; - case AxleConfiguration.AxleConfig_8x2: - case AxleConfiguration.AxleConfig_8x4: - case AxleConfiguration.AxleConfig_8x6: - case AxleConfiguration.AxleConfig_8x8: - return 4; - } - return 0; - } - } +using System; +using System.Diagnostics.CodeAnalysis; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCommon.Models +{ + [SuppressMessage("ReSharper", "InconsistentNaming")] + public enum AxleConfiguration + { + AxleConfig_4x2, + AxleConfig_4x4, + AxleConfig_6x2, + AxleConfig_6x4, + AxleConfig_6x6, + AxleConfig_8x2, + AxleConfig_8x4, + AxleConfig_8x6, + AxleConfig_8x8, + } + + public enum AxleType + { + VehicleDriven, + VehicleNonDriven, + Trailer + } + + public static class AxleTypeHelper + { + public static string GetLabel(this AxleType self) + { + switch (self) { + case AxleType.VehicleDriven: + return "Vehicle driven"; + case AxleType.VehicleNonDriven: + return "Vehicle non-driven"; + case AxleType.Trailer: + return "Trailer"; + default: + throw new ArgumentOutOfRangeException("self", self, null); + } + } + } + + public static class AxleConfigurationHelper + { + private const string Prefix = "AxleConfig_"; + + public static string GetName(this AxleConfiguration self) + { + return self.ToString().Replace(Prefix, ""); + } + + public static AxleConfiguration Parse(string typeString) + { + return (Prefix + typeString).ParseEnum<AxleConfiguration>(); + } + + public static int NumAxles(this AxleConfiguration self) + { + switch (self) { + case AxleConfiguration.AxleConfig_4x2: + case AxleConfiguration.AxleConfig_4x4: + return 2; + case AxleConfiguration.AxleConfig_6x2: + case AxleConfiguration.AxleConfig_6x4: + case AxleConfiguration.AxleConfig_6x6: + return 3; + case AxleConfiguration.AxleConfig_8x2: + case AxleConfiguration.AxleConfig_8x4: + case AxleConfiguration.AxleConfig_8x6: + case AxleConfiguration.AxleConfig_8x8: + return 4; + } + return 0; + } + + public static int NumDrivenAxles(this AxleConfiguration self) + { + switch (self) { + case AxleConfiguration.AxleConfig_4x2: + case AxleConfiguration.AxleConfig_6x2: + case AxleConfiguration.AxleConfig_8x2: + return 1; + case AxleConfiguration.AxleConfig_4x4: + case AxleConfiguration.AxleConfig_6x4: + case AxleConfiguration.AxleConfig_8x4: + return 2; + case AxleConfiguration.AxleConfig_6x6: + case AxleConfiguration.AxleConfig_8x6: + return 3; + case AxleConfiguration.AxleConfig_8x8: + return 4; + } + return 0; + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Models/LegislativeClass.cs b/VectoCommon/VectoCommon/Models/LegislativeClass.cs new file mode 100644 index 0000000000000000000000000000000000000000..d6addcc01eab7107b0b79663fe600f0203737943 --- /dev/null +++ b/VectoCommon/VectoCommon/Models/LegislativeClass.cs @@ -0,0 +1,22 @@ +namespace TUGraz.VectoCommon.Models +{ + public enum LegislativeClass + { + Unknown, + N2, + N3 + } + + public static class LegislativeClassHelper + { + public static string GetLabel(this LegislativeClass self) + { + return self.ToString(); + } + + public static string ToXMLFormat(this LegislativeClass self) + { + return self.ToString(); + } + } +} \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Models/OperatingPoint.cs b/VectoCommon/VectoCommon/Models/OperatingPoint.cs index c5b154f942a2da0103f7c934dd234f9174b2c0e7..627ef89223fc810aff533b2b6c9981dc501ac2a5 100644 --- a/VectoCommon/VectoCommon/Models/OperatingPoint.cs +++ b/VectoCommon/VectoCommon/Models/OperatingPoint.cs @@ -35,7 +35,7 @@ using TUGraz.VectoCommon.Utils; namespace TUGraz.VectoCommon.Models { [DebuggerDisplay("a: {Acceleration}, dt: {SimulationInterval}, ds: {SimulationDistance}")] - public struct OperatingPoint + public class OperatingPoint { public MeterPerSquareSecond Acceleration; public Meter SimulationDistance; diff --git a/VectoCommon/VectoCommon/Models/VehicleCategory.cs b/VectoCommon/VectoCommon/Models/VehicleCategory.cs index af6baf04d0637013b03aae01d733db3a9bf0817f..8c59130ffc0d0278926eca1996c539f866c14062 100644 --- a/VectoCommon/VectoCommon/Models/VehicleCategory.cs +++ b/VectoCommon/VectoCommon/Models/VehicleCategory.cs @@ -29,72 +29,87 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; - -namespace TUGraz.VectoCommon.Models -{ - public enum VehicleCategory - { - RigidTruck, - Tractor, - CityBus, - InterurbanBus, - Coach - } - - public static class VehicleCategoryHelper - { - public static string GetLabel(this VehicleCategory category) - { - switch (category) - { - case VehicleCategory.RigidTruck: - return "Rigid Truck"; - case VehicleCategory.Tractor: - return "Tractor"; - case VehicleCategory.CityBus: - return "City Bus"; - case VehicleCategory.InterurbanBus: - return "Interurban Bus"; - case VehicleCategory.Coach: - return "Coach"; - default: - return category.ToString(); - } - } - public static string GetCategoryName(this VehicleCategory category) - { - switch (category) { - case VehicleCategory.RigidTruck: - return "Rigid Truck"; - case VehicleCategory.Tractor: - return "Semitrailer Truck"; - case VehicleCategory.CityBus: - return "Citybus"; - case VehicleCategory.InterurbanBus: - return "Interurban Bus"; - case VehicleCategory.Coach: - return "Coach"; - default: - return category.ToString(); - } - } - - public static string ToXMLFormat(this VehicleCategory vehicleCategory) - { - switch (vehicleCategory) { - case VehicleCategory.Coach: - case VehicleCategory.Tractor: - return vehicleCategory.ToString(); - case VehicleCategory.CityBus: - return "City Bus"; - case VehicleCategory.InterurbanBus: - return "Interurban Bus"; - case VehicleCategory.RigidTruck: - return "Rigid Truck"; - default: - throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null); - } - } - } +using System; + +namespace TUGraz.VectoCommon.Models +{ + public enum VehicleCategory + { + RigidTruck, + Tractor, + CityBus, + InterurbanBus, + Coach + } + + public static class VehicleCategoryHelper + { + public static string GetLabel(this VehicleCategory category) + { + switch (category) { + case VehicleCategory.RigidTruck: + return "Rigid Truck"; + case VehicleCategory.Tractor: + return "Tractor"; + case VehicleCategory.CityBus: + return "City Bus"; + case VehicleCategory.InterurbanBus: + return "Interurban Bus"; + case VehicleCategory.Coach: + return "Coach"; + default: + return category.ToString(); + } + } + + public static string GetCategoryName(this VehicleCategory category) + { + switch (category) { + case VehicleCategory.RigidTruck: + return "Rigid Truck"; + case VehicleCategory.Tractor: + return "Semitrailer Truck"; + case VehicleCategory.CityBus: + return "Citybus"; + case VehicleCategory.InterurbanBus: + return "Interurban Bus"; + case VehicleCategory.Coach: + return "Coach"; + default: + return category.ToString(); + } + } + + public static string ToXMLFormat(this VehicleCategory vehicleCategory) + { + switch (vehicleCategory) { + case VehicleCategory.Coach: + case VehicleCategory.Tractor: + return vehicleCategory.ToString(); + case VehicleCategory.CityBus: + return "City Bus"; + case VehicleCategory.InterurbanBus: + return "Interurban Bus"; + case VehicleCategory.RigidTruck: + return "Rigid Truck"; + default: + throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null); + } + } + + public static bool IsTruck(this VehicleCategory category) + { + switch (category) { + case VehicleCategory.RigidTruck: + case VehicleCategory.Tractor: + return true; + case VehicleCategory.CityBus: + case VehicleCategory.InterurbanBus: + case VehicleCategory.Coach: + return false; + default: + throw new ArgumentOutOfRangeException("VehicleCategory", category, null); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Utils/VectoMath.cs b/VectoCommon/VectoCommon/Utils/VectoMath.cs index 4a63f351383d5cdeac2a5e9d7a7351f13084cc51..e3c10c4302dca7c8666acebd50fc14500329ec2d 100644 --- a/VectoCommon/VectoCommon/Utils/VectoMath.cs +++ b/VectoCommon/VectoCommon/Utils/VectoMath.cs @@ -29,704 +29,706 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Runtime.CompilerServices; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; - -namespace TUGraz.VectoCommon.Utils -{ - /// <summary> - /// Provides helper methods for mathematical functions. - /// </summary> - public static class VectoMath - { - /// <summary> - /// Linearly interpolates a value between two points. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <typeparam name="TResult">The type of the result.</typeparam> - /// <param name="x1">First Value on the X-Axis.</param> - /// <param name="x2">Second Value on the X-Axis.</param> - /// <param name="y1">First Value on the Y-Axis.</param> - /// <param name="y2">Second Value on the Y-Axis.</param> - /// <param name="xint">Value on the X-Axis, for which the Y-Value should be interpolated.</param> - /// <returns></returns> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TResult Interpolate<T, TResult>(T x1, T x2, TResult y1, TResult y2, T xint) where T : SI - where TResult : SIBase<TResult> - { - return Interpolate(x1.Value(), x2.Value(), y1.Value(), y2.Value(), xint.Value()).SI<TResult>(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TResult Interpolate<TInput, T, TResult>(this Tuple<TInput, TInput> self, Func<TInput, T> x, - Func<TInput, TResult> y, T xInterpolate) - where T : SIBase<T> - where TResult : SIBase<TResult> - { - return Interpolate(x(self.Item1).Value(), x(self.Item2).Value(), y(self.Item1).Value(), y(self.Item2).Value(), - xInterpolate.Value()).SI<TResult>(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TResult Interpolate<TInput, TResult>(this Tuple<TInput, TInput> self, Func<TInput, double> x, - Func<TInput, TResult> y, double xInterpolate) - where TResult : SIBase<TResult> - { - return - Interpolate(x(self.Item1), x(self.Item2), y(self.Item1).Value(), y(self.Item2).Value(), xInterpolate).SI<TResult>(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TResult Interpolate<TInput, TResult>(this IEnumerable<TInput> self, Func<TInput, double> x, - Func<TInput, TResult> y, double xInterpolate) - where TResult : SIBase<TResult> - { - return self.GetSection(elem => x(elem) < xInterpolate).Interpolate(x, y, xInterpolate); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Interpolate<TInput>(this IEnumerable<TInput> self, Func<TInput, double> x, - Func<TInput, double> y, double xInterpolate) - { - return self.GetSection(elem => x(elem) < xInterpolate).Interpolate(x, y, xInterpolate); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Interpolate<TInput>(this Tuple<TInput, TInput> self, Func<TInput, double> x, - Func<TInput, double> y, double xInterpolate) - { - return Interpolate(x(self.Item1), x(self.Item2), y(self.Item1), y(self.Item2), xInterpolate); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Interpolate<T>(T x1, T x2, double y1, double y2, T xint) where T : SI - { - return Interpolate(x1.Value(), x2.Value(), y1, y2, xint.Value()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TResult Interpolate<TResult>(double x1, double x2, TResult y1, TResult y2, double xint) - where TResult : SIBase<TResult> - { - return Interpolate(x1, x2, y1.Value(), y2.Value(), xint).SI<TResult>(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Interpolate(Point p1, Point p2, double x) - { - return Interpolate(p1.X, p2.X, p1.Y, p2.Y, x); - } - - /// <summary> - /// Linearly interpolates a value between two points. - /// </summary> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Interpolate(double x1, double x2, double y1, double y2, double xint) - { - return (xint - x1) * (y2 - y1) / (x2 - x1) + y1; - } - - /// <summary> - /// Returns the absolute value. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SI Abs(SI si) - { - return si.Abs(); - } - - /// <summary> - /// Returns the minimum of two values. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Min<T>(T c1, T c2) where T : IComparable - { - if (c1 == null) { - return c2; - } - - if (c2 == null) { - return c1; - } - - return c1.CompareTo(c2) <= 0 ? c1 : c2; - } - - /// <summary> - /// Returns the maximum of two values. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Max<T>(T c1, T c2) where T : IComparable - { - return c1.CompareTo(c2) > 0 ? c1 : c2; - } - - /// <summary> - /// Returns the maximum of two values. - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Max<T>(double c1, T c2) where T : SIBase<T> - { - return c1 > c2.Value() ? c1.SI<T>() : c2; - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Max<T>(T c1, T c2, T c3) where T : SIBase<T> - { - return Max(Max(c1, c2), c3); - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T LimitTo<T>(this T value, T lowerBound, T upperBound) where T : IComparable - { - if (lowerBound.CompareTo(upperBound) > 0) { - throw new VectoException( - "VectoMath.LimitTo: lowerBound must not be greater than upperBound. lowerBound: {0}, upperBound: {1}", lowerBound, - upperBound); - } - - if (value.CompareTo(upperBound) > 0) { - return upperBound; - } - - if (value.CompareTo(lowerBound) < 0) { - return lowerBound; - } - - return value; - } - - /// <summary> - /// converts the given inclination in percent (0-1+) into Radians - /// </summary> - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radian InclinationToAngle(double inclinationPercent) - { - return Math.Atan(inclinationPercent).SI<Radian>(); - } - - public static double[] QuadraticEquationSolver(double a, double b, double c) - { - var d = b * b - 4 * a * c; - - // no real solution - if (d < 0) { - return new double[0]; - } - - if (d > 0) { - // two solutions - return new[] { (-b + Math.Sqrt(d)) / (2 * a), (-b - Math.Sqrt(d)) / (2 * a) }; - } - - // one real solution - return new[] { -b / (2 * a) }; - } - - public static Point Intersect(Edge line1, Edge line2) - { - var s10X = line1.P2.X - line1.P1.X; - var s10Y = line1.P2.Y - line1.P1.Y; - var s32X = line2.P2.X - line2.P1.X; - var s32Y = line2.P2.Y - line2.P1.Y; - - var denom = s10X * s32Y - s32X * s10Y; - if (denom.IsEqual(0)) { - return null; - } - - var s02X = line1.P1.X - line2.P1.X; - var s02Y = line1.P1.Y - line2.P1.Y; - var sNumer = s10X * s02Y - s10Y * s02X; - if ((sNumer < 0) == (denom > 0)) { - return null; - } - var tNumer = s32X * s02Y - s32Y * s02X; - if ((tNumer < 0) == (denom > 0)) { - return null; - } - if (((sNumer > denom) == (denom > 0)) || ((tNumer > denom) == (denom > 0))) { - return null; - } - var t = tNumer / denom; - - return new Point(line1.P1.X + t * s10X, line1.P1.Y + t * s10Y); - } - - /// <summary> - /// Computes the time interval for driving the given distance ds with the vehicle's current speed and the given acceleration. - /// If the distance ds can not be reached (i.e., the vehicle would halt before ds is reached) then the distance parameter is adjusted. - /// Returns a new operating point (a, ds, dt) - /// </summary> - /// <param name="currentSpeed">vehicle's current speed at the beginning of the simulation interval</param> - /// <param name="acceleration">vehicle's acceleration</param> - /// <param name="distance">absolute distance at the beginning of the simulation interval (can be 0)</param> - /// <param name="ds">distance to drive in the current simulation interval</param> - /// <returns>Operating point (a, ds, dt)</returns> - public static OperatingPoint ComputeTimeInterval(MeterPerSecond currentSpeed, MeterPerSquareSecond acceleration, - Meter distance, Meter ds) - { - if (!(ds > 0)) { - throw new VectoSimulationException("ds has to be greater than 0! ds: {0}", ds); - } - - var retVal = new OperatingPoint() { Acceleration = acceleration, SimulationDistance = ds }; - if (acceleration.IsEqual(0)) { - if (currentSpeed > 0) { - retVal.SimulationInterval = ds / currentSpeed; - return retVal; - } - //Log.Error("{2}: vehicle speed is {0}, acceleration is {1}", currentSpeed.Value(), acceleration.Value(), - // distance); - throw new VectoSimulationException( - "vehicle speed has to be > 0 if acceleration = 0! v: {0}, a: {1}, distance: {2}", currentSpeed.Value(), - acceleration.Value(), distance); - } - - // we need to accelerate / decelerate. solve quadratic equation... - // ds = acceleration / 2 * dt^2 + currentSpeed * dt => solve for dt - var solutions = QuadraticEquationSolver(acceleration.Value() / 2.0, currentSpeed.Value(), - -ds.Value()); - - if (solutions.Length == 0) { - // no real-valued solutions: acceleration is so negative that vehicle stops already before the required distance can be reached. - // adapt ds to the halting-point. - // t = v / a - var dt = currentSpeed / -acceleration; - - // s = a/2*t^2 + v*t - var stopDistance = acceleration / 2 * dt * dt + currentSpeed * dt; - - if (stopDistance.IsGreater(ds)) { - // just to cover everything - does not happen... - //Log.Error( - // "Could not find solution for computing required time interval to drive distance ds: {0}. currentSpeed: {1}, acceleration: {2}, stopDistance: {3}, distance: {4}", - // ds, currentSpeed, acceleration, stopDistance,distance); - throw new VectoSimulationException("Could not find solution for time-interval! ds: {0}, stopDistance: {1}", ds, - stopDistance); - } - - //LoggingObject.Logger<>().Info( - // "Adjusted distance when computing time interval: currentSpeed: {0}, acceleration: {1}, distance: {2} -> {3}, timeInterval: {4}", - // currentSpeed, acceleration, stopDistance, stopDistance, dt); - - retVal.SimulationInterval = dt; - retVal.SimulationDistance = stopDistance; - return retVal; - } - // if there are 2 positive solutions (i.e. when decelerating), take the smaller time interval - // (the second solution means that you reach negative speed) - retVal.SimulationInterval = solutions.Where(x => x >= 0).Min().SI<Second>(); - return retVal; - } - - [DebuggerStepThrough] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Ceiling<T>(T si) where T : SIBase<T> - { - return Math.Ceiling(si.Value()).SI<T>(); - } - - public static double[] CubicEquationSolver(double a, double b, double c, double d) - { - var solutions = new List<double>(); - if (a.IsEqual(0, 1e-12)) { - return QuadraticEquationSolver(b, c, d); - } - var w = b / (3 * a); - var p = Math.Pow(c / (3 * a) - w * w, 3); - var q = -0.5 * (2 * (w * w * w) - (c * w - d) / a); - var discriminant = q * q + p; - if (discriminant < 0.0) { - // 3 real solutions - var h = q / Math.Sqrt(-p); - var phi = Math.Acos(Math.Max(-1.0, Math.Min(1.0, h))); - p = 2 * Math.Pow(-p, 1.0 / 6.0); - for (var i = 0; i < 3; i++) { - solutions.Add(p * Math.Cos((phi + 2 * i * Math.PI) / 3.0) - w); - } - } else { - // one real solution - discriminant = Math.Sqrt(discriminant); - solutions.Add(Cbrt(q + discriminant) + Cbrt(q - discriminant) - w); - } - - // 1 Newton iteration step in order to minimize round-off errors - for (var i = 0; i < solutions.Count; i++) { - var h = c + solutions[i] * (2 * b + 3 * solutions[i] * a); - if (!h.IsEqual(0, 1e-12)) { - solutions[i] -= (d + solutions[i] * (c + solutions[i] * (b + solutions[i] * a))) / h; - } - } - solutions.Sort(); - return solutions.ToArray(); - } - - private static double Cbrt(double x) - { - return x < 0 ? -Math.Pow(-x, 1.0 / 3.0) : Math.Pow(x, 1.0 / 3.0); - } - - - public static void LeastSquaresFitting<T>(IEnumerable<T> entries, Func<T, double> getX, Func<T, double> getY, - out double k, out double d, out double r) - { - // algoritm taken from http://mathworld.wolfram.com/LeastSquaresFitting.html (eqn. 27 & 28) - var count = 0; - var sumX = 0.0; - var sumY = 0.0; - var sumXSquare = 0.0; - var sumYSquare = 0.0; - var sumXY = 0.0; - foreach (var entry in entries) { - var x = getX(entry); - var y = getY(entry); - sumX += x; - sumY += y; - sumXSquare += x * x; - sumYSquare += y * y; - sumXY += x * y; - count++; - } - if (count == 0) { - k = 0; - d = 0; - r = 0; - return; - } - var ssxx = sumXSquare - sumX * sumX / count; - var ssxy = sumXY - sumX * sumY / count; - var ssyy = sumYSquare - sumY * sumY / count; - k = ssxy / ssxx; - d = (sumY - k * sumX) / count; - r = ssxy * ssxy / ssxx / ssyy; - } - } - - [DebuggerDisplay("(X:{X}, Y:{Y}, Z:{Z})")] - public class Point - { - public readonly double X; - public readonly double Y; - public readonly double Z; - - public Point(double x, double y, double z = 0) - { - X = x; - Y = y; - Z = z; - } - - public static Point operator +(Point p1, Point p2) - { - return new Point(p1.X + p2.X, p1.Y + p2.Y, p1.Z + p2.Z); - } - - public static Point operator -(Point p1, Point p2) - { - return new Point(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z); - } - - public static Point operator -(Point p1) - { - return new Point(-p1.X, -p1.Y); - } - - public static Point operator *(Point p1, double scalar) - { - return new Point(p1.X * scalar, p1.Y * scalar, p1.Z * scalar); - } - - public static Point operator *(double scalar, Point p1) - { - return p1 * scalar; - } - - /// <summary> - /// Returns perpendicular vector for xy-components of this point. P = (-Y, X) - /// </summary> - /// <returns></returns> - public Point Perpendicular() - { - return new Point(-Y, X); - } - - /// <summary> - /// Returns dot product between two 3d-vectors. - /// </summary> - /// <param name="other"></param> - /// <returns></returns> - public double Dot(Point other) - { - return X * other.X + Y * other.Y + Z * other.Z; - } - - #region Equality members - - private bool Equals(Point other) - { - return X.IsEqual(other.X) && Y.IsEqual(other.Y) && Z.IsEqual(other.Z); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - return obj.GetType() == GetType() && Equals((Point)obj); - } - - public override int GetHashCode() - { - return unchecked((((X.GetHashCode() * 397) ^ Y.GetHashCode()) * 397) ^ Z.GetHashCode()); - } - - #endregion - - /// <summary> - /// Test if point is on the left side of an edge. - /// </summary> - /// <param name="e"></param> - /// <returns></returns> - public bool IsLeftOf(Edge e) - { - var abX = e.P2.X - e.P1.X; - var abY = e.P2.Y - e.P1.Y; - var acX = X - e.P1.X; - var acY = Y - e.P1.Y; - var z = abX * acY - abY * acX; - return z.IsGreater(0); - } - } - - [DebuggerDisplay("Plane({X}, {Y}, {Z}, {W})")] - public class Plane - { - public readonly double X; - public readonly double Y; - public readonly double Z; - public readonly double W; - - public Plane(Triangle tr) - { - var abX = tr.P2.X - tr.P1.X; - var abY = tr.P2.Y - tr.P1.Y; - var abZ = tr.P2.Z - tr.P1.Z; - - var acX = tr.P3.X - tr.P1.X; - var acY = tr.P3.Y - tr.P1.Y; - var acZ = tr.P3.Z - tr.P1.Z; - - X = abY * acZ - abZ * acY; - Y = abZ * acX - abX * acZ; - Z = abX * acY - abY * acX; - W = tr.P1.X * X + tr.P1.Y * Y + tr.P1.Z * Z; - } - } - - [DebuggerDisplay("Triangle(({P1.X}, {P1.Y}, {P1.Z}), ({P2.X}, {P2.Y}, {P2.Z}), ({P3.X}, {P3.Y}, {P3.Z}))")] - public class Triangle - { - public readonly Point P1; - public readonly Point P2; - public readonly Point P3; - - public Triangle(Point p1, Point p2, Point p3) - { - P1 = p1; - P2 = p2; - P3 = p3; - - if ((P1.X.IsEqual(P2.X) && P2.X.IsEqual(P3.X)) || (P1.Y.IsEqual(P2.Y) && P2.Y.IsEqual(P3.Y))) { - throw new VectoException("triangle is not extrapolatable by a plane."); - } - } - - /// <summary> - /// Check if Point is inside of Triangle. Barycentric Technique: http://www.blackpawn.com/texts/pointinpoly/default.html - /// </summary> - public bool IsInside(double x, double y, bool exact) - { - var smallerY = y - DoubleExtensionMethods.Tolerance; - var biggerY = y + DoubleExtensionMethods.Tolerance; - var smallerX = x - DoubleExtensionMethods.Tolerance; - var biggerX = x + DoubleExtensionMethods.Tolerance; - - if ((P1.Y < smallerY && P2.Y < smallerY && P3.Y < smallerY) - || (P1.X < smallerX && P2.X < smallerX && P3.X < smallerX) - || (P1.X > biggerX && P2.X > biggerX && P3.X > biggerX) - || (P1.Y > biggerY && P2.Y > biggerY && P3.Y > biggerY)) { - return false; - } - - var v0X = P3.X - P1.X; - var v0Y = P3.Y - P1.Y; - var v1X = P2.X - P1.X; - var v1Y = P2.Y - P1.Y; - var v2X = x - P1.X; - var v2Y = y - P1.Y; - - var dot00 = v0X * v0X + v0Y * v0Y; - var dot01 = v0X * v1X + v0Y * v1Y; - var dot02 = v0X * v2X + v0Y * v2Y; - var dot11 = v1X * v1X + v1Y * v1Y; - var dot12 = v1X * v2X + v1Y * v2Y; - - var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - if (exact) { - return u >= 0 && v >= 0 && u + v <= 1; - } - - return u.IsPositive() && v.IsPositive() && (u + v).IsSmallerOrEqual(1); - } - - public bool ContainsInCircumcircle(Point p) - { - var p0X = P1.X - p.X; - var p0Y = P1.Y - p.Y; - var p1X = P2.X - p.X; - var p1Y = P2.Y - p.Y; - var p2X = P3.X - p.X; - var p2Y = P3.Y - p.Y; - - var p0Square = p0X * p0X + p0Y * p0Y; - var p1Square = p1X * p1X + p1Y * p1Y; - var p2Square = p2X * p2X + p2Y * p2Y; - - var det01 = p0X * p1Y - p1X * p0Y; - var det12 = p1X * p2Y - p2X * p1Y; - var det20 = p2X * p0Y - p0X * p2Y; - - var result = p0Square * det12 + p1Square * det20 + p2Square * det01; - return result > 0; - } - - public bool Contains(Point p) - { - return p.Equals(P1) || p.Equals(P2) || p.Equals(P3); - } - - public bool SharesVertexWith(Triangle t) - { - return Contains(t.P1) || Contains(t.P2) || Contains(t.P3); - } - - public IEnumerable<Edge> GetEdges() - { - return new[] { new Edge(P1, P2), new Edge(P2, P3), new Edge(P3, P1) }; - } - - #region Equality members - - protected bool Equals(Triangle other) - { - return Equals(P1, other.P1) && Equals(P2, other.P2) && Equals(P3, other.P3); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != GetType()) { - return false; - } - return Equals((Triangle)obj); - } - - public override int GetHashCode() - { - unchecked { - var hashCode = P1.GetHashCode(); - hashCode = (hashCode * 397) ^ P2.GetHashCode(); - hashCode = (hashCode * 397) ^ P3.GetHashCode(); - return hashCode; - } - } - - #endregion - } - - [DebuggerDisplay("Edge(({P1.X}, {P1.Y},{P1.Z}), ({P2.X}, {P2.Y},{P2.Z}))")] - public class Edge - { - public readonly Point P1; - public readonly Point P2; - - private Point _vector; - - public Edge(Point p1, Point p2) - { - P1 = p1; - P2 = p2; - } - - public Point Vector - { - get { return _vector ?? (_vector = P2 - P1); } - } - - public double SlopeXY - { - get { return Vector.Y / Vector.X; } - } - - public double OffsetXY - { - get { return P2.Y - SlopeXY * P2.X; } - } - - #region Equality members - - protected bool Equals(Edge other) - { - return (P1.Equals(other.P1) && Equals(P2, other.P2)) || (P1.Equals(other.P2) && P2.Equals(other.P1)); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - return obj.GetType() == GetType() && Equals((Edge)obj); - } - - public override int GetHashCode() - { - return P1.GetHashCode() ^ P2.GetHashCode(); - } - - #endregion - - public static Edge Create(Point arg1, Point arg2) - { - return new Edge(arg1, arg2); - } - - public bool ContainsXY(Point point) - { - return (SlopeXY * point.X + (P1.Y - SlopeXY * P1.X) - point.Y).IsEqual(0, 1E-9); - } - } +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; + +namespace TUGraz.VectoCommon.Utils +{ + /// <summary> + /// Provides helper methods for mathematical functions. + /// </summary> + public static class VectoMath + { + /// <summary> + /// Linearly interpolates a value between two points. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <typeparam name="TResult">The type of the result.</typeparam> + /// <param name="x1">First Value on the X-Axis.</param> + /// <param name="x2">Second Value on the X-Axis.</param> + /// <param name="y1">First Value on the Y-Axis.</param> + /// <param name="y2">Second Value on the Y-Axis.</param> + /// <param name="xint">Value on the X-Axis, for which the Y-Value should be interpolated.</param> + /// <returns></returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TResult Interpolate<T, TResult>(T x1, T x2, TResult y1, TResult y2, T xint) where T : SI + where TResult : SIBase<TResult> + { + return Interpolate(x1.Value(), x2.Value(), y1.Value(), y2.Value(), xint.Value()).SI<TResult>(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TResult Interpolate<TInput, T, TResult>(this Tuple<TInput, TInput> self, Func<TInput, T> x, + Func<TInput, TResult> y, T xInterpolate) + where T : SIBase<T> + where TResult : SIBase<TResult> + { + return Interpolate(x(self.Item1).Value(), x(self.Item2).Value(), y(self.Item1).Value(), y(self.Item2).Value(), + xInterpolate.Value()).SI<TResult>(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TResult Interpolate<TInput, TResult>(this Tuple<TInput, TInput> self, Func<TInput, double> x, + Func<TInput, TResult> y, double xInterpolate) + where TResult : SIBase<TResult> + { + return + Interpolate(x(self.Item1), x(self.Item2), y(self.Item1).Value(), y(self.Item2).Value(), xInterpolate).SI<TResult>(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TResult Interpolate<TInput, TResult>(this IEnumerable<TInput> self, Func<TInput, double> x, + Func<TInput, TResult> y, double xInterpolate) + where TResult : SIBase<TResult> + { + return self.GetSection(elem => x(elem) < xInterpolate).Interpolate(x, y, xInterpolate); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Interpolate<TInput>(this IEnumerable<TInput> self, Func<TInput, double> x, + Func<TInput, double> y, double xInterpolate) + { + return self.GetSection(elem => x(elem) < xInterpolate).Interpolate(x, y, xInterpolate); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Interpolate<TInput>(this Tuple<TInput, TInput> self, Func<TInput, double> x, + Func<TInput, double> y, double xInterpolate) + { + return Interpolate(x(self.Item1), x(self.Item2), y(self.Item1), y(self.Item2), xInterpolate); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Interpolate<T>(T x1, T x2, double y1, double y2, T xint) where T : SI + { + return Interpolate(x1.Value(), x2.Value(), y1, y2, xint.Value()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TResult Interpolate<TResult>(double x1, double x2, TResult y1, TResult y2, double xint) + where TResult : SIBase<TResult> + { + return Interpolate(x1, x2, y1.Value(), y2.Value(), xint).SI<TResult>(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Interpolate(Point p1, Point p2, double x) + { + return Interpolate(p1.X, p2.X, p1.Y, p2.Y, x); + } + + /// <summary> + /// Linearly interpolates a value between two points. + /// </summary> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Interpolate(double x1, double x2, double y1, double y2, double xint) + { + return (xint - x1) * (y2 - y1) / (x2 - x1) + y1; + } + + /// <summary> + /// Returns the absolute value. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SI Abs(SI si) + { + return si.Abs(); + } + + /// <summary> + /// Returns the minimum of two values. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Min<T>(T c1, T c2) where T : IComparable + { + if (c1 == null) { + return c2; + } + + if (c2 == null) { + return c1; + } + + return c1.CompareTo(c2) <= 0 ? c1 : c2; + } + + /// <summary> + /// Returns the maximum of two values. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Max<T>(T c1, T c2) where T : IComparable + { + return c1.CompareTo(c2) > 0 ? c1 : c2; + } + + /// <summary> + /// Returns the maximum of two values. + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Max<T>(double c1, T c2) where T : SIBase<T> + { + return c1 > c2.Value() ? c1.SI<T>() : c2; + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Max<T>(T c1, T c2, T c3) where T : SIBase<T> + { + return Max(Max(c1, c2), c3); + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T LimitTo<T>(this T value, T lowerBound, T upperBound) where T : IComparable + { + if (lowerBound.CompareTo(upperBound) > 0) { + throw new VectoException( + "VectoMath.LimitTo: lowerBound must not be greater than upperBound. lowerBound: {0}, upperBound: {1}", lowerBound, + upperBound); + } + + if (value.CompareTo(upperBound) > 0) { + return upperBound; + } + + if (value.CompareTo(lowerBound) < 0) { + return lowerBound; + } + + return value; + } + + /// <summary> + /// converts the given inclination in percent (0-1+) into Radians + /// </summary> + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Radian InclinationToAngle(double inclinationPercent) + { + return Math.Atan(inclinationPercent).SI<Radian>(); + } + + public static double[] QuadraticEquationSolver(double a, double b, double c) + { + var d = b * b - 4 * a * c; + + // no real solution + if (d < 0) { + return new double[0]; + } + + if (d > 0) { + // two solutions + return new[] { (-b + Math.Sqrt(d)) / (2 * a), (-b - Math.Sqrt(d)) / (2 * a) }; + } + + // one real solution + return new[] { -b / (2 * a) }; + } + + public static Point Intersect(Edge line1, Edge line2) + { + var s10X = line1.P2.X - line1.P1.X; + var s10Y = line1.P2.Y - line1.P1.Y; + var s32X = line2.P2.X - line2.P1.X; + var s32Y = line2.P2.Y - line2.P1.Y; + + var denom = s10X * s32Y - s32X * s10Y; + if (denom.IsEqual(0)) { + return null; + } + + var s02X = line1.P1.X - line2.P1.X; + var s02Y = line1.P1.Y - line2.P1.Y; + var sNumer = s10X * s02Y - s10Y * s02X; + if ((sNumer < 0) == (denom > 0)) { + return null; + } + var tNumer = s32X * s02Y - s32Y * s02X; + if ((tNumer < 0) == (denom > 0)) { + return null; + } + if (((sNumer > denom) == (denom > 0)) || ((tNumer > denom) == (denom > 0))) { + return null; + } + var t = tNumer / denom; + + return new Point(line1.P1.X + t * s10X, line1.P1.Y + t * s10Y); + } + + /// <summary> + /// Computes the time interval for driving the given distance ds with the vehicle's current speed and the given acceleration. + /// If the distance ds can not be reached (i.e., the vehicle would halt before ds is reached) then the distance parameter is adjusted. + /// Returns a new operating point (a, ds, dt) + /// </summary> + /// <param name="currentSpeed">vehicle's current speed at the beginning of the simulation interval</param> + /// <param name="acceleration">vehicle's acceleration</param> + /// <param name="distance">absolute distance at the beginning of the simulation interval (can be 0)</param> + /// <param name="ds">distance to drive in the current simulation interval</param> + /// <returns>Operating point (a, ds, dt)</returns> + public static OperatingPoint ComputeTimeInterval(MeterPerSecond currentSpeed, MeterPerSquareSecond acceleration, + Meter distance, Meter ds) + { + if (!(ds > 0)) { + throw new VectoSimulationException("ds has to be greater than 0! ds: {0}", ds); + } + + var retVal = new OperatingPoint() { Acceleration = acceleration, SimulationDistance = ds }; + if (acceleration.IsEqual(0)) { + if (currentSpeed > 0) { + retVal.SimulationInterval = ds / currentSpeed; + return retVal; + } + //Log.Error("{2}: vehicle speed is {0}, acceleration is {1}", currentSpeed.Value(), acceleration.Value(), + // distance); + throw new VectoSimulationException( + "vehicle speed has to be > 0 if acceleration = 0! v: {0}, a: {1}, distance: {2}", currentSpeed.Value(), + acceleration.Value(), distance); + } + + // we need to accelerate / decelerate. solve quadratic equation... + // ds = acceleration / 2 * dt^2 + currentSpeed * dt => solve for dt + var solutions = QuadraticEquationSolver(acceleration.Value() / 2.0, currentSpeed.Value(), + -ds.Value()); + + if (solutions.Length == 0) { + // no real-valued solutions: acceleration is so negative that vehicle stops already before the required distance can be reached. + // adapt ds to the halting-point. + // t = v / a + var dt = currentSpeed / -acceleration; + + // s = a/2*t^2 + v*t + var stopDistance = acceleration / 2 * dt * dt + currentSpeed * dt; + + if (stopDistance.IsGreater(ds)) { + // just to cover everything - does not happen... + //Log.Error( + // "Could not find solution for computing required time interval to drive distance ds: {0}. currentSpeed: {1}, acceleration: {2}, stopDistance: {3}, distance: {4}", + // ds, currentSpeed, acceleration, stopDistance,distance); + throw new VectoSimulationException("Could not find solution for time-interval! ds: {0}, stopDistance: {1}", ds, + stopDistance); + } + + //LoggingObject.Logger<>().Info( + // "Adjusted distance when computing time interval: currentSpeed: {0}, acceleration: {1}, distance: {2} -> {3}, timeInterval: {4}", + // currentSpeed, acceleration, stopDistance, stopDistance, dt); + + retVal.SimulationInterval = dt; + retVal.SimulationDistance = stopDistance; + return retVal; + } + // if there are 2 positive solutions (i.e. when decelerating), take the smaller time interval + // (the second solution means that you reach negative speed) + retVal.SimulationInterval = solutions.Where(x => x >= 0).Min().SI<Second>(); + return retVal; + } + + [DebuggerStepThrough] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Ceiling<T>(T si) where T : SIBase<T> + { + return Math.Ceiling(si.Value()).SI<T>(); + } + + public static double[] CubicEquationSolver(double a, double b, double c, double d) + { + var solutions = new List<double>(); + if (a.IsEqual(0, 1e-12)) { + return QuadraticEquationSolver(b, c, d); + } + var w = b / (3 * a); + var p = Math.Pow(c / (3 * a) - w * w, 3); + var q = -0.5 * (2 * (w * w * w) - (c * w - d) / a); + var discriminant = q * q + p; + if (discriminant < 0.0) { + // 3 real solutions + var h = q / Math.Sqrt(-p); + var phi = Math.Acos(Math.Max(-1.0, Math.Min(1.0, h))); + p = 2 * Math.Pow(-p, 1.0 / 6.0); + for (var i = 0; i < 3; i++) { + solutions.Add(p * Math.Cos((phi + 2 * i * Math.PI) / 3.0) - w); + } + } else { + // one real solution + discriminant = Math.Sqrt(discriminant); + solutions.Add(Cbrt(q + discriminant) + Cbrt(q - discriminant) - w); + } + + // 1 Newton iteration step in order to minimize round-off errors + for (var i = 0; i < solutions.Count; i++) { + var h = c + solutions[i] * (2 * b + 3 * solutions[i] * a); + if (!h.IsEqual(0, 1e-12)) { + solutions[i] -= (d + solutions[i] * (c + solutions[i] * (b + solutions[i] * a))) / h; + } + } + solutions.Sort(); + return solutions.ToArray(); + } + + private static double Cbrt(double x) + { + return x < 0 ? -Math.Pow(-x, 1.0 / 3.0) : Math.Pow(x, 1.0 / 3.0); + } + + + public static void LeastSquaresFitting<T>(IEnumerable<T> entries, Func<T, double> getX, Func<T, double> getY, + out double k, out double d, out double r) + { + // algoritm taken from http://mathworld.wolfram.com/LeastSquaresFitting.html (eqn. 27 & 28) + var count = 0; + var sumX = 0.0; + var sumY = 0.0; + var sumXSquare = 0.0; + var sumYSquare = 0.0; + var sumXY = 0.0; + foreach (var entry in entries) { + var x = getX(entry); + var y = getY(entry); + sumX += x; + sumY += y; + sumXSquare += x * x; + sumYSquare += y * y; + sumXY += x * y; + count++; + } + if (count == 0) { + k = 0; + d = 0; + r = 0; + return; + } + var ssxx = sumXSquare - sumX * sumX / count; + var ssxy = sumXY - sumX * sumY / count; + var ssyy = sumYSquare - sumY * sumY / count; + k = ssxy / ssxx; + d = (sumY - k * sumX) / count; + r = ssxy * ssxy / ssxx / ssyy; + } + } + + [DebuggerDisplay("(X:{X}, Y:{Y}, Z:{Z})")] + public class Point + { + public readonly double X; + public readonly double Y; + public readonly double Z; + + public Point(double x, double y, double z = 0) + { + X = x; + Y = y; + Z = z; + } + + public static Point operator +(Point p1, Point p2) + { + return new Point(p1.X + p2.X, p1.Y + p2.Y, p1.Z + p2.Z); + } + + public static Point operator -(Point p1, Point p2) + { + return new Point(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z); + } + + public static Point operator -(Point p1) + { + return new Point(-p1.X, -p1.Y); + } + + public static Point operator *(Point p1, double scalar) + { + return new Point(p1.X * scalar, p1.Y * scalar, p1.Z * scalar); + } + + public static Point operator *(double scalar, Point p1) + { + return p1 * scalar; + } + + /// <summary> + /// Returns perpendicular vector for xy-components of this point. P = (-Y, X) + /// </summary> + /// <returns></returns> + public Point Perpendicular() + { + return new Point(-Y, X); + } + + /// <summary> + /// Returns dot product between two 3d-vectors. + /// </summary> + /// <param name="other"></param> + /// <returns></returns> + public double Dot(Point other) + { + return X * other.X + Y * other.Y + Z * other.Z; + } + + #region Equality members + + private bool Equals(Point other) + { + return X.IsEqual(other.X) && Y.IsEqual(other.Y) && Z.IsEqual(other.Z); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) { + return false; + } + return obj.GetType() == GetType() && Equals((Point)obj); + } + + public override int GetHashCode() + { + return unchecked((((X.GetHashCode() * 397) ^ Y.GetHashCode()) * 397) ^ Z.GetHashCode()); + } + + #endregion + + /// <summary> + /// Test if point is on the left side of an edge. + /// </summary> + /// <param name="e"></param> + /// <returns></returns> + public bool IsLeftOf(Edge e) + { + var abX = e.P2.X - e.P1.X; + var abY = e.P2.Y - e.P1.Y; + var acX = X - e.P1.X; + var acY = Y - e.P1.Y; + var z = abX * acY - abY * acX; + return z.IsGreater(0); + } + } + + [DebuggerDisplay("Plane({X}, {Y}, {Z}, {W})")] + public class Plane + { + public readonly double X; + public readonly double Y; + public readonly double Z; + public readonly double W; + + public Plane(Triangle tr) + { + var abX = tr.P2.X - tr.P1.X; + var abY = tr.P2.Y - tr.P1.Y; + var abZ = tr.P2.Z - tr.P1.Z; + + var acX = tr.P3.X - tr.P1.X; + var acY = tr.P3.Y - tr.P1.Y; + var acZ = tr.P3.Z - tr.P1.Z; + + X = abY * acZ - abZ * acY; + Y = abZ * acX - abX * acZ; + Z = abX * acY - abY * acX; + W = tr.P1.X * X + tr.P1.Y * Y + tr.P1.Z * Z; + } + } + + [DebuggerDisplay("Triangle(({P1.X}, {P1.Y}, {P1.Z}), ({P2.X}, {P2.Y}, {P2.Z}), ({P3.X}, {P3.Y}, {P3.Z}))")] + public class Triangle + { + public readonly Point P1; + public readonly Point P2; + public readonly Point P3; + + public Triangle(Point p1, Point p2, Point p3) + { + P1 = p1; + P2 = p2; + P3 = p3; + + if ((P1.X.IsEqual(P2.X) && P2.X.IsEqual(P3.X)) || (P1.Y.IsEqual(P2.Y) && P2.Y.IsEqual(P3.Y))) { + throw new VectoException("triangle is not extrapolatable by a plane."); + } + } + + /// <summary> + /// Check if Point is inside of Triangle. Barycentric Technique: http://www.blackpawn.com/texts/pointinpoly/default.html + /// </summary> + public bool IsInside(double x, double y, bool exact) + { + var smallerY = y - DoubleExtensionMethods.Tolerance; + var biggerY = y + DoubleExtensionMethods.Tolerance; + var smallerX = x - DoubleExtensionMethods.Tolerance; + var biggerX = x + DoubleExtensionMethods.Tolerance; + + var aboveTriangle = P1.Y < smallerY && P2.Y < smallerY && P3.Y < smallerY; + var belowTriangle = P1.Y > biggerY && P2.Y > biggerY && P3.Y > biggerY; + var leftOfTriangle = P1.X > biggerX && P2.X > biggerX && P3.X > biggerX; + var rightOfTriangle = P1.X < smallerX && P2.X < smallerX && P3.X < smallerX; + + if (aboveTriangle || rightOfTriangle || leftOfTriangle || belowTriangle) { + return false; + } + + var v0X = P3.X - P1.X; + var v0Y = P3.Y - P1.Y; + var v1X = P2.X - P1.X; + var v1Y = P2.Y - P1.Y; + var v2X = x - P1.X; + var v2Y = y - P1.Y; + + var dot00 = v0X * v0X + v0Y * v0Y; + var dot01 = v0X * v1X + v0Y * v1Y; + var dot02 = v0X * v2X + v0Y * v2Y; + var dot11 = v1X * v1X + v1Y * v1Y; + var dot12 = v1X * v2X + v1Y * v2Y; + + var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + if (exact) { + return u >= 0 && v >= 0 && u + v <= 1; + } + + return u.IsPositive() && v.IsPositive() && (u + v).IsSmallerOrEqual(1); + } + + public bool ContainsInCircumcircle(Point p) + { + var p0X = P1.X - p.X; + var p0Y = P1.Y - p.Y; + var p1X = P2.X - p.X; + var p1Y = P2.Y - p.Y; + var p2X = P3.X - p.X; + var p2Y = P3.Y - p.Y; + + var p0Square = p0X * p0X + p0Y * p0Y; + var p1Square = p1X * p1X + p1Y * p1Y; + var p2Square = p2X * p2X + p2Y * p2Y; + + var det01 = p0X * p1Y - p1X * p0Y; + var det12 = p1X * p2Y - p2X * p1Y; + var det20 = p2X * p0Y - p0X * p2Y; + + var result = p0Square * det12 + p1Square * det20 + p2Square * det01; + return result > 0; + } + + public bool Contains(Point p) + { + return p.Equals(P1) || p.Equals(P2) || p.Equals(P3); + } + + public bool SharesVertexWith(Triangle t) + { + return Contains(t.P1) || Contains(t.P2) || Contains(t.P3); + } + + public IEnumerable<Edge> GetEdges() + { + return new[] { new Edge(P1, P2), new Edge(P2, P3), new Edge(P3, P1) }; + } + + #region Equality members + + protected bool Equals(Triangle other) + { + return Equals(P1, other.P1) && Equals(P2, other.P2) && Equals(P3, other.P3); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + if (obj.GetType() != GetType()) { + return false; + } + return Equals((Triangle)obj); + } + + public override int GetHashCode() + { + unchecked { + var hashCode = P1.GetHashCode(); + hashCode = (hashCode * 397) ^ P2.GetHashCode(); + hashCode = (hashCode * 397) ^ P3.GetHashCode(); + return hashCode; + } + } + + #endregion + } + + [DebuggerDisplay("Edge(({P1.X}, {P1.Y},{P1.Z}), ({P2.X}, {P2.Y},{P2.Z}))")] + public class Edge + { + public readonly Point P1; + public readonly Point P2; + + private Point _vector; + + public Edge(Point p1, Point p2) + { + P1 = p1; + P2 = p2; + } + + public Point Vector + { + get { return _vector ?? (_vector = P2 - P1); } + } + + public double SlopeXY + { + get { return Vector.Y / Vector.X; } + } + + public double OffsetXY + { + get { return P2.Y - SlopeXY * P2.X; } + } + + #region Equality members + + protected bool Equals(Edge other) + { + return (P1.Equals(other.P1) && Equals(P2, other.P2)) || (P1.Equals(other.P2) && P2.Equals(other.P1)); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + return obj.GetType() == GetType() && Equals((Edge)obj); + } + + public override int GetHashCode() + { + return P1.GetHashCode() ^ P2.GetHashCode(); + } + + #endregion + + public static Edge Create(Point arg1, Point arg2) + { + return new Edge(arg1, arg2); + } + + public bool ContainsXY(Point point) + { + return (SlopeXY * point.X + (P1.Y - SlopeXY * P1.X) - point.Y).IsEqual(0, 1E-9); + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/VectoCommon.csproj b/VectoCommon/VectoCommon/VectoCommon.csproj index c994ad974c018a6524114452fafb12fd69ebc6d0..1d91d423b391097d52a6f7a95579644a1aa93750 100644 --- a/VectoCommon/VectoCommon/VectoCommon.csproj +++ b/VectoCommon/VectoCommon/VectoCommon.csproj @@ -67,6 +67,7 @@ <Compile Include="Models\FuelType.cs" /> <Compile Include="Models\GearboxType.cs" /> <Compile Include="Models\IResponse.cs" /> + <Compile Include="Models\LegislativeClass.cs" /> <Compile Include="Models\LoggingObject.cs" /> <Compile Include="Models\OperatingPoint.cs" /> <Compile Include="Models\RetarderType.cs" /> diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs index 9e4d0f73b25843e4f22cecdf1fdf243531c1ba0e..0a23117745ed764a1d58c44c81354822c67c51ba 100644 --- a/VectoConsole/Program.cs +++ b/VectoConsole/Program.cs @@ -64,36 +64,36 @@ namespace VectoConsole private const string Usage = @"Usage: vectocmd.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; - private const string Help = @" -Commandline Interface for Vecto. - -Synopsis: - vectocmd.exe [-h] [-v] FILE1.(vecto|xml) [FILE2.(vecto|xml) ...] - -Description: - FILE1.vecto [FILE2.vecto ...]: A list of vecto-job files (with the - extension: .vecto). At least one file must be given. Delimited by - whitespace. - - -t: output information about execution times - -mod: write mod-data in addition to sum-data - -1Hz: convert mod-data to 1Hz resolution - -eng: switch to engineering mode (implies -mod) - -q: quiet - disables console output unless verbose information is enabled - -nv: skip validation of internal data structure before simulation - -v: Shows verbose information (errors and warnings will be displayed) - -vv: Shows more verbose information (infos will be displayed) - -vvv: Shows debug messages (slow!) - -vvvv: Shows all verbose information (everything, slow!) - -V: show version information - -h: Displays this help. - -Examples: - vecto.exe ""12t Delivery Truck.vecto"" 40t_Long_Haul_Truck.vecto - vecto.exe 24tCoach.vecto 40t_Long_Haul_Truck.vecto - vecto.exe -v 24tCoach.vecto - vecto.exe -v jobs\40t_Long_Haul_Truck.vecto - vecto.exe -h + private const string Help = @" +Commandline Interface for Vecto. + +Synopsis: + vectocmd.exe [-h] [-v] FILE1.(vecto|xml) [FILE2.(vecto|xml) ...] + +Description: + FILE1.vecto [FILE2.vecto ...]: A list of vecto-job files (with the + extension: .vecto). At least one file must be given. Delimited by + whitespace. + + -t: output information about execution times + -mod: write mod-data in addition to sum-data + -1Hz: convert mod-data to 1Hz resolution + -eng: switch to engineering mode (implies -mod) + -q: quiet - disables console output unless verbose information is enabled + -nv: skip validation of internal data structure before simulation + -v: Shows verbose information (errors and warnings will be displayed) + -vv: Shows more verbose information (infos will be displayed) + -vvv: Shows debug messages (slow!) + -vvvv: Shows all verbose information (everything, slow!) + -V: show version information + -h: Displays this help. + +Examples: + vecto.exe ""12t Delivery Truck.vecto"" 40t_Long_Haul_Truck.vecto + vecto.exe 24tCoach.vecto 40t_Long_Haul_Truck.vecto + vecto.exe -v 24tCoach.vecto + vecto.exe -v jobs\40t_Long_Haul_Truck.vecto + vecto.exe -h "; private static JobContainer _jobContainer; @@ -289,8 +289,9 @@ Examples: #if DEBUG Console.Error.WriteLine("done."); - if (!Console.IsInputRedirected) + if (!Console.IsInputRedirected) { Console.ReadKey(); + } #endif return Environment.ExitCode; } diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs index c31323bed471769f058132d46d28ceb7114923e3..53f64fc8c4ea957001a627be8194ec63a575b602 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs @@ -29,160 +29,160 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.IO; -using System.Xml.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.InputData.FileIO.JSON -{ - public class JSONComponentInputData : IEngineeringInputDataProvider, IDeclarationInputDataProvider - { - protected IGearboxEngineeringInputData Gearbox; - protected IAxleGearInputData AxleGear; - protected ITorqueConverterEngineeringInputData TorqueConverter; - protected IAngledriveInputData Angledrive; - protected IEngineEngineeringInputData Engine; - protected IVehicleEngineeringInputData VehicleData; - protected IRetarderInputData Retarder; - protected IPTOTransmissionInputData PTOTransmission; - private IAirdragEngineeringInputData AirdragData; - - - public JSONComponentInputData(string filename, bool tolerateMissing = false) - { - var extension = Path.GetExtension(filename); - object tmp = null; - switch (extension) { - case Constants.FileExtensions.VehicleDataFile: - tmp = JSONInputDataFactory.ReadJsonVehicle(filename, tolerateMissing); - break; - case Constants.FileExtensions.EngineDataFile: - tmp = JSONInputDataFactory.ReadEngine(filename, tolerateMissing); - break; - case Constants.FileExtensions.GearboxDataFile: - tmp = JSONInputDataFactory.ReadGearbox(filename, tolerateMissing); - break; - } - tmp.Switch() - .If<IVehicleEngineeringInputData>(c => VehicleData = c) - .If<IAirdragEngineeringInputData>(c => AirdragData = c) - .If<IEngineEngineeringInputData>(c => Engine = c) - .If<IGearboxEngineeringInputData>(c => Gearbox = c) - .If<IAxleGearInputData>(c => AxleGear = c) - .If<IRetarderInputData>(c => Retarder = c) - .If<ITorqueConverterEngineeringInputData>(c => TorqueConverter = c) - .If<IAngledriveInputData>(c => Angledrive = c) - .If<IPTOTransmissionInputData>(c => PTOTransmission = c); - } - - - public IEngineeringJobInputData JobInputData() - { - throw new NotImplementedException(); - } - - - IVehicleDeclarationInputData IDeclarationInputDataProvider.VehicleInputData - { - get { return VehicleData; } - } - - IAirdragDeclarationInputData IDeclarationInputDataProvider.AirdragInputData - { - get { return AirdragInputData; } - } - - public IAirdragEngineeringInputData AirdragInputData - { - get { return AirdragData; } - } - - IGearboxDeclarationInputData IDeclarationInputDataProvider.GearboxInputData - { - get { return GearboxInputData; } - } - - ITorqueConverterDeclarationInputData IDeclarationInputDataProvider.TorqueConverterInputData - { - get { return TorqueConverterInputData; } - } - - IDeclarationJobInputData IDeclarationInputDataProvider.JobInputData() - { - throw new NotImplementedException(); - } - - public IVehicleEngineeringInputData VehicleInputData - { - get { return VehicleData; } - } - - public IGearboxEngineeringInputData GearboxInputData - { - get { return Gearbox; } - } - - public ITorqueConverterEngineeringInputData TorqueConverterInputData - { - get { return TorqueConverter; } - } - - public IAxleGearInputData AxleGearInputData - { - get { return AxleGear; } - } - - public IAngledriveInputData AngledriveInputData - { - get { return Angledrive; } - } - - IEngineDeclarationInputData IDeclarationInputDataProvider.EngineInputData - { - get { return EngineInputData; } - } - - public IEngineEngineeringInputData EngineInputData - { - get { return Engine; } - } - - public IAuxiliariesEngineeringInputData AuxiliaryInputData() - { - throw new NotImplementedException(); - } - - IAuxiliariesDeclarationInputData IDeclarationInputDataProvider.AuxiliaryInputData() - { - throw new NotImplementedException(); - } - - public IRetarderInputData RetarderInputData - { - get { return Retarder; } - } - - IDriverDeclarationInputData IDeclarationInputDataProvider.DriverInputData - { - get { throw new NotImplementedException(); } - } - - public IDriverEngineeringInputData DriverInputData - { - get { throw new NotImplementedException(); } - } - - public IPTOTransmissionInputData PTOTransmissionInputData - { - get { return PTOTransmission; } - } - - public XElement XMLHash - { - get { return null; } - } - } +using System; +using System.IO; +using System.Xml.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.InputData.FileIO.JSON +{ + public class JSONComponentInputData : IEngineeringInputDataProvider, IDeclarationInputDataProvider + { + protected IGearboxEngineeringInputData Gearbox; + protected IAxleGearInputData AxleGear; + protected ITorqueConverterEngineeringInputData TorqueConverter; + protected IAngledriveInputData Angledrive; + protected IEngineEngineeringInputData Engine; + protected IVehicleEngineeringInputData VehicleData; + protected IRetarderInputData Retarder; + protected IPTOTransmissionInputData PTOTransmission; + private IAirdragEngineeringInputData AirdragData; + + + public JSONComponentInputData(string filename, bool tolerateMissing = false) + { + var extension = Path.GetExtension(filename); + object tmp = null; + switch (extension) { + case Constants.FileExtensions.VehicleDataFile: + tmp = JSONInputDataFactory.ReadJsonVehicle(filename, tolerateMissing); + break; + case Constants.FileExtensions.EngineDataFile: + tmp = JSONInputDataFactory.ReadEngine(filename, tolerateMissing); + break; + case Constants.FileExtensions.GearboxDataFile: + tmp = JSONInputDataFactory.ReadGearbox(filename, tolerateMissing); + break; + } + tmp.Switch() + .If<IVehicleEngineeringInputData>(c => VehicleData = c) + .If<IAirdragEngineeringInputData>(c => AirdragData = c) + .If<IEngineEngineeringInputData>(c => Engine = c) + .If<IGearboxEngineeringInputData>(c => Gearbox = c) + .If<IAxleGearInputData>(c => AxleGear = c) + .If<IRetarderInputData>(c => Retarder = c) + .If<ITorqueConverterEngineeringInputData>(c => TorqueConverter = c) + .If<IAngledriveInputData>(c => Angledrive = c) + .If<IPTOTransmissionInputData>(c => PTOTransmission = c); + } + + + public IEngineeringJobInputData JobInputData() + { + throw new NotImplementedException(); + } + + + IVehicleDeclarationInputData IDeclarationInputDataProvider.VehicleInputData + { + get { return VehicleData; } + } + + IAirdragDeclarationInputData IDeclarationInputDataProvider.AirdragInputData + { + get { return AirdragInputData; } + } + + public IAirdragEngineeringInputData AirdragInputData + { + get { return AirdragData; } + } + + IGearboxDeclarationInputData IDeclarationInputDataProvider.GearboxInputData + { + get { return GearboxInputData; } + } + + ITorqueConverterDeclarationInputData IDeclarationInputDataProvider.TorqueConverterInputData + { + get { return TorqueConverterInputData; } + } + + IDeclarationJobInputData IDeclarationInputDataProvider.JobInputData() + { + throw new NotImplementedException(); + } + + public IVehicleEngineeringInputData VehicleInputData + { + get { return VehicleData; } + } + + public IGearboxEngineeringInputData GearboxInputData + { + get { return Gearbox; } + } + + public ITorqueConverterEngineeringInputData TorqueConverterInputData + { + get { return TorqueConverter; } + } + + public IAxleGearInputData AxleGearInputData + { + get { return AxleGear; } + } + + public IAngledriveInputData AngledriveInputData + { + get { return Angledrive; } + } + + IEngineDeclarationInputData IDeclarationInputDataProvider.EngineInputData + { + get { return EngineInputData; } + } + + public IEngineEngineeringInputData EngineInputData + { + get { return Engine; } + } + + public IAuxiliariesEngineeringInputData AuxiliaryInputData() + { + throw new NotImplementedException(); + } + + IAuxiliariesDeclarationInputData IDeclarationInputDataProvider.AuxiliaryInputData() + { + throw new NotImplementedException(); + } + + public IRetarderInputData RetarderInputData + { + get { return Retarder; } + } + + IDriverDeclarationInputData IDeclarationInputDataProvider.DriverInputData + { + get { throw new NotImplementedException(); } + } + + public IDriverEngineeringInputData DriverInputData + { + get { throw new NotImplementedException(); } + } + + public IPTOTransmissionInputData PTOTransmissionInputData + { + get { return PTOTransmission; } + } + + public XElement XMLHash + { + get { return null; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs index bf8d8e57a5c19e2e4b8aaed3ac557377677a299c..d1cb4311b329be30216f3717c71a7d936d68dbfe 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs @@ -29,231 +29,231 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.IO; -using Newtonsoft.Json.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.InputData.FileIO.JSON -{ - /// <summary> - /// Represents the CombustionEngineData. Fileformat: .veng - /// </summary> - /// <code> - /// { - /// "Header": { - /// "CreatedBy": " ()", - /// "Date": "3/4/2015 12:26:24 PM", - /// "AppVersion": "2.0.4-beta3", - /// "FileVersion": 2 - /// }, - /// "Body": { - /// "SavedInDeclMode": false, - /// "ModelName": "Generic 24t Coach", - /// "Displacement": 12730.0, - /// "IdlingSpeed": 560.0, - /// "Inertia": 3.8, - /// "FullLoadCurves": [ - /// { - /// "Path": "24t Coach.vfld", - /// "Gears": "0 - 99" - /// } - /// ], - /// "FuelMap": "24t Coach.vmap", - /// "WHTC-Urban": 0.0, - /// "WHTC-Rural": 0.0, - /// "WHTC-Motorway": 0.0 - /// } - /// } - /// </code> - public class JSONEngineDataV4 : JSONEngineDataV3 - { - public JSONEngineDataV4(JObject data, string fileName, bool tolerateMissing = false) - : base(data, fileName, tolerateMissing) {} - - public override Watt RatedPowerDeclared - { - get { return Body.GetEx<double>("RatedPower").SI<Watt>(); } - } - - public override PerSecond RatedSpeedDeclared - { - get { return Body.GetEx<double>("RatedSpeed").RPMtoRad(); } - } - - public override NewtonMeter MaxTorqueDeclared - { - get { return Body.GetEx<double>("MaxTorque").SI<NewtonMeter>(); } - } - - public override double CorrectionFactorRegPer - { - get { return Body.GetEx<double>("CFRegPer"); } - } - - - public override double CorrectionFactorNCV - { - get { return Body.GetEx<double>("CFNCV"); } - } - - public override FuelType FuelType - { - get { return Body.GetEx<string>("FuelType").ParseEnum<FuelType>(); } - } - } - - - public class JSONEngineDataV3 : JSONFile, IEngineEngineeringInputData - { - public JSONEngineDataV3(JObject data, string fileName, bool tolerateMissing = false) - : base(data, fileName, tolerateMissing) {} - - public virtual CubicMeter Displacement - { - get { return Body.GetEx<double>(JsonKeys.Engine_Displacement).SI().Cubic.Centi.Meter.Cast<CubicMeter>(); } - // convert vom ccm to m^3} - } - - public virtual PerSecond IdleSpeed - { - get { return Body.GetEx<double>(JsonKeys.Engine_IdleSpeed).RPMtoRad(); } - } - - - public virtual FuelType FuelType - { - get { return FuelType.DieselCI; } - } - - public virtual TableData FuelConsumptionMap - { - get { - try { - return ReadTableData(Body.GetEx<string>(JsonKeys.Engine_FuelConsumptionMap), "FuelConsumptionMap"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return - new TableData(Path.Combine(BasePath, Body[JsonKeys.Engine_FuelConsumptionMap].ToString()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - - public virtual TableData FullLoadCurve - { - get { - try { - return ReadTableData(Body.GetEx<string>(JsonKeys.Engine_FullLoadCurveFile), "FullLoadCurve"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData( - Path.Combine(BasePath, Body[JsonKeys.Engine_FullLoadCurveFile].ToString()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - - public virtual Watt RatedPowerDeclared - { - get { return 0.SI<Watt>(); } - } - - public virtual PerSecond RatedSpeedDeclared - { - get { return 0.RPMtoRad(); } - } - - public virtual NewtonMeter MaxTorqueDeclared - { - get { return 0.SI<NewtonMeter>(); } - } - - public virtual KilogramSquareMeter Inertia - { - get { return Body.GetEx<double>(JsonKeys.Engine_Inertia).SI<KilogramSquareMeter>(); } - } - - public virtual double WHTCEngineering - { - get { - if (Body["WHTC-Engineering"] == null) { - return 1; - } - return Body.GetEx<double>("WHTC-Engineering"); - } - } - - public virtual double WHTCMotorway - { - get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Motorway); } - } - - public virtual double WHTCRural - { - get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Rural); } - } - - public virtual double WHTCUrban - { - get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Urban); } - } - - public double ColdHotBalancingFactor - { - get { - if (Body["ColdHotBalancingFactor"] == null) { - return 1.0; - } - return Body.GetEx<double>("ColdHotBalancingFactor"); - } - } - - public virtual double CorrectionFactorRegPer - { - get { return 1; } - } - - public virtual double CorrectionFactorNCV - { - get { return 1; } - } - - public string Manufacturer - { - get { return "N/A"; } - } - - public string Model - { - get { return Body.GetEx<string>(JsonKeys.Engine_ModelName); } - } - - - public string Date - { - get { return "N/A"; } - } - - public CertificationMethod CertificationMethod - { - get { return CertificationMethod.NotCertified; } - } - - public string CertificationNumber - { - get { return "N/A"; } - } - - public string DigestValue - { - get { return "N/A"; } - } - } +using System; +using System.IO; +using Newtonsoft.Json.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.InputData.FileIO.JSON +{ + /// <summary> + /// Represents the CombustionEngineData. Fileformat: .veng + /// </summary> + /// <code> + /// { + /// "Header": { + /// "CreatedBy": " ()", + /// "Date": "3/4/2015 12:26:24 PM", + /// "AppVersion": "2.0.4-beta3", + /// "FileVersion": 2 + /// }, + /// "Body": { + /// "SavedInDeclMode": false, + /// "ModelName": "Generic 24t Coach", + /// "Displacement": 12730.0, + /// "IdlingSpeed": 560.0, + /// "Inertia": 3.8, + /// "FullLoadCurves": [ + /// { + /// "Path": "24t Coach.vfld", + /// "Gears": "0 - 99" + /// } + /// ], + /// "FuelMap": "24t Coach.vmap", + /// "WHTC-Urban": 0.0, + /// "WHTC-Rural": 0.0, + /// "WHTC-Motorway": 0.0 + /// } + /// } + /// </code> + public class JSONEngineDataV4 : JSONEngineDataV3 + { + public JSONEngineDataV4(JObject data, string fileName, bool tolerateMissing = false) + : base(data, fileName, tolerateMissing) {} + + public override Watt RatedPowerDeclared + { + get { return Body.GetEx<double>("RatedPower").SI<Watt>(); } + } + + public override PerSecond RatedSpeedDeclared + { + get { return Body.GetEx<double>("RatedSpeed").RPMtoRad(); } + } + + public override NewtonMeter MaxTorqueDeclared + { + get { return Body.GetEx<double>("MaxTorque").SI<NewtonMeter>(); } + } + + public override double CorrectionFactorRegPer + { + get { return Body.GetEx<double>("CFRegPer"); } + } + + + public override double CorrectionFactorNCV + { + get { return Body.GetEx<double>("CFNCV"); } + } + + public override FuelType FuelType + { + get { return Body.GetEx<string>("FuelType").ParseEnum<FuelType>(); } + } + } + + + public class JSONEngineDataV3 : JSONFile, IEngineEngineeringInputData + { + public JSONEngineDataV3(JObject data, string fileName, bool tolerateMissing = false) + : base(data, fileName, tolerateMissing) {} + + public virtual CubicMeter Displacement + { + get { return Body.GetEx<double>(JsonKeys.Engine_Displacement).SI().Cubic.Centi.Meter.Cast<CubicMeter>(); } + // convert vom ccm to m^3} + } + + public virtual PerSecond IdleSpeed + { + get { return Body.GetEx<double>(JsonKeys.Engine_IdleSpeed).RPMtoRad(); } + } + + + public virtual FuelType FuelType + { + get { return FuelType.DieselCI; } + } + + public virtual TableData FuelConsumptionMap + { + get { + try { + return ReadTableData(Body.GetEx<string>(JsonKeys.Engine_FuelConsumptionMap), "FuelConsumptionMap"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return + new TableData(Path.Combine(BasePath, Body[JsonKeys.Engine_FuelConsumptionMap].ToString()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + + public virtual TableData FullLoadCurve + { + get { + try { + return ReadTableData(Body.GetEx<string>(JsonKeys.Engine_FullLoadCurveFile), "FullLoadCurve"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData( + Path.Combine(BasePath, Body[JsonKeys.Engine_FullLoadCurveFile].ToString()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + + public virtual Watt RatedPowerDeclared + { + get { return 0.SI<Watt>(); } + } + + public virtual PerSecond RatedSpeedDeclared + { + get { return 0.RPMtoRad(); } + } + + public virtual NewtonMeter MaxTorqueDeclared + { + get { return 0.SI<NewtonMeter>(); } + } + + public virtual KilogramSquareMeter Inertia + { + get { return Body.GetEx<double>(JsonKeys.Engine_Inertia).SI<KilogramSquareMeter>(); } + } + + public virtual double WHTCEngineering + { + get { + if (Body["WHTC-Engineering"] == null) { + return 1; + } + return Body.GetEx<double>("WHTC-Engineering"); + } + } + + public virtual double WHTCMotorway + { + get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Motorway); } + } + + public virtual double WHTCRural + { + get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Rural); } + } + + public virtual double WHTCUrban + { + get { return Body.GetEx<double>(JsonKeys.Engine_WHTC_Urban); } + } + + public double ColdHotBalancingFactor + { + get { + if (Body["ColdHotBalancingFactor"] == null) { + return 1.0; + } + return Body.GetEx<double>("ColdHotBalancingFactor"); + } + } + + public virtual double CorrectionFactorRegPer + { + get { return 1; } + } + + public virtual double CorrectionFactorNCV + { + get { return 1; } + } + + public string Manufacturer + { + get { return "N/A"; } + } + + public string Model + { + get { return Body.GetEx<string>(JsonKeys.Engine_ModelName); } + } + + + public string Date + { + get { return "N/A"; } + } + + public CertificationMethod CertificationMethod + { + get { return CertificationMethod.NotCertified; } + } + + public string CertificationNumber + { + get { return "N/A"; } + } + + public string DigestValue + { + get { return "N/A"; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs index b6b2f19eb55689a195e71e0aef3f912f0574eb1d..19d015b541a80c3718189125ec065210c939c25f 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs @@ -29,647 +29,679 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.InputData.FileIO.JSON -{ - public abstract class JSONFile : LoggingObject - { - public const string MissingFileSuffix = " -- (MISSING!)"; - - private readonly string _sourceFile; - - protected readonly JObject Body; - - protected JSONFile(JObject data, string filename, bool tolerateMissing = false) - { - //var header = (JObject)data.GetEx(JsonKeys.JsonHeader); - Body = (JObject)data.GetEx(JsonKeys.JsonBody); - _sourceFile = Path.GetFullPath(filename); - TolerateMissing = tolerateMissing; - } - - protected bool TolerateMissing { get; set; } - - public DataSourceType SourceType - { - get { return DataSourceType.JSONFile; } - } - - public string Source - { - get { return _sourceFile; } - } - - public bool SavedInDeclarationMode - { - get { return Body.GetEx(JsonKeys.SavedInDeclMode).Value<bool>(); } - } - - internal string BasePath - { - get { return Path.GetDirectoryName(_sourceFile); } - } - - protected TableData ReadTableData(string filename, string tableType, bool required = true) - { - if (!EmptyOrInvalidFileName(filename) && File.Exists(Path.Combine(BasePath, filename))) { - try { - return VectoCSVFile.Read(Path.Combine(BasePath, filename), true); - } catch (Exception e) { - Log.Warn("Failed to read file {0} {1}", Path.Combine(BasePath, filename), tableType); - throw new VectoException("Failed to read file for {0}: {1}", e, tableType, filename); - } - } - if (required) { - throw new VectoException("Invalid filename for {0}: {1}", tableType, filename); - } - return null; - } - - internal static bool EmptyOrInvalidFileName(string filename) - { - return filename == null || !filename.Any() || - filename.Equals("<NOFILE>", StringComparison.InvariantCultureIgnoreCase) - || filename.Equals("-"); - } - - public static JObject GetDummyJSONStructure() - { - return JObject.FromObject(new Dictionary<string, object>() { - { JsonKeys.JsonHeader, new object() }, - { JsonKeys.JsonBody, new object() } - }); - } - } - - /// <summary> - /// Class for reading json data of vecto-job-file. - /// Fileformat: .vecto - /// </summary> - public class JSONInputDataV2 : JSONFile, IEngineeringInputDataProvider, IDeclarationInputDataProvider, - IEngineeringJobInputData, IDriverEngineeringInputData, IAuxiliariesEngineeringInputData, - IAuxiliariesDeclarationInputData - { - protected readonly IGearboxEngineeringInputData Gearbox; - protected readonly IAxleGearInputData AxleGear; - protected readonly ITorqueConverterEngineeringInputData TorqueConverter; - protected readonly IAngledriveInputData Angledrive; - protected readonly IEngineEngineeringInputData Engine; - protected readonly IVehicleEngineeringInputData VehicleData; - protected readonly IRetarderInputData Retarder; - protected readonly IPTOTransmissionInputData PTOTransmission; - - private readonly string _jobname; - protected internal IAirdragEngineeringInputData AirdragData; - - public JSONInputDataV2(JObject data, string filename, bool tolerateMissing = false) - : base(data, filename, tolerateMissing) - { - _jobname = Path.GetFileNameWithoutExtension(filename); - - Engine = ReadEngine(); - - if (Body.GetEx(JsonKeys.Job_EngineOnlyMode).Value<bool>()) { - return; - } - - Gearbox = ReadGearbox(); - AxleGear = Gearbox as IAxleGearInputData; - TorqueConverter = Gearbox as ITorqueConverterEngineeringInputData; - - VehicleData = ReadVehicle(); - Angledrive = VehicleData as IAngledriveInputData; - Retarder = VehicleData as IRetarderInputData; - PTOTransmission = VehicleData as IPTOTransmissionInputData; - AirdragData = VehicleData as IAirdragEngineeringInputData; - } - - private IVehicleEngineeringInputData ReadVehicle() - { - try { - var vehicleFile = Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>(); - return JSONInputDataFactory.ReadJsonVehicle( - Path.Combine(BasePath, vehicleFile)); - } catch (Exception e) { - if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Vehicle file '{0}': {1}", e, Body[JsonKeys.Vehicle_VehicleFile], - e.Message); - } - return new JSONVehicleDataV7(GetDummyJSONStructure(), - Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>()) + MissingFileSuffix); - } - } - - private IGearboxEngineeringInputData ReadGearbox() - { - try { - var gearboxFile = Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>(); - - return JSONInputDataFactory.ReadGearbox(Path.Combine(BasePath, gearboxFile)); - } catch (Exception e) { - if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Gearbox file '{0}': {1}", e, Body[JsonKeys.Vehicle_GearboxFile], - e.Message); - } - return new JSONGearboxDataV6(GetDummyJSONStructure(), - Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>()) + MissingFileSuffix); - } - } - - private IEngineEngineeringInputData ReadEngine() - { - try { - return JSONInputDataFactory.ReadEngine( - Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>())); - } catch (Exception e) { - if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Engine file '{0}': {1}", e, Body[JsonKeys.Vehicle_EngineFile], - e.Message); - } - //JToken.FromObject(New Dictionary(Of String, Object) From {{"Header", header}, {"Body", body}}) - return - new JSONEngineDataV3(GetDummyJSONStructure(), - Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>()) + MissingFileSuffix); - } - } - - #region IInputDataProvider - - public virtual IEngineeringJobInputData JobInputData() - { - return this; - } - - IVehicleDeclarationInputData IDeclarationInputDataProvider.VehicleInputData - { - get { return VehicleInputData; } - } - - IAirdragDeclarationInputData IDeclarationInputDataProvider.AirdragInputData - { - get { return AirdragInputData; } - } - - public IAirdragEngineeringInputData AirdragInputData - { - get { return AirdragData; } - } - - IGearboxDeclarationInputData IDeclarationInputDataProvider.GearboxInputData - { - get { return GearboxInputData; } - } - - ITorqueConverterDeclarationInputData IDeclarationInputDataProvider.TorqueConverterInputData - { - get { return TorqueConverterInputData; } - } - - public ITorqueConverterEngineeringInputData TorqueConverterInputData - { - get { - if (TorqueConverter == null) { - throw new InvalidFileFormatException("TorqueConverterData not found"); - } - return TorqueConverter; - } - } - - IDeclarationJobInputData IDeclarationInputDataProvider.JobInputData() - { - return JobInputData(); - } - - public virtual IVehicleEngineeringInputData VehicleInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (VehicleData == null) { - throw new InvalidFileFormatException("VehicleData not found "); - } - return VehicleData; - } - } - - public virtual IGearboxEngineeringInputData GearboxInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Gearbox == null) { - throw new InvalidFileFormatException("GearboxData not found"); - } - return Gearbox; - } - } - - public virtual IAxleGearInputData AxleGearInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (AxleGear == null) { - throw new InvalidFileFormatException("AxleGearData not found"); - } - return AxleGear; - } - } - - public IAngledriveInputData AngledriveInputData - { - get { return Angledrive; } - } - - IEngineDeclarationInputData IDeclarationInputDataProvider.EngineInputData - { - get { return EngineInputData; } - } - - public virtual IEngineEngineeringInputData EngineInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Engine == null) { - throw new InvalidFileFormatException("EngineData not found"); - } - return Engine; - } - } - - public virtual IAuxiliariesEngineeringInputData AuxiliaryInputData() - { - return this; - } - - IDriverEngineeringInputData IEngineeringInputDataProvider.DriverInputData - { - get { return this; } - } - - public IPTOTransmissionInputData PTOTransmissionInputData - { - get { return PTOTransmission; } - } - - public XElement XMLHash - { - get { return null; } - } - - IAuxiliariesDeclarationInputData IDeclarationInputDataProvider.AuxiliaryInputData() - { - return this; - } - - public virtual IRetarderInputData RetarderInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - if (Retarder == null) { - throw new InvalidFileFormatException("RetarderData not found"); - } - return Retarder; - } - } - - public virtual IDriverDeclarationInputData DriverInputData - { - get { return this; } - } - - #endregion - - #region IJobInputData - - public virtual IVehicleEngineeringInputData Vehicle - { - get { return VehicleData; } - } - - public virtual IList<ICycleData> Cycles - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - var retVal = new List<ICycleData>(); - if (Body[JsonKeys.Job_Cycles] == null) { - return retVal; - } - foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) { - //.Select(cycle => - var cycleFile = Path.Combine(BasePath, cycle.Value<string>()); - TableData cycleData; - if (File.Exists(cycleFile)) { - cycleData = VectoCSVFile.Read(cycleFile); - } else { - try { - var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." + - cycle.Value<string>() + Constants.FileExtensions.CycleFile; - cycleData = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName), source: resourceName); - } catch (Exception e) { - Log.Debug("Driving Cycle could not be read: " + cycleFile); - if (!TolerateMissing) { - throw new VectoException("Driving Cycle could not be read: " + cycleFile, e); - } - cycleData = new TableData(cycleFile + MissingFileSuffix, DataSourceType.Missing); - } - } - retVal.Add(new CycleInputData() { - Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), - CycleData = cycleData - }); - } - return retVal; - } - } - - public virtual bool EngineOnlyMode - { - get { return Body.GetEx(JsonKeys.Job_EngineOnlyMode).Value<bool>(); } - } - - IVehicleDeclarationInputData IDeclarationJobInputData.Vehicle - { - get { return Vehicle; } - } - - public virtual string JobName - { - get { return _jobname; } - } - - #endregion - - #region DriverInputData - - IOverSpeedEcoRollDeclarationInputData IDriverDeclarationInputData.OverSpeedEcoRoll - { - get { - var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll); - return new OverSpeedEcoRollInputData() { - Mode = DriverData.ParseDriverMode(overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)) - }; - } - } - - public virtual ILookaheadCoastingInputData Lookahead - { - get { - if (Body[JsonKeys.DriverData_LookaheadCoasting] == null) { - return null; - } - - var lac = Body.GetEx(JsonKeys.DriverData_LookaheadCoasting); - var distanceScalingFactor = lac["PreviewDistanceFactor"] != null - ? lac.GetEx<double>("PreviewDistanceFactor") - : DeclarationData.Driver.LookAhead.LookAheadDistanceFactor; - var lacDfOffset = lac["DF_offset"] != null - ? lac.GetEx<double>("DF_offset") - : DeclarationData.Driver.LookAhead.DecisionFactorCoastingOffset; - var lacDfScaling = lac["DF_scaling"] != null - ? lac.GetEx<double>("DF_scaling") - : DeclarationData.Driver.LookAhead.DecisionFactorCoastingScaling; - TableData speedDependentLookup = null; - if (lac["DF_targetSpeedLookup"] != null && !string.IsNullOrWhiteSpace(lac["DF_targetSpeedLookup"].Value<string>())) { - try { - speedDependentLookup = ReadTableData(lac.GetEx<string>("DF_targetSpeedLookup"), - "Lookahead Coasting Decisionfactor - Target speed"); - } catch (Exception) { - if (TolerateMissing) { - speedDependentLookup = - new TableData(Path.Combine(BasePath, lac["DF_targetSpeedLookup"].Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - TableData velocityDropLookup = null; - if (lac["Df_velocityDropLookup"] != null && !string.IsNullOrWhiteSpace(lac["Df_velocityDropLookup"].Value<string>())) { - try { - velocityDropLookup = ReadTableData(lac.GetEx<string>("Df_velocityDropLookup"), - "Lookahead Coasting Decisionfactor - Velocity drop"); - } catch (Exception) { - if (TolerateMissing) { - velocityDropLookup = - new TableData(Path.Combine(BasePath, lac["Df_velocityDropLookup"].Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - var minSpeed = lac["MinSpeed"] != null - ? lac.GetEx<double>(JsonKeys.DriverData_Lookahead_MinSpeed).KMPHtoMeterPerSecond() - : DeclarationData.Driver.LookAhead.MinimumSpeed; - return new LookAheadCoastingInputData() { - Enabled = lac.GetEx<bool>(JsonKeys.DriverData_Lookahead_Enabled), - //Deceleration = lac.GetEx<double>(JsonKeys.DriverData_Lookahead_Deceleration).SI<MeterPerSquareSecond>(), - MinSpeed = minSpeed, - LookaheadDistanceFactor = distanceScalingFactor, - CoastingDecisionFactorOffset = lacDfOffset, - CoastingDecisionFactorScaling = lacDfScaling, - CoastingDecisionFactorTargetSpeedLookup = speedDependentLookup, - CoastingDecisionFactorVelocityDropLookup = velocityDropLookup - }; - } - } - - public virtual IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll - { - get { - var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll); - return new OverSpeedEcoRollInputData() { - Mode = DriverData.ParseDriverMode(overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)), - MinSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_MinSpeed).KMPHtoMeterPerSecond(), - OverSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_OverSpeed).KMPHtoMeterPerSecond(), - UnderSpeed = - overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_UnderSpeed).KMPHtoMeterPerSecond() - }; - } - } - - public virtual TableData AccelerationCurve - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get { - var acceleration = Body[JsonKeys.DriverData_AccelerationCurve]; - if (acceleration == null || EmptyOrInvalidFileName(acceleration.Value<string>())) { - return null; - // throw new VectoException("AccelerationCurve (VACC) required"); - } - try { - return ReadTableData(acceleration.Value<string>(), "DriverAccelerationCurve"); - } catch (VectoException e) { - Log.Warn("Could not find file for acceleration curve. Trying lookup in declaration data."); - try { - var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".VACC." + - acceleration.Value<string>() + - Constants.FileExtensions.DriverAccelerationCurve; - return VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName), source: resourceName); - } catch (Exception) { - if (!TolerateMissing) { - throw new VectoException("Failed to read Driver Acceleration Curve: " + e.Message, e); - } - return new TableData(Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - } - - #endregion - - #region IAuxiliariesEngineeringInputData - - IList<IAuxiliaryEngineeringInputData> IAuxiliariesEngineeringInputData.Auxiliaries - { - get { return AuxData().Cast<IAuxiliaryEngineeringInputData>().ToList(); } - } - - IList<IAuxiliaryDeclarationInputData> IAuxiliariesDeclarationInputData.Auxiliaries - { - get { return AuxData().Cast<IAuxiliaryDeclarationInputData>().ToList(); } - } - - protected virtual IList<AuxiliaryDataInputData> AuxData() - { - var retVal = new List<AuxiliaryDataInputData>(); - foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { - var type = AuxiliaryTypeHelper.Parse(aux.GetEx<string>("Type")); - - var auxData = new AuxiliaryDataInputData { - ID = aux.GetEx<string>("ID"), - Type = type, - Technology = new List<string>(), - }; - var tech = aux.GetEx<string>("Technology"); - - if (auxData.Type == AuxiliaryType.ElectricSystem) { - if (aux["TechList"] == null || aux["TechList"].Any()) { - auxData.Technology.Add("Standard technology"); - } else { - auxData.Technology.Add("Standard technology - LED headlights, all"); - } - } - - if (auxData.Type == AuxiliaryType.SteeringPump) { - auxData.Technology.Add(tech); - } - - if (auxData.Type == AuxiliaryType.Fan) { - switch (tech) { - case "Crankshaft mounted - Electronically controlled visco clutch (Default)": - auxData.Technology.Add("Crankshaft mounted - Electronically controlled visco clutch"); - break; - case "Crankshaft mounted - On/Off clutch": - auxData.Technology.Add("Crankshaft mounted - On/off clutch"); - break; - case "Belt driven or driven via transm. - On/Off clutch": - auxData.Technology.Add("Belt driven or driven via transm. - On/off clutch"); - break; - default: - auxData.Technology.Add(tech); - break; - } - } - - var auxFile = aux["Path"]; - retVal.Add(auxData); - - if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) { - continue; - } - - AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, Path.Combine(BasePath, auxFile.Value<string>())); - } - return retVal; - } - - #endregion - - #region AdvancedAuxiliaries - - public AuxiliaryModel AuxiliaryAssembly - { - get { - return AuxiliaryModelHelper.Parse(Body["AuxiliaryAssembly"] == null ? "" : Body["AuxiliaryAssembly"].ToString()); - } - } - - public string AuxiliaryVersion - { - get { return Body["AuxiliaryVersion"] != null ? Body["AuxiliaryVersion"].Value<string>() : "<CLASSIC>"; } - } - - public string AdvancedAuxiliaryFilePath - { - get { - return Body["AdvancedAuxiliaryFilePath"] != null - ? Path.Combine(Path.GetFullPath(BasePath), Body["AdvancedAuxiliaryFilePath"].Value<string>()) - : ""; - } - } - - #endregion - } - - public class JSONInputDataV3 : JSONInputDataV2 - { - public JSONInputDataV3(JObject data, string filename, bool tolerateMissing = false) - : base(data, filename, tolerateMissing) {} - - protected override IList<AuxiliaryDataInputData> AuxData() - { - var retVal = new List<AuxiliaryDataInputData>(); - if (Body["Padd"] != null) { - retVal.Add(new AuxiliaryDataInputData() { - ID = "ConstantAux", - AuxiliaryType = AuxiliaryDemandType.Constant, - ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>() - }); - } - foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { - try { - aux.GetEx("Technology").ToObject<List<string>>(); - } catch (Exception) { - throw new VectoException( - "Aux: Technology for aux '{0}' list could not be read. Maybe it is a single string instead of a list of strings?", - aux.GetEx<string>("ID")); - } - - var type = AuxiliaryTypeHelper.Parse(aux.GetEx<string>("Type")); - - var auxData = new AuxiliaryDataInputData { - ID = aux.GetEx<string>("ID"), - Type = type, - Technology = aux.GetEx("Technology").ToObject<List<string>>() - }; - - var auxFile = aux["Path"]; - retVal.Add(auxData); - - if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) { - continue; - } - AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, Path.Combine(BasePath, auxFile.Value<string>())); - } - return retVal; - } - } +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.InputData.FileIO.JSON +{ + public abstract class JSONFile : LoggingObject + { + public const string MissingFileSuffix = " -- (MISSING!)"; + + private readonly string _sourceFile; + + protected readonly JObject Body; + + protected JSONFile(JObject data, string filename, bool tolerateMissing = false) + { + //var header = (JObject)data.GetEx(JsonKeys.JsonHeader); + Body = (JObject)data.GetEx(JsonKeys.JsonBody); + _sourceFile = Path.GetFullPath(filename); + TolerateMissing = tolerateMissing; + } + + protected bool TolerateMissing { get; set; } + + public DataSourceType SourceType + { + get { return DataSourceType.JSONFile; } + } + + public string Source + { + get { return _sourceFile; } + } + + public bool SavedInDeclarationMode + { + get { return Body.GetEx(JsonKeys.SavedInDeclMode).Value<bool>(); } + } + + internal string BasePath + { + get { return Path.GetDirectoryName(_sourceFile); } + } + + protected TableData ReadTableData(string filename, string tableType, bool required = true) + { + if (!EmptyOrInvalidFileName(filename) && File.Exists(Path.Combine(BasePath, filename))) { + try { + return VectoCSVFile.Read(Path.Combine(BasePath, filename), true); + } catch (Exception e) { + Log.Warn("Failed to read file {0} {1}", Path.Combine(BasePath, filename), tableType); + throw new VectoException("Failed to read file for {0}: {1}", e, tableType, filename); + } + } + if (required) { + throw new VectoException("Invalid filename for {0}: {1}", tableType, filename); + } + return null; + } + + internal static bool EmptyOrInvalidFileName(string filename) + { + return filename == null || !filename.Any() || + filename.Equals("<NOFILE>", StringComparison.InvariantCultureIgnoreCase) + || filename.Equals("-"); + } + + public static JObject GetDummyJSONStructure() + { + return JObject.FromObject(new Dictionary<string, object>() { + { JsonKeys.JsonHeader, new object() }, + { JsonKeys.JsonBody, new object() } + }); + } + } + + /// <summary> + /// Class for reading json data of vecto-job-file. + /// Fileformat: .vecto + /// </summary> + public class JSONInputDataV2 : JSONFile, IEngineeringInputDataProvider, IDeclarationInputDataProvider, + IEngineeringJobInputData, IDriverEngineeringInputData, IAuxiliariesEngineeringInputData, + IAuxiliariesDeclarationInputData + { + protected readonly IGearboxEngineeringInputData Gearbox; + protected readonly IAxleGearInputData AxleGear; + protected readonly ITorqueConverterEngineeringInputData TorqueConverter; + protected readonly IAngledriveInputData Angledrive; + protected readonly IEngineEngineeringInputData Engine; + protected readonly IVehicleEngineeringInputData VehicleData; + protected readonly IRetarderInputData Retarder; + protected readonly IPTOTransmissionInputData PTOTransmission; + + private readonly string _jobname; + protected internal IAirdragEngineeringInputData AirdragData; + + public JSONInputDataV2(JObject data, string filename, bool tolerateMissing = false) + : base(data, filename, tolerateMissing) + { + _jobname = Path.GetFileNameWithoutExtension(filename); + + Engine = ReadEngine(); + + if (Body.GetEx(JsonKeys.Job_EngineOnlyMode).Value<bool>()) { + return; + } + + Gearbox = ReadGearbox(); + AxleGear = Gearbox as IAxleGearInputData; + TorqueConverter = Gearbox as ITorqueConverterEngineeringInputData; + + VehicleData = ReadVehicle(); + Angledrive = VehicleData as IAngledriveInputData; + Retarder = VehicleData as IRetarderInputData; + PTOTransmission = VehicleData as IPTOTransmissionInputData; + AirdragData = VehicleData as IAirdragEngineeringInputData; + } + + private IVehicleEngineeringInputData ReadVehicle() + { + try { + var vehicleFile = Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>(); + return JSONInputDataFactory.ReadJsonVehicle( + Path.Combine(BasePath, vehicleFile)); + } catch (Exception e) { + if (!TolerateMissing) { + throw new VectoException("JobFile: Failed to read Vehicle file '{0}': {1}", e, Body[JsonKeys.Vehicle_VehicleFile], + e.Message); + } + return new JSONVehicleDataV7(GetDummyJSONStructure(), + Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>()) + MissingFileSuffix); + } + } + + private IGearboxEngineeringInputData ReadGearbox() + { + try { + var gearboxFile = Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>(); + + return JSONInputDataFactory.ReadGearbox(Path.Combine(BasePath, gearboxFile)); + } catch (Exception e) { + if (!TolerateMissing) { + throw new VectoException("JobFile: Failed to read Gearbox file '{0}': {1}", e, Body[JsonKeys.Vehicle_GearboxFile], + e.Message); + } + return new JSONGearboxDataV6(GetDummyJSONStructure(), + Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>()) + MissingFileSuffix); + } + } + + private IEngineEngineeringInputData ReadEngine() + { + try { + return JSONInputDataFactory.ReadEngine( + Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>())); + } catch (Exception e) { + if (!TolerateMissing) { + throw new VectoException("JobFile: Failed to read Engine file '{0}': {1}", e, Body[JsonKeys.Vehicle_EngineFile], + e.Message); + } + //JToken.FromObject(New Dictionary(Of String, Object) From {{"Header", header}, {"Body", body}}) + return + new JSONEngineDataV3(GetDummyJSONStructure(), + Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>()) + MissingFileSuffix); + } + } + + #region IInputDataProvider + + public virtual IEngineeringJobInputData JobInputData() + { + return this; + } + + IVehicleDeclarationInputData IDeclarationInputDataProvider.VehicleInputData + { + get { return VehicleInputData; } + } + + IAirdragDeclarationInputData IDeclarationInputDataProvider.AirdragInputData + { + get { return AirdragInputData; } + } + + public IAirdragEngineeringInputData AirdragInputData + { + get { return AirdragData; } + } + + IGearboxDeclarationInputData IDeclarationInputDataProvider.GearboxInputData + { + get { return GearboxInputData; } + } + + ITorqueConverterDeclarationInputData IDeclarationInputDataProvider.TorqueConverterInputData + { + get { return TorqueConverterInputData; } + } + + public ITorqueConverterEngineeringInputData TorqueConverterInputData + { + get + { + if (TorqueConverter == null) { + throw new InvalidFileFormatException("TorqueConverterData not found"); + } + return TorqueConverter; + } + } + + IDeclarationJobInputData IDeclarationInputDataProvider.JobInputData() + { + return JobInputData(); + } + + public virtual IVehicleEngineeringInputData VehicleInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + if (VehicleData == null) { + throw new InvalidFileFormatException("VehicleData not found "); + } + return VehicleData; + } + } + + public virtual IGearboxEngineeringInputData GearboxInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + if (Gearbox == null) { + throw new InvalidFileFormatException("GearboxData not found"); + } + return Gearbox; + } + } + + public virtual IAxleGearInputData AxleGearInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + if (AxleGear == null) { + throw new InvalidFileFormatException("AxleGearData not found"); + } + return AxleGear; + } + } + + public IAngledriveInputData AngledriveInputData + { + get { return Angledrive; } + } + + IEngineDeclarationInputData IDeclarationInputDataProvider.EngineInputData + { + get { return EngineInputData; } + } + + public virtual IEngineEngineeringInputData EngineInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + if (Engine == null) { + throw new InvalidFileFormatException("EngineData not found"); + } + return Engine; + } + } + + public virtual IAuxiliariesEngineeringInputData AuxiliaryInputData() + { + return this; + } + + IDriverEngineeringInputData IEngineeringInputDataProvider.DriverInputData + { + get { return this; } + } + + public IPTOTransmissionInputData PTOTransmissionInputData + { + get { return PTOTransmission; } + } + + public XElement XMLHash + { + get { return null; } + } + + IAuxiliariesDeclarationInputData IDeclarationInputDataProvider.AuxiliaryInputData() + { + return this; + } + + public virtual IRetarderInputData RetarderInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + if (Retarder == null) { + throw new InvalidFileFormatException("RetarderData not found"); + } + return Retarder; + } + } + + public virtual IDriverDeclarationInputData DriverInputData + { + get { return this; } + } + + #endregion + + #region IJobInputData + + public virtual IVehicleEngineeringInputData Vehicle + { + get { return VehicleData; } + } + + public virtual IList<ICycleData> Cycles + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + var retVal = new List<ICycleData>(); + if (Body[JsonKeys.Job_Cycles] == null) { + return retVal; + } + foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) { + //.Select(cycle => + var cycleFile = Path.Combine(BasePath, cycle.Value<string>()); + TableData cycleData; + if (File.Exists(cycleFile)) { + cycleData = VectoCSVFile.Read(cycleFile); + } else { + try { + var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." + + cycle.Value<string>() + Constants.FileExtensions.CycleFile; + cycleData = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName), source: resourceName); + } catch (Exception e) { + Log.Debug("Driving Cycle could not be read: " + cycleFile); + if (!TolerateMissing) { + throw new VectoException("Driving Cycle could not be read: " + cycleFile, e); + } + cycleData = new TableData(cycleFile + MissingFileSuffix, DataSourceType.Missing); + } + } + retVal.Add(new CycleInputData() { + Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), + CycleData = cycleData + }); + } + return retVal; + } + } + + public virtual bool EngineOnlyMode + { + get { return Body.GetEx(JsonKeys.Job_EngineOnlyMode).Value<bool>(); } + } + + IVehicleDeclarationInputData IDeclarationJobInputData.Vehicle + { + get { return Vehicle; } + } + + public virtual string JobName + { + get { return _jobname; } + } + + #endregion + + #region DriverInputData + + IOverSpeedEcoRollDeclarationInputData IDriverDeclarationInputData.OverSpeedEcoRoll + { + get + { + var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll); + return new OverSpeedEcoRollInputData() { + Mode = DriverData.ParseDriverMode(overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)) + }; + } + } + + public virtual ILookaheadCoastingInputData Lookahead + { + get + { + if (Body[JsonKeys.DriverData_LookaheadCoasting] == null) { + return null; + } + + var lac = Body.GetEx(JsonKeys.DriverData_LookaheadCoasting); + var distanceScalingFactor = lac["PreviewDistanceFactor"] != null + ? lac.GetEx<double>("PreviewDistanceFactor") + : DeclarationData.Driver.LookAhead.LookAheadDistanceFactor; + var lacDfOffset = lac["DF_offset"] != null + ? lac.GetEx<double>("DF_offset") + : DeclarationData.Driver.LookAhead.DecisionFactorCoastingOffset; + var lacDfScaling = lac["DF_scaling"] != null + ? lac.GetEx<double>("DF_scaling") + : DeclarationData.Driver.LookAhead.DecisionFactorCoastingScaling; + var speedDependentLookup = GetSpeedDependentLookupTable(lac); + var velocityDropLookup = GetVelocityDropLookupTable(lac); + var minSpeed = lac["MinSpeed"] != null + ? lac.GetEx<double>(JsonKeys.DriverData_Lookahead_MinSpeed).KMPHtoMeterPerSecond() + : DeclarationData.Driver.LookAhead.MinimumSpeed; + return new LookAheadCoastingInputData() { + Enabled = lac.GetEx<bool>(JsonKeys.DriverData_Lookahead_Enabled), + //Deceleration = lac.GetEx<double>(JsonKeys.DriverData_Lookahead_Deceleration).SI<MeterPerSquareSecond>(), + MinSpeed = minSpeed, + LookaheadDistanceFactor = distanceScalingFactor, + CoastingDecisionFactorOffset = lacDfOffset, + CoastingDecisionFactorScaling = lacDfScaling, + CoastingDecisionFactorTargetSpeedLookup = speedDependentLookup, + CoastingDecisionFactorVelocityDropLookup = velocityDropLookup + }; + } + } + + private TableData GetVelocityDropLookupTable(JToken lac) + { + if (lac["Df_velocityDropLookup"] == null || string.IsNullOrWhiteSpace(lac["Df_velocityDropLookup"].Value<string>())) { + return null; + } + try { + return ReadTableData(lac.GetEx<string>("Df_velocityDropLookup"), + "Lookahead Coasting Decisionfactor - Velocity drop"); + } catch (Exception) { + if (TolerateMissing) { + return + new TableData(Path.Combine(BasePath, lac["Df_velocityDropLookup"].Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + return null; + } + + private TableData GetSpeedDependentLookupTable(JToken lac) + { + if (lac["DF_targetSpeedLookup"] == null || string.IsNullOrWhiteSpace(lac["DF_targetSpeedLookup"].Value<string>())) { + return null; + } + try { + return ReadTableData(lac.GetEx<string>("DF_targetSpeedLookup"), + "Lookahead Coasting Decisionfactor - Target speed"); + } catch (Exception) { + if (TolerateMissing) { + return + new TableData(Path.Combine(BasePath, lac["DF_targetSpeedLookup"].Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + return null; + } + + public virtual IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll + { + get + { + var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll); + return new OverSpeedEcoRollInputData() { + Mode = DriverData.ParseDriverMode(overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)), + MinSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_MinSpeed).KMPHtoMeterPerSecond(), + OverSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_OverSpeed).KMPHtoMeterPerSecond(), + UnderSpeed = + overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_UnderSpeed).KMPHtoMeterPerSecond() + }; + } + } + + public virtual TableData AccelerationCurve + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + get + { + var acceleration = Body[JsonKeys.DriverData_AccelerationCurve]; + if (acceleration == null || EmptyOrInvalidFileName(acceleration.Value<string>())) { + return null; + // throw new VectoException("AccelerationCurve (VACC) required"); + } + try { + return ReadTableData(acceleration.Value<string>(), "DriverAccelerationCurve"); + } catch (VectoException e) { + Log.Warn("Could not find file for acceleration curve. Trying lookup in declaration data."); + try { + var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".VACC." + + acceleration.Value<string>() + + Constants.FileExtensions.DriverAccelerationCurve; + return VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName), source: resourceName); + } catch (Exception) { + if (!TolerateMissing) { + throw new VectoException("Failed to read Driver Acceleration Curve: " + e.Message, e); + } + return new TableData(Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + } + + #endregion + + #region IAuxiliariesEngineeringInputData + + IList<IAuxiliaryEngineeringInputData> IAuxiliariesEngineeringInputData.Auxiliaries + { + get { return AuxData().Cast<IAuxiliaryEngineeringInputData>().ToList(); } + } + + IList<IAuxiliaryDeclarationInputData> IAuxiliariesDeclarationInputData.Auxiliaries + { + get { return AuxData().Cast<IAuxiliaryDeclarationInputData>().ToList(); } + } + + protected virtual IList<AuxiliaryDataInputData> AuxData() + { + var retVal = new List<AuxiliaryDataInputData>(); + foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { + var type = AuxiliaryTypeHelper.Parse(aux.GetEx<string>("Type")); + + var auxData = new AuxiliaryDataInputData { + ID = aux.GetEx<string>("ID"), + Type = type, + Technology = new List<string>(), + }; + var tech = aux.GetEx<string>("Technology"); + + if (auxData.Type == AuxiliaryType.ElectricSystem) { + if (aux["TechList"] == null || aux["TechList"].Any()) { + auxData.Technology.Add("Standard technology"); + } else { + auxData.Technology.Add("Standard technology - LED headlights, all"); + } + } + + if (auxData.Type == AuxiliaryType.SteeringPump) { + auxData.Technology.Add(tech); + } + + if (auxData.Type == AuxiliaryType.Fan) { + auxData.Technology.Add(MapLegacyFanTechnologies(tech)); + } + + var auxFile = aux["Path"]; + retVal.Add(auxData); + + if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) { + continue; + } + + AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, Path.Combine(BasePath, auxFile.Value<string>())); + } + return retVal; + } + + private static string MapLegacyFanTechnologies(string tech) + { + string newTech; + switch (tech) { + case "Crankshaft mounted - Electronically controlled visco clutch (Default)": + newTech = "Crankshaft mounted - Electronically controlled visco clutch"; + break; + case "Crankshaft mounted - On/Off clutch": + newTech = "Crankshaft mounted - On/off clutch"; + break; + case "Belt driven or driven via transm. - On/Off clutch": + newTech = "Belt driven or driven via transm. - On/off clutch"; + break; + default: + newTech = tech; + break; + } + return newTech; + } + + #endregion + + #region AdvancedAuxiliaries + + public AuxiliaryModel AuxiliaryAssembly + { + get + { + return AuxiliaryModelHelper.Parse(Body["AuxiliaryAssembly"] == null ? "" : Body["AuxiliaryAssembly"].ToString()); + } + } + + public string AuxiliaryVersion + { + get { return Body["AuxiliaryVersion"] != null ? Body["AuxiliaryVersion"].Value<string>() : "<CLASSIC>"; } + } + + public string AdvancedAuxiliaryFilePath + { + get + { + return Body["AdvancedAuxiliaryFilePath"] != null + ? Path.Combine(Path.GetFullPath(BasePath), Body["AdvancedAuxiliaryFilePath"].Value<string>()) + : ""; + } + } + + #endregion + } + + public class JSONInputDataV3 : JSONInputDataV2 + { + public JSONInputDataV3(JObject data, string filename, bool tolerateMissing = false) + : base(data, filename, tolerateMissing) {} + + protected override IList<AuxiliaryDataInputData> AuxData() + { + var retVal = new List<AuxiliaryDataInputData>(); + if (Body["Padd"] != null) { + retVal.Add(new AuxiliaryDataInputData() { + ID = "ConstantAux", + AuxiliaryType = AuxiliaryDemandType.Constant, + ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>() + }); + } + foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { + try { + aux.GetEx("Technology").ToObject<List<string>>(); + } catch (Exception) { + throw new VectoException( + "Aux: Technology for aux '{0}' list could not be read. Maybe it is a single string instead of a list of strings?", + aux.GetEx<string>("ID")); + } + + var type = AuxiliaryTypeHelper.Parse(aux.GetEx<string>("Type")); + + var auxData = new AuxiliaryDataInputData { + ID = aux.GetEx<string>("ID"), + Type = type, + Technology = aux.GetEx("Technology").ToObject<List<string>>() + }; + + var auxFile = aux["Path"]; + retVal.Add(auxData); + + if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) { + continue; + } + AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, Path.Combine(BasePath, auxFile.Value<string>())); + } + return retVal; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs index c406af6f577cce116208b59668c8b6012643e388..84520f0a606ea9de508fb2a5a096b860c97d0320 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs @@ -29,96 +29,96 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.IO; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCore.Configuration; - -namespace TUGraz.VectoCore.InputData.FileIO.JSON -{ - // ReSharper disable once InconsistentNaming - public static class JSONInputDataFactory - { - internal static JObject ReadFile(string fileName) - { - if (!File.Exists(fileName)) { - throw new FileNotFoundException("failed to load file: " + fileName, fileName); - } - using (var reader = File.OpenText(fileName)) { - return (JObject)JToken.ReadFrom(new JsonTextReader(reader)); - } - } - - public static IInputDataProvider ReadComponentData(string filename) - { - if (Constants.FileExtensions.VectoJobFile.Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase)) { - return ReadJsonJob(filename, true); - } - return new JSONComponentInputData(filename, true); - } - - public static IInputDataProvider ReadJsonJob(string filename, bool tolerateMissing = false) - { - var json = ReadFile(filename); - var version = ReadVersion(json); - - switch (version) { - case 2: - return new JSONInputDataV2(json, filename, tolerateMissing); - case 3: - return new JSONInputDataV3(json, filename, tolerateMissing); - default: - throw new VectoException("Job-File: Unsupported FileVersion. Got: {0} ", version); - } - } - - public static IVehicleEngineeringInputData ReadJsonVehicle(string filename, bool tolerateMissing = false) - { - var json = ReadFile(filename); - var version = ReadVersion(json); - switch (version) { - case 7: - return new JSONVehicleDataV7(json, filename, tolerateMissing); - default: - throw new VectoException("Vehicle-File: Unsupported FileVersion. Got {0}", version); - } - } - - public static IGearboxEngineeringInputData ReadGearbox(string filename, bool tolerateMissing = false) - { - var json = ReadFile(filename); - var version = ReadVersion(json); - switch (version) { - case 5: - return new JSONGearboxDataV5(json, filename, tolerateMissing); - case 6: - return new JSONGearboxDataV6(json, filename, tolerateMissing); - default: - throw new VectoException("Gearbox-File: Unsupported FileVersion. Got {0}", version); - } - } - - public static IEngineEngineeringInputData ReadEngine(string filename, bool tolerateMissing = false) - { - var json = ReadFile(filename); - var version = ReadVersion(json); - switch (version) { - case 3: - return new JSONEngineDataV3(json, filename, tolerateMissing); - case 4: - return new JSONEngineDataV4(json, filename, tolerateMissing); - default: - throw new VectoException("Engine-File: Unsupported FileVersion. Got {0}", version); - } - } - - private static int ReadVersion(JObject json) - { - var value = json.GetEx(JsonKeys.JsonHeader).GetEx<string>(JsonKeys.JsonHeader_FileVersion); - return (int)double.Parse(value.Trim('"')); - } - } +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.IO; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCore.Configuration; + +namespace TUGraz.VectoCore.InputData.FileIO.JSON +{ + // ReSharper disable once InconsistentNaming + public static class JSONInputDataFactory + { + internal static JObject ReadFile(string fileName) + { + if (!File.Exists(fileName)) { + throw new FileNotFoundException("failed to load file: " + fileName, fileName); + } + using (var reader = File.OpenText(fileName)) { + return (JObject)JToken.ReadFrom(new JsonTextReader(reader)); + } + } + + public static IInputDataProvider ReadComponentData(string filename) + { + if (Constants.FileExtensions.VectoJobFile.Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase)) { + return ReadJsonJob(filename, true); + } + return new JSONComponentInputData(filename, true); + } + + public static IInputDataProvider ReadJsonJob(string filename, bool tolerateMissing = false) + { + var json = ReadFile(filename); + var version = ReadVersion(json); + + switch (version) { + case 2: + return new JSONInputDataV2(json, filename, tolerateMissing); + case 3: + return new JSONInputDataV3(json, filename, tolerateMissing); + default: + throw new VectoException("Job-File: Unsupported FileVersion. Got: {0} ", version); + } + } + + public static IVehicleEngineeringInputData ReadJsonVehicle(string filename, bool tolerateMissing = false) + { + var json = ReadFile(filename); + var version = ReadVersion(json); + switch (version) { + case 7: + return new JSONVehicleDataV7(json, filename, tolerateMissing); + default: + throw new VectoException("Vehicle-File: Unsupported FileVersion. Got {0}", version); + } + } + + public static IGearboxEngineeringInputData ReadGearbox(string filename, bool tolerateMissing = false) + { + var json = ReadFile(filename); + var version = ReadVersion(json); + switch (version) { + case 5: + return new JSONGearboxDataV5(json, filename, tolerateMissing); + case 6: + return new JSONGearboxDataV6(json, filename, tolerateMissing); + default: + throw new VectoException("Gearbox-File: Unsupported FileVersion. Got {0}", version); + } + } + + public static IEngineEngineeringInputData ReadEngine(string filename, bool tolerateMissing = false) + { + var json = ReadFile(filename); + var version = ReadVersion(json); + switch (version) { + case 3: + return new JSONEngineDataV3(json, filename, tolerateMissing); + case 4: + return new JSONEngineDataV4(json, filename, tolerateMissing); + default: + throw new VectoException("Engine-File: Unsupported FileVersion. Got {0}", version); + } + } + + private static int ReadVersion(JObject json) + { + var value = json.GetEx(JsonKeys.JsonHeader).GetEx<string>(JsonKeys.JsonHeader_FileVersion); + return (int)double.Parse(value.Trim('"')); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs index 6c23a3f3a27fda1aa029a141982343f60d4c8a5e..700f70c88a1822bbef48400b1d964e9975d1266e 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs @@ -29,353 +29,357 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Newtonsoft.Json.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Impl; - -namespace TUGraz.VectoCore.InputData.FileIO.JSON -{ - public class JSONVehicleDataV7 : JSONFile, IVehicleEngineeringInputData, IRetarderInputData, IAngledriveInputData, - IPTOTransmissionInputData, IAirdragEngineeringInputData - { - public JSONVehicleDataV7(JObject data, string fileName, bool tolerateMissing = false) - : base(data, fileName, tolerateMissing) {} - - #region IVehicleInputData - - public string VIN - { - get { return "N.A."; } - } - - public string LegislativeClass - { - get { return "N3"; } - } - - public VehicleCategory VehicleCategory - { - get { - return - (VehicleCategory)Enum.Parse(typeof(VehicleCategory), Body[JsonKeys.Vehicle_VehicleCategory].Value<string>(), true); - } - } - - public virtual Kilogram CurbMassChassis - { - get { return Body.GetEx<double>(JsonKeys.Vehicle_CurbWeight).SI<Kilogram>(); } - } - - public virtual Kilogram CurbMassExtra - { - get { return Body.GetEx<double>(JsonKeys.Vehicle_CurbWeightExtra).SI<Kilogram>(); } - } - - public virtual Kilogram GrossVehicleMassRating - { - get { return Body.GetEx<double>(JsonKeys.Vehicle_GrossVehicleMassRating).SI().Ton.Cast<Kilogram>(); } - } - - public IList<ITorqueLimitInputData> TorqueLimits - { - get { - var retVal = new List<ITorqueLimitInputData>(); - if (Body["TorqueLimits"] == null) { - return retVal; - } - foreach (var entry in (JObject)Body["TorqueLimits"]) { - retVal.Add(new TorqueLimitInputData() { - Gear = entry.Key.ToInt(), - MaxTorque = entry.Value.ToString().ToDouble(0).SI<NewtonMeter>() - }); - } - return retVal; - } - } - - public virtual Kilogram Loading - { - get { return Body.GetEx<double>(JsonKeys.Vehicle_Loading).SI<Kilogram>(); } - } - - public virtual Meter DynamicTyreRadius - { - get { return Body.GetEx<double>(JsonKeys.Vehicle_DynamicTyreRadius).SI().Milli.Meter.Cast<Meter>(); } - } - - public virtual AxleConfiguration AxleConfiguration - { - get { - return - AxleConfigurationHelper.Parse( - Body.GetEx(JsonKeys.Vehicle_AxleConfiguration).GetEx<string>(JsonKeys.Vehicle_AxleConfiguration_Type)); - } - } - - public virtual IList<IAxleEngineeringInputData> Axles - { - get { return AxleWheels().Cast<IAxleEngineeringInputData>().ToList(); } - } - - public string ManufacturerAddress - { - get { return "N.A."; } - } - - public PerSecond EngineIdleSpeed - { - get { return Body["IdlingSpeed"] != null ? Body.GetEx<double>("IdlingSpeed").RPMtoRad() : null; } - } - - IList<IAxleDeclarationInputData> IVehicleDeclarationInputData.Axles - { - get { return AxleWheels().Cast<IAxleDeclarationInputData>().ToList(); } - } - - private IEnumerable<AxleInputData> AxleWheels() - { - return - Body.GetEx(JsonKeys.Vehicle_AxleConfiguration).GetEx(JsonKeys.Vehicle_AxleConfiguration_Axles).Select( - (axle, idx) => new AxleInputData { - SourceType = DataSourceType.JSONFile, - Source = Source, - Inertia = axle.GetEx<double>(JsonKeys.Vehicle_Axles_Inertia).SI<KilogramSquareMeter>(), - Wheels = axle.GetEx<string>(JsonKeys.Vehicle_Axles_Wheels), - TwinTyres = axle.GetEx<bool>(JsonKeys.Vehicle_Axles_TwinTyres), - RollResistanceCoefficient = axle.GetEx<double>(JsonKeys.Vehicle_Axles_RollResistanceCoefficient), - TyreTestLoad = axle.GetEx<double>(JsonKeys.Vehicle_Axles_TyreTestLoad).SI<Newton>(), - AxleWeightShare = axle.GetEx<double>("AxleWeightShare"), - AxleType = - axle["Type"] != null - ? axle.GetEx<string>("Type").ParseEnum<AxleType>() - : (idx == 1 ? AxleType.VehicleDriven : AxleType.VehicleNonDriven) - }); - } - - #endregion - - #region Airdrag - - public virtual SquareMeter AirDragArea - { - get { - return Body[JsonKeys.Vehicle_DragCoefficient] == null - ? null - : Body.GetEx<double>(JsonKeys.Vehicle_DragCoefficient).SI<SquareMeter>(); - } - } - - public virtual CrossWindCorrectionMode CrossWindCorrectionMode - { - get { return CrossWindCorrectionModeHelper.Parse(Body.GetEx<string>("CdCorrMode")); } - } - - public virtual TableData CrosswindCorrectionMap - { - get { - try { - return ReadTableData(Body.GetEx<string>("CdCorrFile"), "CrosswindCorrection File"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData(Path.Combine(BasePath, Body["CdCorrFile"].ToString()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - - #endregion - - #region IRetarderInputData - - RetarderType IRetarderInputData.Type - { - get { - var retarderType = Body.GetEx(JsonKeys.Vehicle_Retarder).GetEx<string>(JsonKeys.Vehicle_Retarder_Type); - return RetarderTypeHelper.Parse(retarderType); - } - } - - double IRetarderInputData.Ratio - { - get { return Body.GetEx(JsonKeys.Vehicle_Retarder).GetEx<double>(JsonKeys.Vehicle_Retarder_Ratio); } - } - - TableData IRetarderInputData.LossMap - { - get { - if (Body[JsonKeys.Vehicle_Retarder] != null && - Body.GetEx(JsonKeys.Vehicle_Retarder)[JsonKeys.Vehicle_Retarder_LossMapFile] != null) { - var lossmapFile = Body.GetEx(JsonKeys.Vehicle_Retarder)[JsonKeys.Vehicle_Retarder_LossMapFile]; - if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { - return null; - } - try { - return ReadTableData(lossmapFile.Value<string>(), "LossMap"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - return null; - } - } - - #endregion - - #region IAngledriveInputData - - AngledriveType IAngledriveInputData.Type - { - get { - var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; - if (angleDrive == null) { - return AngledriveType.None; - } - - return angleDrive.GetEx<string>(JsonKeys.Vehicle_Angledrive_Type).ParseEnum<AngledriveType>(); - } - } - - double IAngledriveInputData.Ratio - { - get { - var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; - if (angleDrive == null) { - return double.NaN; - } - return Body.GetEx(JsonKeys.Vehicle_Angledrive).GetEx<double>(JsonKeys.Vehicle_Angledrive_Ratio); - } - } - - TableData IAngledriveInputData.LossMap - { - get { - var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; - if (angleDrive == null || angleDrive[JsonKeys.Vehicle_Angledrive_LossMapFile] == null) { - return null; - } - var lossmapFile = angleDrive[JsonKeys.Vehicle_Angledrive_LossMapFile]; - if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { - return null; - } - try { - return ReadTableData(lossmapFile.Value<string>(), "LossMap"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - - double IAngledriveInputData.Efficiency - { - get { return Body.GetEx(JsonKeys.Vehicle_Angledrive).GetEx<double>(JsonKeys.Vehicle_Angledrive_Efficiency); } - } - - #endregion - - #region IPTOTransmissionInputData - - string IPTOTransmissionInputData.PTOTransmissionType - { - get { - var pto = Body[JsonKeys.Vehicle_PTO]; - if (pto == null) { - return "None"; - } - return pto[JsonKeys.Vehicle_PTO_Type].Value<string>(); - } - } - - TableData IPTOTransmissionInputData.PTOLossMap - { - get { - var pto = Body[JsonKeys.Vehicle_PTO]; - if (pto == null || pto[JsonKeys.Vehicle_PTO_LossMapFile] == null) { - return null; - } - var lossmapFile = pto[JsonKeys.Vehicle_PTO_LossMapFile]; - if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { - return null; - } - try { - return ReadTableData(Body.GetEx(JsonKeys.Vehicle_PTO).GetEx<string>(JsonKeys.Vehicle_PTO_LossMapFile), "LossMap"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, - DataSourceType.Missing); - } - } - } - - public TableData PTOCycle - { - get { - var pto = Body[JsonKeys.Vehicle_PTO]; - if (pto == null || pto[JsonKeys.Vehicle_PTO_Cycle] == null) { - return null; - } - var cycle = pto[JsonKeys.Vehicle_PTO_Cycle]; - if (string.IsNullOrWhiteSpace(cycle.Value<string>())) { - return null; - } - try { - return ReadTableData(Body.GetEx(JsonKeys.Vehicle_PTO).GetEx<string>(JsonKeys.Vehicle_PTO_Cycle), "Cycle"); - } catch (Exception) { - if (!TolerateMissing) { - throw; - } - return new TableData(Path.Combine(BasePath, cycle.Value<string>()) + MissingFileSuffix, DataSourceType.Missing); - } - } - } - - #endregion - - public string Manufacturer - { - get { return "N/A"; } - } - - public string Model - { - get { return "N.A."; } - } - - public string Date - { - get { return "N/A"; } - } - - public CertificationMethod CertificationMethod - { - get { return CertificationMethod.NotCertified; } - } - - public string CertificationNumber - { - get { return "N.A."; } - } - - public string DigestValue - { - get { return ""; } - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Impl; + +namespace TUGraz.VectoCore.InputData.FileIO.JSON +{ + public class JSONVehicleDataV7 : JSONFile, IVehicleEngineeringInputData, IRetarderInputData, IAngledriveInputData, + IPTOTransmissionInputData, IAirdragEngineeringInputData + { + public JSONVehicleDataV7(JObject data, string fileName, bool tolerateMissing = false) + : base(data, fileName, tolerateMissing) {} + + #region IVehicleInputData + + public string VIN + { + get { return "N.A."; } + } + + public LegislativeClass LegislativeClass + { + get { + return Body["LegislativeClass"] != null + ? Body["LegislativeClass"].Value<string>().ParseEnum<LegislativeClass>() + : LegislativeClass.Unknown; + } + } + + public VehicleCategory VehicleCategory + { + get { + return + (VehicleCategory)Enum.Parse(typeof(VehicleCategory), Body[JsonKeys.Vehicle_VehicleCategory].Value<string>(), true); + } + } + + public virtual Kilogram CurbMassChassis + { + get { return Body.GetEx<double>(JsonKeys.Vehicle_CurbWeight).SI<Kilogram>(); } + } + + public virtual Kilogram CurbMassExtra + { + get { return Body.GetEx<double>(JsonKeys.Vehicle_CurbWeightExtra).SI<Kilogram>(); } + } + + public virtual Kilogram GrossVehicleMassRating + { + get { return Body.GetEx<double>(JsonKeys.Vehicle_GrossVehicleMassRating).SI().Ton.Cast<Kilogram>(); } + } + + public IList<ITorqueLimitInputData> TorqueLimits + { + get { + var retVal = new List<ITorqueLimitInputData>(); + if (Body["TorqueLimits"] == null) { + return retVal; + } + foreach (var entry in (JObject)Body["TorqueLimits"]) { + retVal.Add(new TorqueLimitInputData() { + Gear = entry.Key.ToInt(), + MaxTorque = entry.Value.ToString().ToDouble(0).SI<NewtonMeter>() + }); + } + return retVal; + } + } + + public virtual Kilogram Loading + { + get { return Body.GetEx<double>(JsonKeys.Vehicle_Loading).SI<Kilogram>(); } + } + + public virtual Meter DynamicTyreRadius + { + get { return Body.GetEx<double>(JsonKeys.Vehicle_DynamicTyreRadius).SI().Milli.Meter.Cast<Meter>(); } + } + + public virtual AxleConfiguration AxleConfiguration + { + get { + return + AxleConfigurationHelper.Parse( + Body.GetEx(JsonKeys.Vehicle_AxleConfiguration).GetEx<string>(JsonKeys.Vehicle_AxleConfiguration_Type)); + } + } + + public virtual IList<IAxleEngineeringInputData> Axles + { + get { return AxleWheels().Cast<IAxleEngineeringInputData>().ToList(); } + } + + public string ManufacturerAddress + { + get { return "N.A."; } + } + + public PerSecond EngineIdleSpeed + { + get { return Body["IdlingSpeed"] != null ? Body.GetEx<double>("IdlingSpeed").RPMtoRad() : null; } + } + + IList<IAxleDeclarationInputData> IVehicleDeclarationInputData.Axles + { + get { return AxleWheels().Cast<IAxleDeclarationInputData>().ToList(); } + } + + private IEnumerable<AxleInputData> AxleWheels() + { + return + Body.GetEx(JsonKeys.Vehicle_AxleConfiguration).GetEx(JsonKeys.Vehicle_AxleConfiguration_Axles).Select( + (axle, idx) => new AxleInputData { + SourceType = DataSourceType.JSONFile, + Source = Source, + Inertia = axle.GetEx<double>(JsonKeys.Vehicle_Axles_Inertia).SI<KilogramSquareMeter>(), + Wheels = axle.GetEx<string>(JsonKeys.Vehicle_Axles_Wheels), + TwinTyres = axle.GetEx<bool>(JsonKeys.Vehicle_Axles_TwinTyres), + RollResistanceCoefficient = axle.GetEx<double>(JsonKeys.Vehicle_Axles_RollResistanceCoefficient), + TyreTestLoad = axle.GetEx<double>(JsonKeys.Vehicle_Axles_TyreTestLoad).SI<Newton>(), + AxleWeightShare = axle.GetEx<double>("AxleWeightShare"), + AxleType = + axle["Type"] != null + ? axle.GetEx<string>("Type").ParseEnum<AxleType>() + : (idx == 1 ? AxleType.VehicleDriven : AxleType.VehicleNonDriven) + }); + } + + #endregion + + #region Airdrag + + public virtual SquareMeter AirDragArea + { + get { + return Body[JsonKeys.Vehicle_DragCoefficient] == null + ? null + : Body.GetEx<double>(JsonKeys.Vehicle_DragCoefficient).SI<SquareMeter>(); + } + } + + public virtual CrossWindCorrectionMode CrossWindCorrectionMode + { + get { return CrossWindCorrectionModeHelper.Parse(Body.GetEx<string>("CdCorrMode")); } + } + + public virtual TableData CrosswindCorrectionMap + { + get { + try { + return ReadTableData(Body.GetEx<string>("CdCorrFile"), "CrosswindCorrection File"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData(Path.Combine(BasePath, Body["CdCorrFile"].ToString()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + + #endregion + + #region IRetarderInputData + + RetarderType IRetarderInputData.Type + { + get { + var retarderType = Body.GetEx(JsonKeys.Vehicle_Retarder).GetEx<string>(JsonKeys.Vehicle_Retarder_Type); + return RetarderTypeHelper.Parse(retarderType); + } + } + + double IRetarderInputData.Ratio + { + get { return Body.GetEx(JsonKeys.Vehicle_Retarder).GetEx<double>(JsonKeys.Vehicle_Retarder_Ratio); } + } + + TableData IRetarderInputData.LossMap + { + get { + if (Body[JsonKeys.Vehicle_Retarder] != null && + Body.GetEx(JsonKeys.Vehicle_Retarder)[JsonKeys.Vehicle_Retarder_LossMapFile] != null) { + var lossmapFile = Body.GetEx(JsonKeys.Vehicle_Retarder)[JsonKeys.Vehicle_Retarder_LossMapFile]; + if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { + return null; + } + try { + return ReadTableData(lossmapFile.Value<string>(), "LossMap"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + return null; + } + } + + #endregion + + #region IAngledriveInputData + + AngledriveType IAngledriveInputData.Type + { + get { + var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; + if (angleDrive == null) { + return AngledriveType.None; + } + + return angleDrive.GetEx<string>(JsonKeys.Vehicle_Angledrive_Type).ParseEnum<AngledriveType>(); + } + } + + double IAngledriveInputData.Ratio + { + get { + var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; + if (angleDrive == null) { + return double.NaN; + } + return Body.GetEx(JsonKeys.Vehicle_Angledrive).GetEx<double>(JsonKeys.Vehicle_Angledrive_Ratio); + } + } + + TableData IAngledriveInputData.LossMap + { + get { + var angleDrive = Body[JsonKeys.Vehicle_Angledrive]; + if (angleDrive == null || angleDrive[JsonKeys.Vehicle_Angledrive_LossMapFile] == null) { + return null; + } + var lossmapFile = angleDrive[JsonKeys.Vehicle_Angledrive_LossMapFile]; + if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { + return null; + } + try { + return ReadTableData(lossmapFile.Value<string>(), "LossMap"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + + double IAngledriveInputData.Efficiency + { + get { return Body.GetEx(JsonKeys.Vehicle_Angledrive).GetEx<double>(JsonKeys.Vehicle_Angledrive_Efficiency); } + } + + #endregion + + #region IPTOTransmissionInputData + + string IPTOTransmissionInputData.PTOTransmissionType + { + get { + var pto = Body[JsonKeys.Vehicle_PTO]; + if (pto == null) { + return "None"; + } + return pto[JsonKeys.Vehicle_PTO_Type].Value<string>(); + } + } + + TableData IPTOTransmissionInputData.PTOLossMap + { + get { + var pto = Body[JsonKeys.Vehicle_PTO]; + if (pto == null || pto[JsonKeys.Vehicle_PTO_LossMapFile] == null) { + return null; + } + var lossmapFile = pto[JsonKeys.Vehicle_PTO_LossMapFile]; + if (string.IsNullOrWhiteSpace(lossmapFile.Value<string>())) { + return null; + } + try { + return ReadTableData(Body.GetEx(JsonKeys.Vehicle_PTO).GetEx<string>(JsonKeys.Vehicle_PTO_LossMapFile), "LossMap"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData(Path.Combine(BasePath, lossmapFile.Value<string>()) + MissingFileSuffix, + DataSourceType.Missing); + } + } + } + + public TableData PTOCycle + { + get { + var pto = Body[JsonKeys.Vehicle_PTO]; + if (pto == null || pto[JsonKeys.Vehicle_PTO_Cycle] == null) { + return null; + } + var cycle = pto[JsonKeys.Vehicle_PTO_Cycle]; + if (string.IsNullOrWhiteSpace(cycle.Value<string>())) { + return null; + } + try { + return ReadTableData(Body.GetEx(JsonKeys.Vehicle_PTO).GetEx<string>(JsonKeys.Vehicle_PTO_Cycle), "Cycle"); + } catch (Exception) { + if (!TolerateMissing) { + throw; + } + return new TableData(Path.Combine(BasePath, cycle.Value<string>()) + MissingFileSuffix, DataSourceType.Missing); + } + } + } + + #endregion + + public string Manufacturer + { + get { return "N/A"; } + } + + public string Model + { + get { return "N.A."; } + } + + public string Date + { + get { return "N/A"; } + } + + public CertificationMethod CertificationMethod + { + get { return CertificationMethod.NotCertified; } + } + + public string CertificationNumber + { + get { return "N.A."; } + } + + public string DigestValue + { + get { return ""; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs index 88f881aeedff39c3588bdf179771683f33994bad..af787557a5dcd8bd7a6a284e15f8d83bb8915d7c 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs @@ -29,190 +29,190 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Impl; -using TUGraz.VectoCore.Models.Declaration; - -namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration -{ - public class XMLDeclarationVehicleDataProvider : AbstractDeclarationXMLComponentDataProvider, - IVehicleDeclarationInputData, IPTOTransmissionInputData - { - public XMLDeclarationVehicleDataProvider(XMLDeclarationInputDataProvider xmlInputDataProvider) - : base(xmlInputDataProvider) - { - XBasePath = VehiclePath; - } - - public string VIN - { - get { return GetElementValue(XMLNames.Vehicle_VIN); } - } - - public string LegislativeClass - { - get { return GetElementValue(XMLNames.Vehicle_LegislativeClass); } - } - - public VehicleCategory VehicleCategory - { - get { return GetElementValue(XMLNames.Vehicle_VehicleCategory).ParseEnum<VehicleCategory>(); } - } - - public Kilogram CurbMassChassis - { - get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassChassis).SI<Kilogram>(); } - } - - - public Kilogram GrossVehicleMassRating - { - get { return GetDoubleElementValue(XMLNames.Vehicle_GrossVehicleMass).SI<Kilogram>(); } - } - - public IList<ITorqueLimitInputData> TorqueLimits - { - get { - var retVal = new List<ITorqueLimitInputData>(); - var limits = - Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_TorqueLimits, XMLNames.Vehicle_TorqueLimits_Entry), - Manager); - while (limits.MoveNext()) { - retVal.Add(new TorqueLimitInputData() { - Gear = limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, "").ToInt(), - MaxTorque = - limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, "").ToDouble().SI<NewtonMeter>() - }); - } - return retVal; - } - } - - public AxleConfiguration AxleConfiguration - { - get { return AxleConfigurationHelper.Parse(GetElementValue(XMLNames.Vehicle_AxleConfiguration)); } - } - - public IList<IAxleDeclarationInputData> Axles - { - get { - var axles = Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_Components, XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, XMLNames.AxleWheels_Axles, XMLNames.AxleWheels_Axles_Axle), Manager); - - var retVal = new IAxleDeclarationInputData[axles.Count]; - while (axles.MoveNext()) { - var axleNumber = axles.Current.GetAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, "").ToInt(); - if (axleNumber < 1 || axleNumber > retVal.Length) { - throw new VectoException("Axle #{0} exceeds axle count", axleNumber); - } - if (retVal[axleNumber - 1] != null) { - throw new VectoException("Axle #{0} defined multiple times!", axleNumber); - } - var axleType = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), Manager); - var twinTyres = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_TwinTyres), Manager); - var steered = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Steered), Manager); - var tyre = - axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Tyre, XMLNames.ComponentDataWrapper), - Manager); - if (tyre == null) { - throw new VectoException("Axle #{0} contains no tyre definition", axleNumber); - } - var dimension = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Dimension), Manager); - var rollResistance = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_RRCDeclared), Manager); - var tyreTestLoad = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager); - retVal[axleNumber - 1] = new AxleInputData { - AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(), - TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value), - Steered = steered != null && XmlConvert.ToBoolean(steered.Value), - TyreTestLoad = tyreTestLoad == null ? null : tyreTestLoad.Value.ToDouble().SI<Newton>(), - RollResistanceCoefficient = rollResistance == null ? double.NaN : rollResistance.Value.ToDouble(), - Wheels = dimension == null ? null : dimension.Value, - }; - } - return retVal; - } - } - - public string ManufacturerAddress - { - get { return GetElementValue(XMLNames.Component_ManufacturerAddress); } - } - - public PerSecond EngineIdleSpeed - { - get { return GetDoubleElementValue(XMLNames.Vehicle_IdlingSpeed).RPMtoRad(); } - } - - public double RetarderRatio - { - get { return GetDoubleElementValue(XMLNames.Vehicle_RetarderRatio); } - } - - public RetarderType RetarderType - { - get { - var value = GetElementValue(XMLNames.Vehicle_RetarderType); //.ParseEnum<RetarderType>(); - switch (value) { - case "None": - return RetarderType.None; - case "Losses included in Gearbox": - return RetarderType.LossesIncludedInTransmission; - case "Engine Retarder": - return RetarderType.EngineRetarder; - case "Transmission Input Retarder": - return RetarderType.TransmissionInputRetarder; - case "Transmission Output Retarder": - return RetarderType.TransmissionOutputRetarder; - } - throw new ArgumentOutOfRangeException("RetarderType", value); - } - } - - public AngledriveType AngulargearType - { - get { return GetElementValue(XMLNames.Vehicle_AngledriveType).ParseEnum<AngledriveType>(); } - } - - public IPTOTransmissionInputData GetPTOData() - { - return this; - } - - public string PTOTransmissionType - { - get { - var shaftGearWheels = GetElementValue(Helper.Query(XMLNames.Vehicle_PTO, XMLNames.Vehicle_PTO_ShaftsGearWheels)); - if ("none".Equals(shaftGearWheels, StringComparison.InvariantCultureIgnoreCase)) { - return "None"; - } - if ("only one engaged gearwheel above oil level".Equals(shaftGearWheels, StringComparison.CurrentCultureIgnoreCase)) { - return "only one engaged gearwheel above oil level"; - } - var otherElements = GetElementValue(Helper.Query(XMLNames.Vehicle_PTO, XMLNames.Vehicle_PTO_OtherElements)); - var ptoTech = string.Format("{0} - {1}", shaftGearWheels, otherElements); - if (DeclarationData.PTOTransmission.GetTechnologies().Contains(ptoTech)) { - return ptoTech; - } - throw new VectoException("PTO Technology {0} invalid!", ptoTech); - } - } - - public TableData PTOLossMap - { - get { return null; } - } - - public TableData PTOCycle - { - get { return null; } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Impl; +using TUGraz.VectoCore.Models.Declaration; + +namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration +{ + public class XMLDeclarationVehicleDataProvider : AbstractDeclarationXMLComponentDataProvider, + IVehicleDeclarationInputData, IPTOTransmissionInputData + { + public XMLDeclarationVehicleDataProvider(XMLDeclarationInputDataProvider xmlInputDataProvider) + : base(xmlInputDataProvider) + { + XBasePath = VehiclePath; + } + + public string VIN + { + get { return GetElementValue(XMLNames.Vehicle_VIN); } + } + + public LegislativeClass LegislativeClass + { + get { return GetElementValue(XMLNames.Vehicle_LegislativeClass).ParseEnum<LegislativeClass>(); } + } + + public VehicleCategory VehicleCategory + { + get { return GetElementValue(XMLNames.Vehicle_VehicleCategory).ParseEnum<VehicleCategory>(); } + } + + public Kilogram CurbMassChassis + { + get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassChassis).SI<Kilogram>(); } + } + + + public Kilogram GrossVehicleMassRating + { + get { return GetDoubleElementValue(XMLNames.Vehicle_GrossVehicleMass).SI<Kilogram>(); } + } + + public IList<ITorqueLimitInputData> TorqueLimits + { + get { + var retVal = new List<ITorqueLimitInputData>(); + var limits = + Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_TorqueLimits, XMLNames.Vehicle_TorqueLimits_Entry), + Manager); + while (limits.MoveNext()) { + retVal.Add(new TorqueLimitInputData() { + Gear = limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, "").ToInt(), + MaxTorque = + limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, "").ToDouble().SI<NewtonMeter>() + }); + } + return retVal; + } + } + + public AxleConfiguration AxleConfiguration + { + get { return AxleConfigurationHelper.Parse(GetElementValue(XMLNames.Vehicle_AxleConfiguration)); } + } + + public IList<IAxleDeclarationInputData> Axles + { + get { + var axles = Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_Components, XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, XMLNames.AxleWheels_Axles, XMLNames.AxleWheels_Axles_Axle), Manager); + + var retVal = new IAxleDeclarationInputData[axles.Count]; + while (axles.MoveNext()) { + var axleNumber = axles.Current.GetAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, "").ToInt(); + if (axleNumber < 1 || axleNumber > retVal.Length) { + throw new VectoException("Axle #{0} exceeds axle count", axleNumber); + } + if (retVal[axleNumber - 1] != null) { + throw new VectoException("Axle #{0} defined multiple times!", axleNumber); + } + var axleType = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), Manager); + var twinTyres = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_TwinTyres), Manager); + var steered = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Steered), Manager); + var tyre = + axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Tyre, XMLNames.ComponentDataWrapper), + Manager); + if (tyre == null) { + throw new VectoException("Axle #{0} contains no tyre definition", axleNumber); + } + var dimension = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Dimension), Manager); + var rollResistance = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_RRCDeclared), Manager); + var tyreTestLoad = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager); + retVal[axleNumber - 1] = new AxleInputData { + AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(), + TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value), + Steered = steered != null && XmlConvert.ToBoolean(steered.Value), + TyreTestLoad = tyreTestLoad == null ? null : tyreTestLoad.Value.ToDouble().SI<Newton>(), + RollResistanceCoefficient = rollResistance == null ? double.NaN : rollResistance.Value.ToDouble(), + Wheels = dimension == null ? null : dimension.Value, + }; + } + return retVal; + } + } + + public string ManufacturerAddress + { + get { return GetElementValue(XMLNames.Component_ManufacturerAddress); } + } + + public PerSecond EngineIdleSpeed + { + get { return GetDoubleElementValue(XMLNames.Vehicle_IdlingSpeed).RPMtoRad(); } + } + + public double RetarderRatio + { + get { return GetDoubleElementValue(XMLNames.Vehicle_RetarderRatio); } + } + + public RetarderType RetarderType + { + get { + var value = GetElementValue(XMLNames.Vehicle_RetarderType); //.ParseEnum<RetarderType>(); + switch (value) { + case "None": + return RetarderType.None; + case "Losses included in Gearbox": + return RetarderType.LossesIncludedInTransmission; + case "Engine Retarder": + return RetarderType.EngineRetarder; + case "Transmission Input Retarder": + return RetarderType.TransmissionInputRetarder; + case "Transmission Output Retarder": + return RetarderType.TransmissionOutputRetarder; + } + throw new ArgumentOutOfRangeException("RetarderType", value); + } + } + + public AngledriveType AngulargearType + { + get { return GetElementValue(XMLNames.Vehicle_AngledriveType).ParseEnum<AngledriveType>(); } + } + + public IPTOTransmissionInputData GetPTOData() + { + return this; + } + + public string PTOTransmissionType + { + get { + var shaftGearWheels = GetElementValue(Helper.Query(XMLNames.Vehicle_PTO, XMLNames.Vehicle_PTO_ShaftsGearWheels)); + if ("none".Equals(shaftGearWheels, StringComparison.InvariantCultureIgnoreCase)) { + return "None"; + } + if ("only one engaged gearwheel above oil level".Equals(shaftGearWheels, StringComparison.CurrentCultureIgnoreCase)) { + return "only one engaged gearwheel above oil level"; + } + var otherElements = GetElementValue(Helper.Query(XMLNames.Vehicle_PTO, XMLNames.Vehicle_PTO_OtherElements)); + var ptoTech = string.Format("{0} - {1}", shaftGearWheels, otherElements); + if (DeclarationData.PTOTransmission.GetTechnologies().Contains(ptoTech)) { + return ptoTech; + } + throw new VectoException("PTO Technology {0} invalid!", ptoTech); + } + } + + public TableData PTOLossMap + { + get { return null; } + } + + public TableData PTOCycle + { + get { return null; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/XMLEngineeringVehicleDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/XMLEngineeringVehicleDataProvider.cs index c20feb6f484102dc51423a4e7ec74a61c2ebae1e..5442dfe82ef80fe3c3bdbc2db37b6be3988ecb17 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/XMLEngineeringVehicleDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/XMLEngineeringVehicleDataProvider.cs @@ -29,311 +29,311 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml; -using System.Xml.Schema; -using System.Xml.XPath; -using TUGraz.IVT.VectoXML; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Impl; - -namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering -{ - public class XMLEngineeringVehicleDataProvider : AbstractEngineeringXMLComponentDataProvider, - IVehicleEngineeringInputData, - IPTOTransmissionInputData - { - public XMLEngineeringVehicleDataProvider(XMLEngineeringInputDataProvider xmlEngineeringJobInputDataProvider, - XPathDocument vehicleDocument, string xmlBasePath, string fsBasePath) - : base(xmlEngineeringJobInputDataProvider, vehicleDocument, xmlBasePath, fsBasePath) {} - - public string GetVehicleID - { - get { return GetAttributeValue("", XMLNames.Component_ID_Attr); } - } - - public string VIN - { - get { return GetElementValue(XMLNames.Vehicle_VIN); } - } - - public string LegislativeClass - { - get { return GetElementValue(XMLNames.Vehicle_LegislativeClass); } - } - - public VehicleCategory VehicleCategory - { - get { return GetElementValue(XMLNames.Vehicle_VehicleCategory).ParseEnum<VehicleCategory>(); } - } - - public Kilogram CurbMassChassis - { - get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassChassis).SI<Kilogram>(); } - } - - public Kilogram CurbMassExtra - { - get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassExtra).SI<Kilogram>(); } - } - - public Kilogram GrossVehicleMassRating - { - get { return GetDoubleElementValue(XMLNames.Vehicle_GrossVehicleMass).SI<Kilogram>(); } - } - - public IList<ITorqueLimitInputData> TorqueLimits - { - get { - var retVal = new List<ITorqueLimitInputData>(); - var limits = - Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_TorqueLimits, XMLNames.Vehicle_TorqueLimits_Entry), - Manager); - while (limits.MoveNext()) { - retVal.Add(new TorqueLimitInputData() { - Gear = limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, "").ToInt(), - MaxTorque = - limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, "").ToDouble().SI<NewtonMeter>() - }); - } - return retVal; - } - } - - public Kilogram Loading - { - get { return GetDoubleElementValue(XMLNames.Vehicle_Loading).SI<Kilogram>(); } - } - - public Meter DynamicTyreRadius - { - get { - var queryPath = Helper.Query(XMLNames.Vehicle_Components, - XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, - XMLNames.AxleWheels_Axles, - Helper.QueryConstraint(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle), - Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), - AxleType.VehicleDriven.ToString(), ""), // query - XMLNames.AxleWheels_Axles_Axle_DynamicTyreRadius - ); - return (GetDoubleElementValue(queryPath) / 1000).SI<Meter>(); - } - } - - - public AxleConfiguration AxleConfiguration - { - get { return AxleConfigurationHelper.Parse(GetElementValue(XMLNames.Vehicle_AxleConfiguration)); } - } - - public IList<IAxleEngineeringInputData> Axles - { - get { return AxleEngineeringInput().Cast<IAxleEngineeringInputData>().ToList(); } - } - - public string ManufacturerAddress - { - get { return "N.A."; } - } - - public PerSecond EngineIdleSpeed - { - get { return null; } - } - - IList<IAxleDeclarationInputData> IVehicleDeclarationInputData.Axles - { - get { return AxleEngineeringInput().Cast<IAxleDeclarationInputData>().ToList(); } - } - - private IEnumerable<AxleInputData> AxleEngineeringInput() - { - var axlePath = Helper.Query( - XMLNames.Vehicle_Components, - XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, - XMLNames.AxleWheels_Axles, - XMLNames.AxleWheels_Axles_Axle); - var axles = - Navigator.Select(Helper.Query(XBasePath, axlePath), Manager); - - var retVal = new AxleInputData[axles.Count]; - - while (axles.MoveNext()) { - var axleNumber = axles.Current.GetAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, "").ToInt(); - if (axleNumber < 1 || axleNumber > retVal.Length) { - throw new VectoException("Axle #{0} exceeds axle count", axleNumber); - } - if (retVal[axleNumber - 1] != null) { - throw new VectoException("Axle #{0} defined multiple times!", axleNumber); - } - var dimension = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Dimension), Manager); - var rollResistance = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_RRCISO), Manager); - var tyreTestLoad = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager); - var weightShare = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_WeightShare), Manager); - var inertia = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Inertia), Manager); - var axleType = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), Manager); - var twinTyres = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_TwinTyres), Manager); - var steered = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Steered), Manager); - - retVal[axleNumber - 1] = new AxleInputData { - AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(), - TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value), - Steered = steered != null && XmlConvert.ToBoolean(steered.Value), - TyreTestLoad = tyreTestLoad == null ? null : tyreTestLoad.ValueAsDouble.SI<Newton>(), - RollResistanceCoefficient = rollResistance == null ? double.NaN : rollResistance.ValueAsDouble, - Wheels = dimension == null ? null : dimension.Value, - AxleWeightShare = weightShare == null ? 0 : weightShare.ValueAsDouble, - Inertia = inertia == null ? null : inertia.ValueAsDouble.SI<KilogramSquareMeter>() - }; - } - return retVal; - } - - public double RetarderRatio - { - get { return GetDoubleElementValue(XMLNames.Vehicle_RetarderRatio); } - } - - public RetarderType RetarderType - { - get { return GetElementValue(XMLNames.Vehicle_RetarderType).ParseEnum<RetarderType>(); } - } - - public AngledriveType AngledriveType - { - get { return GetElementValue(XMLNames.Vehicle_AngledriveType).ParseEnum<AngledriveType>(); } - } - - public IAirdragEngineeringInputData GetAirdragInputData(XmlReaderSettings settings) - { - return CreateComponentInput(XMLNames.Component_AirDrag, settings, - (a, b, c, d) => new XMLEngineeringAirdragDataProvider(a, b, c, d)); - } - - public XMLEngineeringAxlegearDataProvider GetAxleGearInputData(XmlReaderSettings settings) - { - return CreateComponentInput(XMLNames.Component_Axlegear, settings, - (a, b, c, d) => new XMLEngineeringAxlegearDataProvider(a, b, c, d)); - } - - public XMLEngineeringEngineDataProvider GetEngineInputData(XmlReaderSettings settings) - { - return CreateComponentInput(XMLNames.Component_Engine, settings, - (a, b, c, d) => new XMLEngineeringEngineDataProvider(a, b, c, d)); - } - - public XMLEngineeringRetarderDataProvider GetRetarderInputData(XmlReaderSettings settings) - { - if (!RetarderType.IsDedicatedComponent()) { - return new XMLEngineeringRetarderDataProvider(InputData, XMLDocument, - Helper.Query(XBasePath, XMLNames.Vehicle_Components, XMLNames.Component_Retarder, XMLNames.ComponentDataWrapper), - FSBasePath); - } - - return CreateComponentInput(XMLNames.Component_Retarder, settings, - (a, b, c, d) => new XMLEngineeringRetarderDataProvider(a, b, c, d)); - } - - public XMLEngineeringGearboxDataProvider GetGearboxData(XmlReaderSettings settings) - { - return CreateComponentInput(XMLNames.Component_Gearbox, settings, - (a, b, c, d) => new XMLEngineeringGearboxDataProvider(a, b, c, d)); - } - - public XMLEngineeringAuxiliaryDataProvider GetAuxiliaryData(XmlReaderSettings settings) - { - return CreateComponentInput(XMLNames.Component_Auxiliaries, settings, - (a, b, c, d) => new XMLEngineeringAuxiliaryDataProvider(a, b, c, d)); - } - - - protected T CreateComponentInput<T>(string componentName, XmlReaderSettings settings, - Func<XMLEngineeringInputDataProvider, XPathDocument, string, string, T> creator) - { - if (ElementExists(Helper.Query(XMLNames.Vehicle_Components, componentName))) { - return creator(InputData, XMLDocument, - Helper.Query(XBasePath, XMLNames.Vehicle_Components, componentName, XMLNames.ComponentDataWrapper), FSBasePath); - } - string componentPath = Helper.Query(XMLNames.Vehicle_Components, - Helper.QueryConstraint(XMLNames.ExternalResource, string.Format("@component='{0}' and @type='xml'", componentName), - null, "")); - if (!ElementExists(componentPath)) { - throw new VectoException("Component {0} not found!", componentName); - } - var componentNode = - Navigator.SelectSingleNode(Helper.Query(XBasePath, componentPath), Manager); - if (componentNode != null) { - try { - var componentFile = componentNode.GetAttribute(XMLNames.ExtResource_File_Attr, ""); - var componentDocument = new XPathDocument(XmlReader.Create(Path.Combine(FSBasePath, componentFile), settings)); - return creator(InputData, componentDocument, - Helper.QueryAbs(Helper.NSPrefix(XMLNames.VectoComponentEngineering, Constants.XML.RootNSPrefix), componentName, - XMLNames.ComponentDataWrapper), - Path.GetDirectoryName(Path.Combine(Path.GetFullPath(FSBasePath), componentFile))); - } catch (XmlSchemaValidationException validationException) { - throw new VectoException("Validation of XML-file for component {0} failed", validationException, componentName); - } - } - throw new VectoException("Component {0} not found!", componentName); - } - - public XMLEngineeringAngledriveDataProvider GetAngularGearInputData() - { - return new XMLEngineeringAngledriveDataProvider(InputData, XMLDocument, - Helper.Query(XBasePath, XMLNames.Vehicle_Components, XMLNames.Component_Angledrive, XMLNames.ComponentDataWrapper) - , FSBasePath); - } - - #region "PTO" - - public IPTOTransmissionInputData GetPTOData() - { - return this; - } - - public string PTOTransmissionType - { - get { return GetElementValue(XMLNames.Vehicle_PTOType); } - } - - public TableData PTOLossMap - { - get { - if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, XMLNames.Vehicle_PTOIdleLossMap_Entry))) { - return ReadTableData(AttributeMappings.PTOLossMap, - Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, XMLNames.Vehicle_PTOIdleLossMap_Entry)); - } - if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, ExtCsvResourceTag))) { - return ReadCSVResourceFile(XMLNames.Vehicle_PTOIdleLossMap); - } - return null; - } - } - - public TableData PTOCycle - { - get { - if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOCycle, XMLNames.Vehicle_PTOCycle_Entry))) { - return ReadTableData(AttributeMappings.PTOCycleMap, - Helper.Query(XMLNames.Vehicle_PTOCycle, XMLNames.Vehicle_PTOCycle_Entry)); - } - if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOCycle, ExtCsvResourceTag))) { - return ReadCSVResourceFile(XMLNames.Vehicle_PTOCycle); - } - return null; - } - } - - #endregion - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Schema; +using System.Xml.XPath; +using TUGraz.IVT.VectoXML; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Impl; + +namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering +{ + public class XMLEngineeringVehicleDataProvider : AbstractEngineeringXMLComponentDataProvider, + IVehicleEngineeringInputData, + IPTOTransmissionInputData + { + public XMLEngineeringVehicleDataProvider(XMLEngineeringInputDataProvider xmlEngineeringJobInputDataProvider, + XPathDocument vehicleDocument, string xmlBasePath, string fsBasePath) + : base(xmlEngineeringJobInputDataProvider, vehicleDocument, xmlBasePath, fsBasePath) {} + + public string GetVehicleID + { + get { return GetAttributeValue("", XMLNames.Component_ID_Attr); } + } + + public string VIN + { + get { return GetElementValue(XMLNames.Vehicle_VIN); } + } + + public LegislativeClass LegislativeClass + { + get { return GetElementValue(XMLNames.Vehicle_LegislativeClass).ParseEnum<LegislativeClass>(); } + } + + public VehicleCategory VehicleCategory + { + get { return GetElementValue(XMLNames.Vehicle_VehicleCategory).ParseEnum<VehicleCategory>(); } + } + + public Kilogram CurbMassChassis + { + get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassChassis).SI<Kilogram>(); } + } + + public Kilogram CurbMassExtra + { + get { return GetDoubleElementValue(XMLNames.Vehicle_CurbMassExtra).SI<Kilogram>(); } + } + + public Kilogram GrossVehicleMassRating + { + get { return GetDoubleElementValue(XMLNames.Vehicle_GrossVehicleMass).SI<Kilogram>(); } + } + + public IList<ITorqueLimitInputData> TorqueLimits + { + get { + var retVal = new List<ITorqueLimitInputData>(); + var limits = + Navigator.Select(Helper.Query(VehiclePath, XMLNames.Vehicle_TorqueLimits, XMLNames.Vehicle_TorqueLimits_Entry), + Manager); + while (limits.MoveNext()) { + retVal.Add(new TorqueLimitInputData() { + Gear = limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, "").ToInt(), + MaxTorque = + limits.Current.GetAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, "").ToDouble().SI<NewtonMeter>() + }); + } + return retVal; + } + } + + public Kilogram Loading + { + get { return GetDoubleElementValue(XMLNames.Vehicle_Loading).SI<Kilogram>(); } + } + + public Meter DynamicTyreRadius + { + get { + var queryPath = Helper.Query(XMLNames.Vehicle_Components, + XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, + XMLNames.AxleWheels_Axles, + Helper.QueryConstraint(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle), + Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), + AxleType.VehicleDriven.ToString(), ""), // query + XMLNames.AxleWheels_Axles_Axle_DynamicTyreRadius + ); + return (GetDoubleElementValue(queryPath) / 1000).SI<Meter>(); + } + } + + + public AxleConfiguration AxleConfiguration + { + get { return AxleConfigurationHelper.Parse(GetElementValue(XMLNames.Vehicle_AxleConfiguration)); } + } + + public IList<IAxleEngineeringInputData> Axles + { + get { return AxleEngineeringInput().Cast<IAxleEngineeringInputData>().ToList(); } + } + + public string ManufacturerAddress + { + get { return "N.A."; } + } + + public PerSecond EngineIdleSpeed + { + get { return null; } + } + + IList<IAxleDeclarationInputData> IVehicleDeclarationInputData.Axles + { + get { return AxleEngineeringInput().Cast<IAxleDeclarationInputData>().ToList(); } + } + + private IEnumerable<AxleInputData> AxleEngineeringInput() + { + var axlePath = Helper.Query( + XMLNames.Vehicle_Components, + XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, + XMLNames.AxleWheels_Axles, + XMLNames.AxleWheels_Axles_Axle); + var axles = + Navigator.Select(Helper.Query(XBasePath, axlePath), Manager); + + var retVal = new AxleInputData[axles.Count]; + + while (axles.MoveNext()) { + var axleNumber = axles.Current.GetAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, "").ToInt(); + if (axleNumber < 1 || axleNumber > retVal.Length) { + throw new VectoException("Axle #{0} exceeds axle count", axleNumber); + } + if (retVal[axleNumber - 1] != null) { + throw new VectoException("Axle #{0} defined multiple times!", axleNumber); + } + var dimension = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Dimension), Manager); + var rollResistance = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_RRCISO), Manager); + var tyreTestLoad = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager); + var weightShare = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_WeightShare), Manager); + var inertia = axles.Current.SelectSingleNode(Helper.Query(XMLNames.AxleWheels_Axles_Axle_Inertia), Manager); + var axleType = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_AxleType), Manager); + var twinTyres = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_TwinTyres), Manager); + var steered = axles.Current.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_Steered), Manager); + + retVal[axleNumber - 1] = new AxleInputData { + AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(), + TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value), + Steered = steered != null && XmlConvert.ToBoolean(steered.Value), + TyreTestLoad = tyreTestLoad == null ? null : tyreTestLoad.ValueAsDouble.SI<Newton>(), + RollResistanceCoefficient = rollResistance == null ? double.NaN : rollResistance.ValueAsDouble, + Wheels = dimension == null ? null : dimension.Value, + AxleWeightShare = weightShare == null ? 0 : weightShare.ValueAsDouble, + Inertia = inertia == null ? null : inertia.ValueAsDouble.SI<KilogramSquareMeter>() + }; + } + return retVal; + } + + public double RetarderRatio + { + get { return GetDoubleElementValue(XMLNames.Vehicle_RetarderRatio); } + } + + public RetarderType RetarderType + { + get { return GetElementValue(XMLNames.Vehicle_RetarderType).ParseEnum<RetarderType>(); } + } + + public AngledriveType AngledriveType + { + get { return GetElementValue(XMLNames.Vehicle_AngledriveType).ParseEnum<AngledriveType>(); } + } + + public IAirdragEngineeringInputData GetAirdragInputData(XmlReaderSettings settings) + { + return CreateComponentInput(XMLNames.Component_AirDrag, settings, + (a, b, c, d) => new XMLEngineeringAirdragDataProvider(a, b, c, d)); + } + + public XMLEngineeringAxlegearDataProvider GetAxleGearInputData(XmlReaderSettings settings) + { + return CreateComponentInput(XMLNames.Component_Axlegear, settings, + (a, b, c, d) => new XMLEngineeringAxlegearDataProvider(a, b, c, d)); + } + + public XMLEngineeringEngineDataProvider GetEngineInputData(XmlReaderSettings settings) + { + return CreateComponentInput(XMLNames.Component_Engine, settings, + (a, b, c, d) => new XMLEngineeringEngineDataProvider(a, b, c, d)); + } + + public XMLEngineeringRetarderDataProvider GetRetarderInputData(XmlReaderSettings settings) + { + if (!RetarderType.IsDedicatedComponent()) { + return new XMLEngineeringRetarderDataProvider(InputData, XMLDocument, + Helper.Query(XBasePath, XMLNames.Vehicle_Components, XMLNames.Component_Retarder, XMLNames.ComponentDataWrapper), + FSBasePath); + } + + return CreateComponentInput(XMLNames.Component_Retarder, settings, + (a, b, c, d) => new XMLEngineeringRetarderDataProvider(a, b, c, d)); + } + + public XMLEngineeringGearboxDataProvider GetGearboxData(XmlReaderSettings settings) + { + return CreateComponentInput(XMLNames.Component_Gearbox, settings, + (a, b, c, d) => new XMLEngineeringGearboxDataProvider(a, b, c, d)); + } + + public XMLEngineeringAuxiliaryDataProvider GetAuxiliaryData(XmlReaderSettings settings) + { + return CreateComponentInput(XMLNames.Component_Auxiliaries, settings, + (a, b, c, d) => new XMLEngineeringAuxiliaryDataProvider(a, b, c, d)); + } + + + protected T CreateComponentInput<T>(string componentName, XmlReaderSettings settings, + Func<XMLEngineeringInputDataProvider, XPathDocument, string, string, T> creator) + { + if (ElementExists(Helper.Query(XMLNames.Vehicle_Components, componentName))) { + return creator(InputData, XMLDocument, + Helper.Query(XBasePath, XMLNames.Vehicle_Components, componentName, XMLNames.ComponentDataWrapper), FSBasePath); + } + string componentPath = Helper.Query(XMLNames.Vehicle_Components, + Helper.QueryConstraint(XMLNames.ExternalResource, string.Format("@component='{0}' and @type='xml'", componentName), + null, "")); + if (!ElementExists(componentPath)) { + throw new VectoException("Component {0} not found!", componentName); + } + var componentNode = + Navigator.SelectSingleNode(Helper.Query(XBasePath, componentPath), Manager); + if (componentNode != null) { + try { + var componentFile = componentNode.GetAttribute(XMLNames.ExtResource_File_Attr, ""); + var componentDocument = new XPathDocument(XmlReader.Create(Path.Combine(FSBasePath, componentFile), settings)); + return creator(InputData, componentDocument, + Helper.QueryAbs(Helper.NSPrefix(XMLNames.VectoComponentEngineering, Constants.XML.RootNSPrefix), componentName, + XMLNames.ComponentDataWrapper), + Path.GetDirectoryName(Path.Combine(Path.GetFullPath(FSBasePath), componentFile))); + } catch (XmlSchemaValidationException validationException) { + throw new VectoException("Validation of XML-file for component {0} failed", validationException, componentName); + } + } + throw new VectoException("Component {0} not found!", componentName); + } + + public XMLEngineeringAngledriveDataProvider GetAngularGearInputData() + { + return new XMLEngineeringAngledriveDataProvider(InputData, XMLDocument, + Helper.Query(XBasePath, XMLNames.Vehicle_Components, XMLNames.Component_Angledrive, XMLNames.ComponentDataWrapper) + , FSBasePath); + } + + #region "PTO" + + public IPTOTransmissionInputData GetPTOData() + { + return this; + } + + public string PTOTransmissionType + { + get { return GetElementValue(XMLNames.Vehicle_PTOType); } + } + + public TableData PTOLossMap + { + get { + if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, XMLNames.Vehicle_PTOIdleLossMap_Entry))) { + return ReadTableData(AttributeMappings.PTOLossMap, + Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, XMLNames.Vehicle_PTOIdleLossMap_Entry)); + } + if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOIdleLossMap, ExtCsvResourceTag))) { + return ReadCSVResourceFile(XMLNames.Vehicle_PTOIdleLossMap); + } + return null; + } + } + + public TableData PTOCycle + { + get { + if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOCycle, XMLNames.Vehicle_PTOCycle_Entry))) { + return ReadTableData(AttributeMappings.PTOCycleMap, + Helper.Query(XMLNames.Vehicle_PTOCycle, XMLNames.Vehicle_PTOCycle_Entry)); + } + if (ElementExists(Helper.Query(XMLNames.Vehicle_PTOCycle, ExtCsvResourceTag))) { + return ReadCSVResourceFile(XMLNames.Vehicle_PTOCycle); + } + return null; + } + } + + #endregion + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Impl/InputData.cs b/VectoCore/VectoCore/InputData/Impl/InputData.cs index 5e882eedeff0805e80451c0e8bd9d5026be3f9f0..d14a8312dcf3eacad9808e9ec4442c431932db9d 100644 --- a/VectoCore/VectoCore/InputData/Impl/InputData.cs +++ b/VectoCore/VectoCore/InputData/Impl/InputData.cs @@ -29,123 +29,118 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.InputData.Impl -{ - public class CycleInputData : ICycleData - { - public string Name { get; internal set; } - - public TableData CycleData { get; internal set; } - } - - public class LookAheadCoastingInputData : ILookaheadCoastingInputData - { - public bool Enabled { get; internal set; } - - //public MeterPerSquareSecond Deceleration { get; internal set; } - - public MeterPerSecond MinSpeed { get; internal set; } - - public double CoastingDecisionFactorOffset { get; internal set; } - public double CoastingDecisionFactorScaling { get; internal set; } - public double LookaheadDistanceFactor { get; internal set; } - public TableData CoastingDecisionFactorTargetSpeedLookup { get; internal set; } - public TableData CoastingDecisionFactorVelocityDropLookup { get; internal set; } - } - - public class OverSpeedEcoRollInputData : IOverSpeedEcoRollEngineeringInputData - { - public DriverMode Mode { get; internal set; } - - public MeterPerSecond MinSpeed { get; internal set; } - - public MeterPerSecond OverSpeed { get; internal set; } - - public MeterPerSecond UnderSpeed { get; internal set; } - } - - public class TransmissionInputData : ITransmissionInputData - { - public int Gear { get; internal set; } - - public double Ratio { get; internal set; } - - public TableData LossMap { get; internal set; } - - public double Efficiency { get; internal set; } - - public NewtonMeter MaxTorque { get; internal set; } - - public PerSecond MaxInputSpeed { get; internal set; } - - public TableData ShiftPolygon { get; internal set; } - } - - public class AxleInputData : IAxleEngineeringInputData - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", - "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - public bool SavedInDeclarationMode - { - get { throw new System.NotImplementedException(); } - } - - public DataSourceType SourceType { get; internal set; } - - public string Source { get; internal set; } - - public string Wheels { get; internal set; } - - public bool TwinTyres { get; internal set; } - - public bool Steered { get; internal set; } - - public AxleType AxleType { get; internal set; } - - public double RollResistanceCoefficient { get; internal set; } - - public Newton TyreTestLoad { get; internal set; } - - public double AxleWeightShare { get; internal set; } - - public KilogramSquareMeter Inertia { get; internal set; } - } - - public class AuxiliaryDataInputData : IAuxiliaryEngineeringInputData, IAuxiliaryDeclarationInputData - { - public AuxiliaryDataInputData() - { - AuxiliaryType = AuxiliaryDemandType.Mapping; - ConstantPowerDemand = 0.SI<Watt>(); - } - - public AuxiliaryDemandType AuxiliaryType { get; internal set; } - - public string ID { get; internal set; } - - public AuxiliaryType Type { get; internal set; } - - public IList<string> Technology { get; internal set; } - - public double TransmissionRatio { get; internal set; } - - public double EfficiencyToEngine { get; internal set; } - - public double EfficiencyToSupply { get; internal set; } - - public TableData DemandMap { get; internal set; } - - public Watt ConstantPowerDemand { get; internal set; } - } - - public class TorqueLimitInputData : ITorqueLimitInputData - { - public int Gear { get; internal set; } - public NewtonMeter MaxTorque { get; internal set; } - } +using System.Collections.Generic; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.InputData.Impl +{ + public class CycleInputData : ICycleData + { + public string Name { get; internal set; } + + public TableData CycleData { get; internal set; } + } + + public class LookAheadCoastingInputData : ILookaheadCoastingInputData + { + public bool Enabled { get; internal set; } + + //public MeterPerSquareSecond Deceleration { get; internal set; } + + public MeterPerSecond MinSpeed { get; internal set; } + + public double CoastingDecisionFactorOffset { get; internal set; } + public double CoastingDecisionFactorScaling { get; internal set; } + public double LookaheadDistanceFactor { get; internal set; } + public TableData CoastingDecisionFactorTargetSpeedLookup { get; internal set; } + public TableData CoastingDecisionFactorVelocityDropLookup { get; internal set; } + } + + public class OverSpeedEcoRollInputData : IOverSpeedEcoRollEngineeringInputData + { + public DriverMode Mode { get; internal set; } + + public MeterPerSecond MinSpeed { get; internal set; } + + public MeterPerSecond OverSpeed { get; internal set; } + + public MeterPerSecond UnderSpeed { get; internal set; } + } + + public class TransmissionInputData : ITransmissionInputData + { + public int Gear { get; internal set; } + + public double Ratio { get; internal set; } + + public TableData LossMap { get; internal set; } + + public double Efficiency { get; internal set; } + + public NewtonMeter MaxTorque { get; internal set; } + + public PerSecond MaxInputSpeed { get; internal set; } + + public TableData ShiftPolygon { get; internal set; } + } + + public class AxleInputData : IAxleEngineeringInputData + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + public DataSourceType SourceType { get; internal set; } + + public string Source { get; internal set; } + + public string Wheels { get; internal set; } + + public bool TwinTyres { get; internal set; } + + public bool Steered { get; internal set; } + + public AxleType AxleType { get; internal set; } + + public double RollResistanceCoefficient { get; internal set; } + + public Newton TyreTestLoad { get; internal set; } + + public double AxleWeightShare { get; internal set; } + + public KilogramSquareMeter Inertia { get; internal set; } + } + + public class AuxiliaryDataInputData : IAuxiliaryEngineeringInputData, IAuxiliaryDeclarationInputData + { + public AuxiliaryDataInputData() + { + AuxiliaryType = AuxiliaryDemandType.Mapping; + ConstantPowerDemand = 0.SI<Watt>(); + } + + public AuxiliaryDemandType AuxiliaryType { get; internal set; } + + public string ID { get; internal set; } + + public AuxiliaryType Type { get; internal set; } + + public IList<string> Technology { get; internal set; } + + public double TransmissionRatio { get; internal set; } + + public double EfficiencyToEngine { get; internal set; } + + public double EfficiencyToSupply { get; internal set; } + + public TableData DemandMap { get; internal set; } + + public Watt ConstantPowerDemand { get; internal set; } + } + + public class TorqueLimitInputData : ITorqueLimitInputData + { + public int Gear { get; internal set; } + public NewtonMeter MaxTorque { get; internal set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index df3cc851b0f88cd2f4cdf8f25c335d2f749a7280..d135c2e77348e2cd98e7c537d0a4c11db7e54d1a 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -29,450 +29,447 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter -{ - public class DeclarationDataAdapter : AbstractSimulationDataAdapter - { - public DriverData CreateDriverData(IDriverDeclarationInputData data) - { - if (!data.SavedInDeclarationMode) { - WarnDeclarationMode("DriverData"); - } - var lookAheadData = new DriverData.LACData { - Enabled = DeclarationData.Driver.LookAhead.Enabled, - //Deceleration = DeclarationData.Driver.LookAhead.Deceleration, - MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed, - LookAheadDecisionFactor = new LACDecisionFactor(), - LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, - }; - var overspeedData = new DriverData.OverSpeedEcoRollData { - Mode = data.OverSpeedEcoRoll.Mode, - MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed, - OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed, - UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed - }; - if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) { - throw new VectoSimulationException( - "Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}", - overspeedData.Mode); - } - var retVal = new DriverData { - LookAheadCoasting = lookAheadData, - OverSpeedEcoRoll = overspeedData, - }; - return retVal; - } - - internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading, - Kilogram municipalBodyWeight) - { - if (!data.SavedInDeclarationMode) { - WarnDeclarationMode("VehicleData"); - } - - var retVal = SetCommonVehicleData(data); - retVal.VIN = data.VIN; - retVal.ManufacturerAddress = data.ManufacturerAddress; - retVal.LegislativeClass = data.LegislativeClass; - retVal.TrailerGrossVehicleWeight = mission.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0); - - retVal.BodyAndTrailerWeight = (mission.MissionType == MissionType.MunicipalUtility - ? municipalBodyWeight - : mission.BodyCurbWeight) + mission.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0); - //retVal.CurbWeight += retVal.BodyAndTrailerWeight; - - retVal.Loading = loading; - var drivenIndex = DrivenAxleIndex(data.Axles); - retVal.DynamicTyreRadius = - DeclarationData.Wheels.Lookup(data.Axles[drivenIndex].Wheels).DynamicTyreRadius; - retVal.CargoVolume = mission.MissionType != MissionType.Construction ? mission.TotalCargoVolume : 0.SI<CubicMeter>(); - - - var axles = data.Axles; - if (axles.Count < mission.AxleWeightDistribution.Length) { - throw new VectoException("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required", - data.Axles.Count, mission.AxleWeightDistribution.Length); - } - var axleData = new List<Axle>(); - for (var i = 0; i < mission.AxleWeightDistribution.Length; i++) { - var axleInput = axles[i]; - var axle = new Axle { - WheelsDimension = axleInput.Wheels, - AxleType = axleInput.AxleType, - AxleWeightShare = mission.AxleWeightDistribution[i], - TwinTyres = axleInput.TwinTyres, - RollResistanceCoefficient = axleInput.RollResistanceCoefficient, - TyreTestLoad = axleInput.TyreTestLoad, - Inertia = DeclarationData.Wheels.Lookup(axleInput.Wheels.RemoveWhitespace()).Inertia, - }; - axleData.Add(axle); - } - - foreach (var trailer in mission.Trailer) { - axleData.AddRange(trailer.TrailerWheels.Select(trailerWheel => new Axle { - AxleType = AxleType.Trailer, - AxleWeightShare = trailer.TrailerAxleWeightShare / trailer.TrailerWheels.Count, - TwinTyres = DeclarationData.Trailer.TwinTyres, - RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, - TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), - Inertia = trailerWheel.Inertia - })); - } - retVal.AxleData = axleData; - return retVal; - } - - private static int DrivenAxleIndex(IList<IAxleDeclarationInputData> axles) - { - for (var i = 0; i < axles.Count; i++) { - if (axles[i].AxleType != AxleType.VehicleDriven) { - continue; - } - return i; - } - return DeclarationData.PoweredAxle(); - } - - internal CombustionEngineData CreateEngineData(IEngineDeclarationInputData engine, PerSecond vehicleEngineIdleSpeed, - IGearboxDeclarationInputData gearbox, IEnumerable<ITorqueLimitInputData> torqueLimits) - { - if (!engine.SavedInDeclarationMode) { - WarnDeclarationMode("EngineData"); - } - - var retVal = SetCommonCombustionEngineData(engine); - retVal.IdleSpeed = VectoMath.Max(engine.IdleSpeed, vehicleEngineIdleSpeed); - retVal.WHTCUrban = engine.WHTCUrban; - retVal.WHTCMotorway = engine.WHTCMotorway; - retVal.WHTCRural = engine.WHTCRural; - retVal.ColdHotCorrectionFactor = engine.ColdHotBalancingFactor; - retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement, gearbox.Type); - var limits = torqueLimits.ToDictionary(e => e.Gear); - var numGears = gearbox.Gears.Count; - var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); - fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve, true); - fullLoadCurves[0].EngineData = retVal; - foreach (var gear in gearbox.Gears) { - var maxTorque = VectoMath.Min( - GbxMaxTorque(gear, numGears, fullLoadCurves[0].MaxTorque), - VehMaxTorque(gear, numGears, limits, fullLoadCurves[0].MaxTorque)); - fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque); - } - retVal.FullLoadCurves = fullLoadCurves; - return retVal; - } - - private static NewtonMeter VehMaxTorque(ITransmissionInputData gear, int numGears, - Dictionary<int, ITorqueLimitInputData> limits, - NewtonMeter maxEngineTorque) - { - if (gear.Gear - 1 >= numGears / 2) { - // only upper half of gears can limit if max-torque <= 0.95 of engine max torque - if (limits.ContainsKey(gear.Gear) && - limits[gear.Gear].MaxTorque <= DeclarationData.Engine.TorqueLimitVehicleFactor * maxEngineTorque) { - return limits[gear.Gear].MaxTorque; - } - } - return null; - } - - private static NewtonMeter GbxMaxTorque(ITransmissionInputData gear, int numGears, NewtonMeter maxEngineTorque - ) - { - if (gear.Gear - 1 < numGears / 2) { - // gears count from 1 to n, -> n entries, lower half can always limit - if (gear.MaxTorque != null) { - return gear.MaxTorque; - } - } else { - // upper half can only limit if max-torque <= 90% of engine max torque - if (gear.MaxTorque != null && gear.MaxTorque <= DeclarationData.Engine.TorqueLimitGearboxFactor * maxEngineTorque) { - return gear.MaxTorque; - } - } - return null; - } - - internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine, - double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback) - { - if (!gearbox.SavedInDeclarationMode) { - WarnDeclarationMode("GearboxData"); - } - var retVal = SetCommonGearboxData(gearbox); - switch (gearbox.Type) { - case GearboxType.DrivingCycle: - case GearboxType.ATPowerSplit: - throw new VectoSimulationException( - "Unsupported gearbox type: {0}!", retVal.Type); - //case GearboxType.Custom: - // throw new VectoSimulationException("Custom Transmission not supported in DeclarationMode!"); - } - var gearsInput = gearbox.Gears; - if (gearsInput.Count < 1) { - throw new VectoSimulationException( - "At least one Gear-Entry must be defined in Gearbox!"); - } - - SetDeclarationData(retVal); - - var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2 - ? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio - : 1.0; - - var gears = new Dictionary<uint, GearData>(); - var tcShiftPolygon = DeclarationData.TorqueConverter.ComputeShiftPolygon(engine.FullLoadCurves[0]); - for (uint i = 0; i < gearsInput.Count; i++) { - var gear = gearsInput[(int)i]; - var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, true); - - var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engine.FullLoadCurves[i + 1], - gearsInput, engine, - axlegearRatio, dynamicTyreRadius); - - var gearData = new GearData { - ShiftPolygon = shiftPolygon, - MaxSpeed = gear.MaxInputSpeed, - Ratio = gear.Ratio, - LossMap = lossMap, - }; - - if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) { - // powersplit transmission: torque converter already contains ratio and losses - CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon); - } - if (gearbox.Type == GearboxType.ATSerial) { - if (i == 0) { - // torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode - CreateTCFirstGearATSerial(gearData, tcShiftPolygon); - } - if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) { - // ratio between first and second gear is above threshold, torqueconverter is active in second gear as well - // -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear - CreateTCSecondGearATSerial(gearData, tcShiftPolygon); - // NOTE: the lower gear in 'gears' dictionary has index i !! - gears[i].Ratio = double.NaN; - gears[i].LossMap = null; - } - } - gears.Add(i + 1, gearData); - } - retVal.Gears = gears; - if (retVal.Type.AutomaticTransmission()) { - var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio; - retVal.PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime; - retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData, - DeclarationData.TorqueConverter.ReferenceRPM, DeclarationData.TorqueConverter.MaxInputSpeed, - ExecutionMode.Declaration, ratio, - DeclarationData.TorqueConverter.CLUpshiftMinAcceleration, DeclarationData.TorqueConverter.CCUpshiftMinAcceleration); - } - - return retVal; - } - - private static void SetDeclarationData(GearboxData retVal) - { - retVal.Inertia = DeclarationData.Gearbox.Inertia; - retVal.TractionInterruption = retVal.Type.TractionInterruption(); - retVal.TorqueReserve = DeclarationData.Gearbox.TorqueReserve; - retVal.StartTorqueReserve = DeclarationData.Gearbox.TorqueReserveStart; - retVal.ShiftTime = DeclarationData.Gearbox.MinTimeBetweenGearshifts; - retVal.StartSpeed = DeclarationData.Gearbox.StartSpeed; - retVal.StartAcceleration = DeclarationData.Gearbox.StartAcceleration; - retVal.DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay; - retVal.UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay; - retVal.UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration; - } - - public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData, - MissionType mission, VehicleClass hvdClass) - { - if (!auxInputData.SavedInDeclarationMode) { - WarnDeclarationMode("AuxiliariesData"); - } - var retVal = new List<VectoRunData.AuxData>(); - - if (auxInputData.Auxiliaries.Count != 5) { - Log.Error( - "In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System."); - throw new VectoException( - "In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System."); - } - - foreach (var auxType in EnumHelper.GetValues<AuxiliaryType>()) { - var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => a.Type == auxType); - if (auxData == null) { - throw new VectoException("Auxiliary {0} not found.", auxType); - } - var aux = new VectoRunData.AuxData { - DemandType = AuxiliaryDemandType.Constant, - Technology = auxData.Technology - }; - - mission = mission.GetNonEMSMissionType(); - switch (auxType) { - case AuxiliaryType.Fan: - aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.FirstOrDefault()); - aux.ID = Constants.Auxiliaries.IDs.Fan; - break; - case AuxiliaryType.SteeringPump: - aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology); - aux.ID = Constants.Auxiliaries.IDs.SteeringPump; - break; - case AuxiliaryType.HVAC: - aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, - auxData.Technology.FirstOrDefault(), hvdClass); - aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition; - break; - case AuxiliaryType.PneumaticSystem: - aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.FirstOrDefault()); - aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem; - break; - case AuxiliaryType.ElectricSystem: - aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.FirstOrDefault()); - aux.ID = Constants.Auxiliaries.IDs.ElectricSystem; - break; - default: - continue; - } - retVal.Add(aux); - } - return retVal; - } - - private void WarnDeclarationMode(string inputData) - { - Log.Warn("{0} not in Declaration Mode!", inputData); - } - - public RetarderData CreateRetarderData(IRetarderInputData retarder) - { - return SetCommonRetarderData(retarder); - } - - public static List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> GetDeclarationAirResistanceCurve( - string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight) - { - const int startSpeed = 60; - const int maxSpeed = 130; - const int speedStep = 5; - - const int maxAlpha = 180; - const int alphaStep = 10; - - const int startHeightPercent = 5; - const int maxHeightPercent = 100; - const int heightPercentStep = 10; - const double heightShare = (double)heightPercentStep / maxHeightPercent; - - var values = DeclarationData.AirDrag.Lookup(crosswindCorrectionParameters); - - // first entry (0m/s) will get CdxA of second entry. - var points = new List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> { - new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { - Velocity = 0.SI<MeterPerSecond>(), - EffectiveCrossSectionArea = 0.SI<SquareMeter>() - } - }; - - for (var speed = startSpeed; speed <= maxSpeed; speed += speedStep) { - var vVeh = speed.KMPHtoMeterPerSecond(); - - var cdASum = 0.SI<SquareMeter>(); - - for (var heightPercent = startHeightPercent; heightPercent < maxHeightPercent; heightPercent += heightPercentStep) { - var height = heightPercent / 100.0 * vehicleHeight; - var vWind = Physics.BaseWindSpeed * Math.Pow(height / Physics.BaseWindHeight, Physics.HellmannExponent); - - for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) { - var vAirX = vVeh + vWind * Math.Cos(alpha.ToRadian()); - var vAirY = vWind * Math.Sin(alpha.ToRadian()); - - var beta = Math.Atan(vAirY / vAirX).ToDegree(); - - // ΔCdxA = A1β + A2β² + A3β³ - var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta; - - // CdxA(β) = CdxA(0) + ΔCdxA(β) - var cdA = aerodynamicDragAera + deltaCdA; - - var share = (alpha == 0 || alpha == maxAlpha ? alphaStep / 2.0 : alphaStep) / maxAlpha; - - // v_air = sqrt(v_airX²+vAirY²) - // cdASum = CdxA(β) * v_air²/v_veh² - cdASum += heightShare * share * cdA * (vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh); - } - } - points.Add(new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { - Velocity = vVeh, - EffectiveCrossSectionArea = cdASum - }); - } - - points[0].EffectiveCrossSectionArea = points[1].EffectiveCrossSectionArea; - return points; - } - - public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto) - { - if (pto.PTOTransmissionType != "None") { - return new PTOData { - TransmissionType = pto.PTOTransmissionType, - LossMap = PTOIdleLossMapReader.GetZeroLossMap(), - }; - } - - return null; - } - - public AirdragData CreateAirdragData(IAirdragDeclarationInputData airdragInputData, Mission mission, - Segment segment) - { - if (airdragInputData == null || airdragInputData.AirDragArea == null) { - return DefaultAirdragData(mission, segment); - } - - var retVal = SetCommonAirdragData(airdragInputData); - var aerodynamicDragArea = airdragInputData.AirDragArea + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0); - - retVal.DeclaredAirdragArea = airdragInputData.AirDragArea; - retVal.CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(aerodynamicDragArea, - GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight), - CrossWindCorrectionMode.DeclarationModeCorrection); - return retVal; - } - - private AirdragData DefaultAirdragData(Mission mission, Segment segment) - { - var aerodynamicDragArea = mission.MissionType == MissionType.Construction - ? segment.CdAConstruction - : segment.CdADefault + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0); - - return new AirdragData() { - CertificationMethod = CertificationMethod.StandardValues, - DeclaredAirdragArea = mission.MissionType == MissionType.Construction ? segment.CdAConstruction : segment.CdADefault, - CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(aerodynamicDragArea, - GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight), - CrossWindCorrectionMode.DeclarationModeCorrection) - }; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter +{ + public class DeclarationDataAdapter : AbstractSimulationDataAdapter + { + public DriverData CreateDriverData(IDriverDeclarationInputData data) + { + if (!data.SavedInDeclarationMode) { + WarnDeclarationMode("DriverData"); + } + var lookAheadData = new DriverData.LACData { + Enabled = DeclarationData.Driver.LookAhead.Enabled, + //Deceleration = DeclarationData.Driver.LookAhead.Deceleration, + MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed, + LookAheadDecisionFactor = new LACDecisionFactor(), + LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, + }; + var overspeedData = new DriverData.OverSpeedEcoRollData { + Mode = data.OverSpeedEcoRoll.Mode, + MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed, + OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed, + UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed + }; + if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) { + throw new VectoSimulationException( + "Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}", + overspeedData.Mode); + } + var retVal = new DriverData { + LookAheadCoasting = lookAheadData, + OverSpeedEcoRoll = overspeedData, + }; + return retVal; + } + + internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading, + Kilogram municipalBodyWeight) + { + if (!data.SavedInDeclarationMode) { + WarnDeclarationMode("VehicleData"); + } + + var retVal = SetCommonVehicleData(data); + retVal.VIN = data.VIN; + retVal.ManufacturerAddress = data.ManufacturerAddress; + retVal.LegislativeClass = data.LegislativeClass; + retVal.TrailerGrossVehicleWeight = mission.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0); + + retVal.BodyAndTrailerWeight = (mission.MissionType == MissionType.MunicipalUtility + ? municipalBodyWeight + : mission.BodyCurbWeight) + mission.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0); + + retVal.Loading = loading; + retVal.DynamicTyreRadius = + data.Axles.Where(axle => axle.AxleType == AxleType.VehicleDriven) + .Select(da => DeclarationData.Wheels.Lookup(da.Wheels).DynamicTyreRadius) + .Average(); + retVal.CargoVolume = mission.MissionType != MissionType.Construction ? mission.TotalCargoVolume : 0.SI<CubicMeter>(); + + + var axles = data.Axles; + if (axles.Count < mission.AxleWeightDistribution.Length) { + throw new VectoException("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required", + data.Axles.Count, mission.AxleWeightDistribution.Length); + } + var axleData = new List<Axle>(); + for (var i = 0; i < mission.AxleWeightDistribution.Length; i++) { + var axleInput = axles[i]; + var axle = new Axle { + WheelsDimension = axleInput.Wheels, + AxleType = axleInput.AxleType, + AxleWeightShare = mission.AxleWeightDistribution[i], + TwinTyres = axleInput.TwinTyres, + RollResistanceCoefficient = axleInput.RollResistanceCoefficient, + TyreTestLoad = axleInput.TyreTestLoad, + Inertia = DeclarationData.Wheels.Lookup(axleInput.Wheels.RemoveWhitespace()).Inertia, + }; + axleData.Add(axle); + } + + foreach (var trailer in mission.Trailer) { + axleData.AddRange(trailer.TrailerWheels.Select(trailerWheel => new Axle { + AxleType = AxleType.Trailer, + AxleWeightShare = trailer.TrailerAxleWeightShare / trailer.TrailerWheels.Count, + TwinTyres = DeclarationData.Trailer.TwinTyres, + RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient, + TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(), + Inertia = trailerWheel.Inertia + })); + } + retVal.AxleData = axleData; + return retVal; + } + + + internal CombustionEngineData CreateEngineData(IEngineDeclarationInputData engine, PerSecond vehicleEngineIdleSpeed, + IGearboxDeclarationInputData gearbox, IEnumerable<ITorqueLimitInputData> torqueLimits) + { + if (!engine.SavedInDeclarationMode) { + WarnDeclarationMode("EngineData"); + } + + var retVal = SetCommonCombustionEngineData(engine); + retVal.IdleSpeed = VectoMath.Max(engine.IdleSpeed, vehicleEngineIdleSpeed); + retVal.WHTCUrban = engine.WHTCUrban; + retVal.WHTCMotorway = engine.WHTCMotorway; + retVal.WHTCRural = engine.WHTCRural; + retVal.ColdHotCorrectionFactor = engine.ColdHotBalancingFactor; + retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement, gearbox.Type); + var limits = torqueLimits.ToDictionary(e => e.Gear); + var numGears = gearbox.Gears.Count; + var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); + fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve, true); + fullLoadCurves[0].EngineData = retVal; + foreach (var gear in gearbox.Gears) { + var maxTorque = VectoMath.Min( + GbxMaxTorque(gear, numGears, fullLoadCurves[0].MaxTorque), + VehMaxTorque(gear, numGears, limits, fullLoadCurves[0].MaxTorque)); + fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque); + } + retVal.FullLoadCurves = fullLoadCurves; + return retVal; + } + + private static NewtonMeter VehMaxTorque(ITransmissionInputData gear, int numGears, + Dictionary<int, ITorqueLimitInputData> limits, + NewtonMeter maxEngineTorque) + { + if (gear.Gear - 1 >= numGears / 2) { + // only upper half of gears can limit if max-torque <= 0.95 of engine max torque + if (limits.ContainsKey(gear.Gear) && + limits[gear.Gear].MaxTorque <= DeclarationData.Engine.TorqueLimitVehicleFactor * maxEngineTorque) { + return limits[gear.Gear].MaxTorque; + } + } + return null; + } + + private static NewtonMeter GbxMaxTorque(ITransmissionInputData gear, int numGears, NewtonMeter maxEngineTorque + ) + { + if (gear.Gear - 1 < numGears / 2) { + // gears count from 1 to n, -> n entries, lower half can always limit + if (gear.MaxTorque != null) { + return gear.MaxTorque; + } + } else { + // upper half can only limit if max-torque <= 90% of engine max torque + if (gear.MaxTorque != null && gear.MaxTorque <= DeclarationData.Engine.TorqueLimitGearboxFactor * maxEngineTorque) { + return gear.MaxTorque; + } + } + return null; + } + + internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine, + double axlegearRatio, Meter dynamicTyreRadius, VehicleCategory vehicleCategory, bool useEfficiencyFallback) + { + if (!gearbox.SavedInDeclarationMode) { + WarnDeclarationMode("GearboxData"); + } + var retVal = SetCommonGearboxData(gearbox); + switch (gearbox.Type) { + case GearboxType.DrivingCycle: + case GearboxType.ATPowerSplit: + throw new VectoSimulationException( + "Unsupported gearbox type: {0}!", retVal.Type); + //case GearboxType.Custom: + // throw new VectoSimulationException("Custom Transmission not supported in DeclarationMode!"); + } + var gearsInput = gearbox.Gears; + if (gearsInput.Count < 1) { + throw new VectoSimulationException( + "At least one Gear-Entry must be defined in Gearbox!"); + } + + SetDeclarationData(retVal); + + var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2 + ? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio + : 1.0; + + var gears = new Dictionary<uint, GearData>(); + var tcShiftPolygon = DeclarationData.TorqueConverter.ComputeShiftPolygon(engine.FullLoadCurves[0]); + for (uint i = 0; i < gearsInput.Count; i++) { + var gear = gearsInput[(int)i]; + var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, true); + + var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engine.FullLoadCurves[i + 1], + gearsInput, engine, + axlegearRatio, dynamicTyreRadius); + + var gearData = new GearData { + ShiftPolygon = shiftPolygon, + MaxSpeed = gear.MaxInputSpeed, + Ratio = gear.Ratio, + LossMap = lossMap, + }; + + CreateATGearData(gearbox, i, gearData, tcShiftPolygon, gearDifferenceRatio, gears, vehicleCategory); + gears.Add(i + 1, gearData); + } + retVal.Gears = gears; + if (retVal.Type.AutomaticTransmission()) { + var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio; + retVal.PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime; + retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData, + DeclarationData.TorqueConverter.ReferenceRPM, DeclarationData.TorqueConverter.MaxInputSpeed, + ExecutionMode.Declaration, ratio, + DeclarationData.TorqueConverter.CLUpshiftMinAcceleration, DeclarationData.TorqueConverter.CCUpshiftMinAcceleration); + } + + return retVal; + } + + private static void CreateATGearData(IGearboxDeclarationInputData gearbox, uint i, GearData gearData, + ShiftPolygon tcShiftPolygon, double gearDifferenceRatio, Dictionary<uint, GearData> gears, + VehicleCategory vehicleCategory) + { + if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) { + // powersplit transmission: torque converter already contains ratio and losses + CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon); + } + if (gearbox.Type == GearboxType.ATSerial) { + if (i == 0) { + // torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode + CreateTCFirstGearATSerial(gearData, tcShiftPolygon); + } + if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold(vehicleCategory)) { + // ratio between first and second gear is above threshold, torqueconverter is active in second gear as well + // -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear + CreateTCSecondGearATSerial(gearData, tcShiftPolygon); + // NOTE: the lower gear in 'gears' dictionary has index i !! + gears[i].Ratio = double.NaN; + gears[i].LossMap = null; + } + } + } + + private static void SetDeclarationData(GearboxData retVal) + { + retVal.Inertia = DeclarationData.Gearbox.Inertia; + retVal.TractionInterruption = retVal.Type.TractionInterruption(); + retVal.TorqueReserve = DeclarationData.Gearbox.TorqueReserve; + retVal.StartTorqueReserve = DeclarationData.Gearbox.TorqueReserveStart; + retVal.ShiftTime = DeclarationData.Gearbox.MinTimeBetweenGearshifts; + retVal.StartSpeed = DeclarationData.Gearbox.StartSpeed; + retVal.StartAcceleration = DeclarationData.Gearbox.StartAcceleration; + retVal.DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay; + retVal.UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay; + retVal.UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration; + } + + public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData, + MissionType mission, VehicleClass hvdClass) + { + if (!auxInputData.SavedInDeclarationMode) { + WarnDeclarationMode("AuxiliariesData"); + } + var retVal = new List<VectoRunData.AuxData>(); + + if (auxInputData.Auxiliaries.Count != 5) { + Log.Error( + "In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System."); + throw new VectoException( + "In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System."); + } + + foreach (var auxType in EnumHelper.GetValues<AuxiliaryType>()) { + var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => a.Type == auxType); + if (auxData == null) { + throw new VectoException("Auxiliary {0} not found.", auxType); + } + var aux = new VectoRunData.AuxData { + DemandType = AuxiliaryDemandType.Constant, + Technology = auxData.Technology + }; + + mission = mission.GetNonEMSMissionType(); + switch (auxType) { + case AuxiliaryType.Fan: + aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.FirstOrDefault()).PowerDemand; + aux.ID = Constants.Auxiliaries.IDs.Fan; + break; + case AuxiliaryType.SteeringPump: + aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology); + aux.ID = Constants.Auxiliaries.IDs.SteeringPump; + break; + case AuxiliaryType.HVAC: + aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, + auxData.Technology.FirstOrDefault(), hvdClass).PowerDemand; + aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition; + break; + case AuxiliaryType.PneumaticSystem: + aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.FirstOrDefault()).PowerDemand; + aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem; + break; + case AuxiliaryType.ElectricSystem: + aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.FirstOrDefault()).PowerDemand; + aux.ID = Constants.Auxiliaries.IDs.ElectricSystem; + break; + default: + continue; + } + retVal.Add(aux); + } + return retVal; + } + + private void WarnDeclarationMode(string inputData) + { + Log.Warn("{0} not in Declaration Mode!", inputData); + } + + public RetarderData CreateRetarderData(IRetarderInputData retarder) + { + return SetCommonRetarderData(retarder); + } + + public static List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> GetDeclarationAirResistanceCurve( + string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight) + { + const int startSpeed = 60; + const int maxSpeed = 130; + const int speedStep = 5; + + const int maxAlpha = 180; + const int alphaStep = 10; + + const int startHeightPercent = 5; + const int maxHeightPercent = 100; + const int heightPercentStep = 10; + const double heightShare = (double)heightPercentStep / maxHeightPercent; + + var values = DeclarationData.AirDrag.Lookup(crosswindCorrectionParameters); + + // first entry (0m/s) will get CdxA of second entry. + var points = new List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> { + new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { + Velocity = 0.SI<MeterPerSecond>(), + EffectiveCrossSectionArea = 0.SI<SquareMeter>() + } + }; + + for (var speed = startSpeed; speed <= maxSpeed; speed += speedStep) { + var vVeh = speed.KMPHtoMeterPerSecond(); + + var cdASum = 0.SI<SquareMeter>(); + + for (var heightPercent = startHeightPercent; heightPercent < maxHeightPercent; heightPercent += heightPercentStep) { + var height = heightPercent / 100.0 * vehicleHeight; + var vWind = Physics.BaseWindSpeed * Math.Pow(height / Physics.BaseWindHeight, Physics.HellmannExponent); + + for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) { + var vAirX = vVeh + vWind * Math.Cos(alpha.ToRadian()); + var vAirY = vWind * Math.Sin(alpha.ToRadian()); + + var beta = Math.Atan(vAirY / vAirX).ToDegree(); + + // ΔCdxA = A1β + A2β² + A3β³ + var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta; + + // CdxA(β) = CdxA(0) + ΔCdxA(β) + var cdA = aerodynamicDragAera + deltaCdA; + + var share = (alpha == 0 || alpha == maxAlpha ? alphaStep / 2.0 : alphaStep) / maxAlpha; + + // v_air = sqrt(v_airX²+vAirY²) + // cdASum = CdxA(β) * v_air²/v_veh² + cdASum += heightShare * share * cdA * (vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh); + } + } + points.Add(new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry { + Velocity = vVeh, + EffectiveCrossSectionArea = cdASum + }); + } + + points[0].EffectiveCrossSectionArea = points[1].EffectiveCrossSectionArea; + return points; + } + + public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto) + { + if (pto.PTOTransmissionType != "None") { + return new PTOData { + TransmissionType = pto.PTOTransmissionType, + LossMap = PTOIdleLossMapReader.GetZeroLossMap(), + }; + } + + return null; + } + + public AirdragData CreateAirdragData(IAirdragDeclarationInputData airdragInputData, Mission mission, + Segment segment) + { + if (airdragInputData == null || airdragInputData.AirDragArea == null) { + return DefaultAirdragData(mission, segment); + } + + var retVal = SetCommonAirdragData(airdragInputData); + var aerodynamicDragArea = airdragInputData.AirDragArea + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0); + + retVal.DeclaredAirdragArea = airdragInputData.AirDragArea; + retVal.CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(aerodynamicDragArea, + GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight), + CrossWindCorrectionMode.DeclarationModeCorrection); + return retVal; + } + + private AirdragData DefaultAirdragData(Mission mission, Segment segment) + { + var aerodynamicDragArea = mission.MissionType == MissionType.Construction + ? segment.CdAConstruction + : segment.CdADefault + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0); + + return new AirdragData() { + CertificationMethod = CertificationMethod.StandardValues, + DeclaredAirdragArea = mission.MissionType == MissionType.Construction ? segment.CdAConstruction : segment.CdADefault, + CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(aerodynamicDragArea, + GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight), + CrossWindCorrectionMode.DeclarationModeCorrection) + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index f1abfcb4b498409916c09f9a9ef432a10d5d787c..813e4d2eb9c71a825ea2aee2dd787e5d1699cd6a 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -29,337 +29,346 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; - -namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter -{ - public class EngineeringDataAdapter : AbstractSimulationDataAdapter - { - internal VehicleData CreateVehicleData(IVehicleEngineeringInputData data) - { - if (data.SavedInDeclarationMode) { - WarnEngineeringMode("VehicleData"); - } - - var retVal = SetCommonVehicleData(data); - retVal.BodyAndTrailerWeight = data.CurbMassExtra; - //retVal.CurbWeight += data.CurbMassExtra; - retVal.TrailerGrossVehicleWeight = 0.SI<Kilogram>(); - retVal.Loading = data.Loading; - retVal.DynamicTyreRadius = data.DynamicTyreRadius; - var axles = data.Axles; - - retVal.AxleData = axles.Select(axle => new Axle { - WheelsDimension = axle.Wheels, - Inertia = axle.Inertia, - TwinTyres = axle.TwinTyres, - RollResistanceCoefficient = axle.RollResistanceCoefficient, - AxleWeightShare = axle.AxleWeightShare, - TyreTestLoad = axle.TyreTestLoad, - //Wheels = axle.WheelsStr - }).ToList(); - return retVal; - } - - public AirdragData CreateAirdragData(IAirdragEngineeringInputData airdragData, IVehicleEngineeringInputData data) - { - var retVal = SetCommonAirdragData(airdragData); - retVal.CrossWindCorrectionMode = airdragData.CrossWindCorrectionMode; - - switch (airdragData.CrossWindCorrectionMode) { - case CrossWindCorrectionMode.NoCorrection: +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; + +namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter +{ + public class EngineeringDataAdapter : AbstractSimulationDataAdapter + { + internal VehicleData CreateVehicleData(IVehicleEngineeringInputData data) + { + if (data.SavedInDeclarationMode) { + WarnEngineeringMode("VehicleData"); + } + + var retVal = SetCommonVehicleData(data); + retVal.BodyAndTrailerWeight = data.CurbMassExtra; + //retVal.CurbWeight += data.CurbMassExtra; + retVal.TrailerGrossVehicleWeight = 0.SI<Kilogram>(); + retVal.Loading = data.Loading; + retVal.DynamicTyreRadius = data.DynamicTyreRadius; + var axles = data.Axles; + + retVal.AxleData = axles.Select(axle => new Axle { + WheelsDimension = axle.Wheels, + Inertia = axle.Inertia, + TwinTyres = axle.TwinTyres, + RollResistanceCoefficient = axle.RollResistanceCoefficient, + AxleWeightShare = axle.AxleWeightShare, + TyreTestLoad = axle.TyreTestLoad, + AxleType = axle.AxleType, + //Wheels = axle.WheelsStr + }).ToList(); + return retVal; + } + + public AirdragData CreateAirdragData(IAirdragEngineeringInputData airdragData, IVehicleEngineeringInputData data) + { + var retVal = SetCommonAirdragData(airdragData); + retVal.CrossWindCorrectionMode = airdragData.CrossWindCorrectionMode; + + switch (airdragData.CrossWindCorrectionMode) { + case CrossWindCorrectionMode.NoCorrection: retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(airdragData.AirDragArea), - CrossWindCorrectionMode.NoCorrection); - break; - case CrossWindCorrectionMode.SpeedDependentCorrectionFactor: - retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, - CrossWindCorrectionCurveReader.ReadSpeedDependentCorrectionCurve(airdragData.CrosswindCorrectionMap, - airdragData.AirDragArea), CrossWindCorrectionMode.SpeedDependentCorrectionFactor); - break; - case CrossWindCorrectionMode.VAirBetaLookupTable: - retVal.CrossWindCorrectionCurve = new CrosswindCorrectionVAirBeta(airdragData.AirDragArea, - CrossWindCorrectionCurveReader.ReadCdxABetaTable(airdragData.CrosswindCorrectionMap)); - break; - case CrossWindCorrectionMode.DeclarationModeCorrection: + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(airdragData.AirDragArea), + CrossWindCorrectionMode.NoCorrection); + break; + case CrossWindCorrectionMode.SpeedDependentCorrectionFactor: + retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea, + CrossWindCorrectionCurveReader.ReadSpeedDependentCorrectionCurve(airdragData.CrosswindCorrectionMap, + airdragData.AirDragArea), CrossWindCorrectionMode.SpeedDependentCorrectionFactor); + break; + case CrossWindCorrectionMode.VAirBetaLookupTable: + retVal.CrossWindCorrectionCurve = new CrosswindCorrectionVAirBeta(airdragData.AirDragArea, + CrossWindCorrectionCurveReader.ReadCdxABetaTable(airdragData.CrosswindCorrectionMap)); + break; + case CrossWindCorrectionMode.DeclarationModeCorrection: var airDragArea = airdragData.AirDragArea ?? DeclarationData.Segments.LookupCdA(data.VehicleCategory, data.AxleConfiguration, data.GrossVehicleMassRating); - var height = DeclarationData.Segments.LookupHeight(data.VehicleCategory, data.AxleConfiguration, - data.GrossVehicleMassRating); + var height = DeclarationData.Segments.LookupHeight(data.VehicleCategory, data.AxleConfiguration, + data.GrossVehicleMassRating); retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airDragArea, - DeclarationDataAdapter.GetDeclarationAirResistanceCurve( + DeclarationDataAdapter.GetDeclarationAirResistanceCurve( GetAirdragParameterSet(data.VehicleCategory, data.AxleConfiguration, data.Axles.Count), airDragArea, height), CrossWindCorrectionMode.DeclarationModeCorrection); - break; - default: - throw new ArgumentOutOfRangeException("CrosswindCorrection", airdragData.CrossWindCorrectionMode.ToString()); - } - return retVal; - } - - private string GetAirdragParameterSet(VehicleCategory vehicleCategory, AxleConfiguration axles, int numAxles) - { - switch (vehicleCategory) { - case VehicleCategory.RigidTruck: - return numAxles > axles.NumAxles() ? "RigidTrailer" : "RigidSolo"; - case VehicleCategory.Tractor: - return "TractorSemitrailer"; - case VehicleCategory.CityBus: - case VehicleCategory.InterurbanBus: - case VehicleCategory.Coach: - return "CoachBus"; - default: - throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null); - } - } - - private void WarnEngineeringMode(string msg) - { - Log.Error("{0} is in Declaration Mode but is used for Engineering Mode!", msg); - } - - internal CombustionEngineData CreateEngineData(IEngineEngineeringInputData engine, IGearboxEngineeringInputData gbx, - IEnumerable<ITorqueLimitInputData> torqueLimits) - { - if (engine.SavedInDeclarationMode) { - WarnEngineeringMode("EngineData"); - } - - var retVal = SetCommonCombustionEngineData(engine); - retVal.Inertia = engine.Inertia + - (gbx != null && gbx.Type.AutomaticTransmission() ? gbx.TorqueConverter.Inertia : 0.SI<KilogramSquareMeter>()); - var limits = torqueLimits.ToDictionary(e => e.Gear); - var numGears = gbx == null ? 0 : gbx.Gears.Count; - var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); - fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve); - fullLoadCurves[0].EngineData = retVal; - if (gbx != null) { - foreach (var gear in gbx.Gears) { - var maxTorque = VectoMath.Min(gear.MaxTorque, limits.ContainsKey(gear.Gear) ? limits[gear.Gear].MaxTorque : null); - fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque); - } - } - retVal.FullLoadCurves = fullLoadCurves; - retVal.FuelConsumptionCorrectionFactor = engine.WHTCEngineering; - return retVal; - } - - internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData, - double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback) - { - if (gearbox.SavedInDeclarationMode) { - WarnEngineeringMode("GearboxData"); - } - - var retVal = SetCommonGearboxData(gearbox); - - //var gears = gearbox.Gears; - if (gearbox.Gears.Count < 2) { - throw new VectoSimulationException("At least two Gear-Entries must be defined in Gearbox!"); - } - - SetEngineeringData(gearbox, retVal); - - var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2 - ? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio - : 1.0; - - var gears = new Dictionary<uint, GearData>(); - ShiftPolygon tcShiftPolygon = null; - if (gearbox.Type.AutomaticTransmission()) { - tcShiftPolygon = gearbox.TorqueConverter.ShiftPolygon != null - ? ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon) - : DeclarationData.TorqueConverter.ComputeShiftPolygon(engineData.FullLoadCurves[0]); - } - for (uint i = 0; i < gearbox.Gears.Count; i++) { - var gear = gearbox.Gears[(int)i]; - var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, false); - - var shiftPolygon = gear.ShiftPolygon != null && gear.ShiftPolygon.SourceType != DataSourceType.Missing - ? ShiftPolygonReader.Create(gear.ShiftPolygon) - : DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engineData.FullLoadCurves[i + 1], gearbox.Gears, - engineData, - axlegearRatio, dynamicTyreRadius); - var gearData = new GearData { - ShiftPolygon = shiftPolygon, - MaxSpeed = gear.MaxInputSpeed, - Ratio = gear.Ratio, - LossMap = lossMap, - }; - - if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) { - // powersplit transmission: torque converter already contains ratio and losses - CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon); - } - if (gearbox.Type == GearboxType.ATSerial) { - if (i == 0) { - // torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode - CreateTCFirstGearATSerial(gearData, tcShiftPolygon); - } - if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) { - // ratio between first and second gear is above threshold, torqueconverter is active in second gear as well - // -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear - CreateTCSecondGearATSerial(gearData, tcShiftPolygon); - // NOTE: the lower gear in 'gears' dictionary has index i !! - gears[i].Ratio = double.NaN; - gears[i].LossMap = null; - } - } - gears.Add(i + 1, gearData); - } - retVal.Gears = gears; - - if (retVal.Type.AutomaticTransmission()) { - var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio; - retVal.PowershiftShiftTime = gearbox.PowershiftShiftTime; - retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData, - gearbox.TorqueConverter.ReferenceRPM, gearbox.TorqueConverter.MaxInputSpeed, ExecutionMode.Engineering, ratio, - gearbox.TorqueConverter.CLUpshiftMinAcceleration, gearbox.TorqueConverter.CCUpshiftMinAcceleration); - } - - return retVal; - } - - private static void SetEngineeringData(IGearboxEngineeringInputData gearbox, GearboxData retVal) - { - retVal.Inertia = gearbox.Type.ManualTransmission() ? gearbox.Inertia : 0.SI<KilogramSquareMeter>(); - retVal.TractionInterruption = gearbox.TractionInterruption; - retVal.TorqueReserve = gearbox.TorqueReserve; - retVal.StartTorqueReserve = gearbox.StartTorqueReserve; - retVal.ShiftTime = gearbox.MinTimeBetweenGearshift; - retVal.StartSpeed = gearbox.StartSpeed; - retVal.StartAcceleration = gearbox.StartAcceleration; - retVal.DownshiftAfterUpshiftDelay = gearbox.DownshiftAfterUpshiftDelay; - retVal.UpshiftAfterDownshiftDelay = gearbox.UpshiftAfterDownshiftDelay; - retVal.UpshiftMinAcceleration = gearbox.UpshiftMinAcceleration; - } - - public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData) - { - var auxList = new List<VectoRunData.AuxData>(auxInputData.Auxiliaries.Count + 1) { - new VectoRunData.AuxData { ID = Constants.Auxiliaries.Cycle, DemandType = AuxiliaryDemandType.Direct } - }; - - foreach (var a in auxInputData.Auxiliaries) { - switch (a.AuxiliaryType) { - case AuxiliaryDemandType.Mapping: - auxList.Add(CreateMappingAuxiliary(a)); - break; - case AuxiliaryDemandType.Constant: - auxList.Add(CreateConstantAuxiliary(a)); - break; - default: - throw new VectoException("Auxiliary type {0} not supported!", a.AuxiliaryType); - } - } - return auxList; - } - - private static VectoRunData.AuxData CreateMappingAuxiliary(IAuxiliaryEngineeringInputData a) - { - if (a.DemandMap == null) { - throw new VectoSimulationException("Demand Map for auxiliary {0} required", a.ID); - } - if (a.DemandMap.Columns.Count != 3 || a.DemandMap.Rows.Count < 4) { - throw new VectoSimulationException( - "Demand Map for auxiliary {0} has to contain exactly 3 columns and at least 4 rows", a.ID); - } - return new VectoRunData.AuxData { - ID = a.ID, - DemandType = AuxiliaryDemandType.Mapping, - Data = AuxiliaryDataReader.Create(a) - }; - } - - private static VectoRunData.AuxData CreateConstantAuxiliary(IAuxiliaryEngineeringInputData a) - { - return new VectoRunData.AuxData { - ID = a.ID, - DemandType = AuxiliaryDemandType.Constant, - PowerDemand = a.ConstantPowerDemand - }; - } - - internal DriverData CreateDriverData(IDriverEngineeringInputData driver) - { - if (driver.SavedInDeclarationMode) { - WarnEngineeringMode("DriverData"); - } - - AccelerationCurveData accelerationData = null; - if (driver.AccelerationCurve != null) { - accelerationData = AccelerationCurveReader.Create(driver.AccelerationCurve); - } - - if (driver.Lookahead == null) { - throw new VectoSimulationException("Error: Lookahead Data is missing."); - } - var lookAheadData = new DriverData.LACData { - Enabled = driver.Lookahead.Enabled, - //Deceleration = driver.Lookahead.Deceleration, - MinSpeed = driver.Lookahead.MinSpeed, - LookAheadDecisionFactor = - new LACDecisionFactor(driver.Lookahead.CoastingDecisionFactorOffset, driver.Lookahead.CoastingDecisionFactorScaling, - driver.Lookahead.CoastingDecisionFactorTargetSpeedLookup, - driver.Lookahead.CoastingDecisionFactorVelocityDropLookup), - LookAheadDistanceFactor = driver.Lookahead.LookaheadDistanceFactor - }; - var overspeedData = new DriverData.OverSpeedEcoRollData { - Mode = driver.OverSpeedEcoRoll.Mode, - MinSpeed = driver.OverSpeedEcoRoll.MinSpeed, - OverSpeed = driver.OverSpeedEcoRoll.OverSpeed, - UnderSpeed = driver.OverSpeedEcoRoll.UnderSpeed, - }; - var retVal = new DriverData { - AccelerationCurve = accelerationData, - LookAheadCoasting = lookAheadData, - OverSpeedEcoRoll = overspeedData, - }; - return retVal; - } - - //================================= - public RetarderData CreateRetarderData(IRetarderInputData retarder) - { - return SetCommonRetarderData(retarder); - } - - public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto) - { - if (pto.PTOTransmissionType != "None") { - var ptoData = new PTOData { - TransmissionType = pto.PTOTransmissionType, - LossMap = PTOIdleLossMapReader.Create(pto.PTOLossMap), - }; - if (pto.PTOCycle != null) { - ptoData.PTOCycle = DrivingCycleDataReader.ReadFromDataTable(pto.PTOCycle, CycleType.PTO, "PTO", false); - } - return ptoData; - } - - return null; - } - - public AdvancedAuxData CreateAdvancedAuxData(IAuxiliariesEngineeringInputData auxInputData) - { - return new AdvancedAuxData() { - AdvancedAuxiliaryFilePath = auxInputData.AdvancedAuxiliaryFilePath, - AuxiliaryAssembly = auxInputData.AuxiliaryAssembly, - AuxiliaryVersion = auxInputData.AuxiliaryVersion - }; - } - } + break; + default: + throw new ArgumentOutOfRangeException("CrosswindCorrection", airdragData.CrossWindCorrectionMode.ToString()); + } + return retVal; + } + + private string GetAirdragParameterSet(VehicleCategory vehicleCategory, AxleConfiguration axles, int numAxles) + { + switch (vehicleCategory) { + case VehicleCategory.RigidTruck: + return numAxles > axles.NumAxles() ? "RigidTrailer" : "RigidSolo"; + case VehicleCategory.Tractor: + return "TractorSemitrailer"; + case VehicleCategory.CityBus: + case VehicleCategory.InterurbanBus: + case VehicleCategory.Coach: + return "CoachBus"; + default: + throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null); + } + } + + private void WarnEngineeringMode(string msg) + { + Log.Error("{0} is in Declaration Mode but is used for Engineering Mode!", msg); + } + + internal CombustionEngineData CreateEngineData(IEngineEngineeringInputData engine, IGearboxEngineeringInputData gbx, + IEnumerable<ITorqueLimitInputData> torqueLimits) + { + if (engine.SavedInDeclarationMode) { + WarnEngineeringMode("EngineData"); + } + + var retVal = SetCommonCombustionEngineData(engine); + retVal.Inertia = engine.Inertia + + (gbx != null && gbx.Type.AutomaticTransmission() ? gbx.TorqueConverter.Inertia : 0.SI<KilogramSquareMeter>()); + var limits = torqueLimits.ToDictionary(e => e.Gear); + var numGears = gbx == null ? 0 : gbx.Gears.Count; + var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); + fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve); + fullLoadCurves[0].EngineData = retVal; + if (gbx != null) { + foreach (var gear in gbx.Gears) { + var maxTorque = VectoMath.Min(gear.MaxTorque, limits.ContainsKey(gear.Gear) ? limits[gear.Gear].MaxTorque : null); + fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque); + } + } + retVal.FullLoadCurves = fullLoadCurves; + retVal.FuelConsumptionCorrectionFactor = engine.WHTCEngineering; + return retVal; + } + + internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData, + double axlegearRatio, Meter dynamicTyreRadius, VehicleCategory vehicleCategory, bool useEfficiencyFallback) + { + if (gearbox.SavedInDeclarationMode) { + WarnEngineeringMode("GearboxData"); + } + + var retVal = SetCommonGearboxData(gearbox); + + //var gears = gearbox.Gears; + if (gearbox.Gears.Count < 2) { + throw new VectoSimulationException("At least two Gear-Entries must be defined in Gearbox!"); + } + + SetEngineeringData(gearbox, retVal); + + var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2 + ? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio + : 1.0; + + var gears = new Dictionary<uint, GearData>(); + ShiftPolygon tcShiftPolygon = null; + if (gearbox.Type.AutomaticTransmission()) { + tcShiftPolygon = gearbox.TorqueConverter.ShiftPolygon != null + ? ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon) + : DeclarationData.TorqueConverter.ComputeShiftPolygon(engineData.FullLoadCurves[0]); + } + for (uint i = 0; i < gearbox.Gears.Count; i++) { + var gear = gearbox.Gears[(int)i]; + var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, false); + + var shiftPolygon = gear.ShiftPolygon != null && gear.ShiftPolygon.SourceType != DataSourceType.Missing + ? ShiftPolygonReader.Create(gear.ShiftPolygon) + : DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engineData.FullLoadCurves[i + 1], gearbox.Gears, + engineData, + axlegearRatio, dynamicTyreRadius); + var gearData = new GearData { + ShiftPolygon = shiftPolygon, + MaxSpeed = gear.MaxInputSpeed, + Ratio = gear.Ratio, + LossMap = lossMap, + }; + + CreateATGearData(gearbox, i, gearData, tcShiftPolygon, gearDifferenceRatio, gears, vehicleCategory); + gears.Add(i + 1, gearData); + } + retVal.Gears = gears; + + if (retVal.Type.AutomaticTransmission()) { + var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio; + retVal.PowershiftShiftTime = gearbox.PowershiftShiftTime; + retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData, + gearbox.TorqueConverter.ReferenceRPM, gearbox.TorqueConverter.MaxInputSpeed, ExecutionMode.Engineering, ratio, + gearbox.TorqueConverter.CLUpshiftMinAcceleration, gearbox.TorqueConverter.CCUpshiftMinAcceleration); + } + + + return retVal; + } + + private static void CreateATGearData(IGearboxEngineeringInputData gearbox, uint i, GearData gearData, + ShiftPolygon tcShiftPolygon, double gearDifferenceRatio, Dictionary<uint, GearData> gears, + VehicleCategory vehicleCategory) + { + if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) { + // powersplit transmission: torque converter already contains ratio and losses + CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon); + } + if (gearbox.Type == GearboxType.ATSerial) { + if (i == 0) { + // torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode + CreateTCFirstGearATSerial(gearData, tcShiftPolygon); + } + if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold(vehicleCategory)) { + // ratio between first and second gear is above threshold, torqueconverter is active in second gear as well + // -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear + CreateTCSecondGearATSerial(gearData, tcShiftPolygon); + // NOTE: the lower gear in 'gears' dictionary has index i !! + gears[i].Ratio = double.NaN; + gears[i].LossMap = null; + } + } + } + + private static void SetEngineeringData(IGearboxEngineeringInputData gearbox, GearboxData retVal) + { + retVal.Inertia = gearbox.Type.ManualTransmission() ? gearbox.Inertia : 0.SI<KilogramSquareMeter>(); + retVal.TractionInterruption = gearbox.TractionInterruption; + retVal.TorqueReserve = gearbox.TorqueReserve; + retVal.StartTorqueReserve = gearbox.StartTorqueReserve; + retVal.ShiftTime = gearbox.MinTimeBetweenGearshift; + retVal.StartSpeed = gearbox.StartSpeed; + retVal.StartAcceleration = gearbox.StartAcceleration; + retVal.DownshiftAfterUpshiftDelay = gearbox.DownshiftAfterUpshiftDelay; + retVal.UpshiftAfterDownshiftDelay = gearbox.UpshiftAfterDownshiftDelay; + retVal.UpshiftMinAcceleration = gearbox.UpshiftMinAcceleration; + } + + public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData) + { + var auxList = new List<VectoRunData.AuxData>(auxInputData.Auxiliaries.Count + 1) { + new VectoRunData.AuxData { ID = Constants.Auxiliaries.Cycle, DemandType = AuxiliaryDemandType.Direct } + }; + + foreach (var a in auxInputData.Auxiliaries) { + switch (a.AuxiliaryType) { + case AuxiliaryDemandType.Mapping: + auxList.Add(CreateMappingAuxiliary(a)); + break; + case AuxiliaryDemandType.Constant: + auxList.Add(CreateConstantAuxiliary(a)); + break; + default: + throw new VectoException("Auxiliary type {0} not supported!", a.AuxiliaryType); + } + } + return auxList; + } + + private static VectoRunData.AuxData CreateMappingAuxiliary(IAuxiliaryEngineeringInputData a) + { + if (a.DemandMap == null) { + throw new VectoSimulationException("Demand Map for auxiliary {0} required", a.ID); + } + if (a.DemandMap.Columns.Count != 3 || a.DemandMap.Rows.Count < 4) { + throw new VectoSimulationException( + "Demand Map for auxiliary {0} has to contain exactly 3 columns and at least 4 rows", a.ID); + } + return new VectoRunData.AuxData { + ID = a.ID, + DemandType = AuxiliaryDemandType.Mapping, + Data = AuxiliaryDataReader.Create(a) + }; + } + + private static VectoRunData.AuxData CreateConstantAuxiliary(IAuxiliaryEngineeringInputData a) + { + return new VectoRunData.AuxData { + ID = a.ID, + DemandType = AuxiliaryDemandType.Constant, + PowerDemand = a.ConstantPowerDemand + }; + } + + internal DriverData CreateDriverData(IDriverEngineeringInputData driver) + { + if (driver.SavedInDeclarationMode) { + WarnEngineeringMode("DriverData"); + } + + AccelerationCurveData accelerationData = null; + if (driver.AccelerationCurve != null) { + accelerationData = AccelerationCurveReader.Create(driver.AccelerationCurve); + } + + if (driver.Lookahead == null) { + throw new VectoSimulationException("Error: Lookahead Data is missing."); + } + var lookAheadData = new DriverData.LACData { + Enabled = driver.Lookahead.Enabled, + //Deceleration = driver.Lookahead.Deceleration, + MinSpeed = driver.Lookahead.MinSpeed, + LookAheadDecisionFactor = + new LACDecisionFactor(driver.Lookahead.CoastingDecisionFactorOffset, driver.Lookahead.CoastingDecisionFactorScaling, + driver.Lookahead.CoastingDecisionFactorTargetSpeedLookup, + driver.Lookahead.CoastingDecisionFactorVelocityDropLookup), + LookAheadDistanceFactor = driver.Lookahead.LookaheadDistanceFactor + }; + var overspeedData = new DriverData.OverSpeedEcoRollData { + Mode = driver.OverSpeedEcoRoll.Mode, + MinSpeed = driver.OverSpeedEcoRoll.MinSpeed, + OverSpeed = driver.OverSpeedEcoRoll.OverSpeed, + UnderSpeed = driver.OverSpeedEcoRoll.UnderSpeed, + }; + var retVal = new DriverData { + AccelerationCurve = accelerationData, + LookAheadCoasting = lookAheadData, + OverSpeedEcoRoll = overspeedData, + }; + return retVal; + } + + //================================= + public RetarderData CreateRetarderData(IRetarderInputData retarder) + { + return SetCommonRetarderData(retarder); + } + + public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto) + { + if (pto.PTOTransmissionType != "None") { + var ptoData = new PTOData { + TransmissionType = pto.PTOTransmissionType, + LossMap = PTOIdleLossMapReader.Create(pto.PTOLossMap), + }; + if (pto.PTOCycle != null) { + ptoData.PTOCycle = DrivingCycleDataReader.ReadFromDataTable(pto.PTOCycle, CycleType.PTO, "PTO", false); + } + return ptoData; + } + + return null; + } + + public AdvancedAuxData CreateAdvancedAuxData(IAuxiliariesEngineeringInputData auxInputData) + { + return new AdvancedAuxData() { + AdvancedAuxiliaryFilePath = auxInputData.AdvancedAuxiliaryFilePath, + AuxiliaryAssembly = auxInputData.AuxiliaryAssembly, + AuxiliaryVersion = auxInputData.AuxiliaryVersion + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/FullLoadCurveReader.cs b/VectoCore/VectoCore/InputData/Reader/FullLoadCurveReader.cs index c8eb1db895ba4625d37aecdc695a38ebbcfa893e..7bb94ac86bac9d1a156f2f43c2f26ab10462e4c7 100644 --- a/VectoCore/VectoCore/InputData/Reader/FullLoadCurveReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/FullLoadCurveReader.cs @@ -29,107 +29,107 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.InputData.Reader -{ - public static class FullLoadCurveReader - { - public static EngineFullLoadCurve ReadFromFile(string fileName, bool declarationMode = false) - { - try { - var data = VectoCSVFile.Read(fileName); - return Create(data, declarationMode); - } catch (Exception ex) { - throw new VectoException("ERROR while reading FullLoadCurve File: " + ex.Message, ex); - } - } - - public static EngineFullLoadCurve Create(DataTable data, bool declarationMode = false) - { - if (data.Columns.Count < 3) { - throw new VectoException("Engine FullLoadCurve Data File must consist of at least 3 columns."); - } - - if (data.Rows.Count < 2) { - throw new VectoException( - "FullLoadCurve must consist of at least two lines with numeric values (below file header)"); - } - - List<EngineFullLoadCurve.FullLoadCurveEntry> entriesFld; - if (HeaderIsValid(data.Columns)) { - entriesFld = CreateFromColumnNames(data); - } else { - LoggingObject.Logger<EngineFullLoadCurve>().Warn( - "FullLoadCurve: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: '{3}'. Falling back to column index.", - Fields.EngineSpeed, Fields.TorqueFullLoad, - Fields.TorqueDrag, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName))); - - entriesFld = CreateFromColumnIndizes(data); - } - - LookupData<PerSecond, PT1.PT1Result> tmp; - if (declarationMode) { - tmp = new PT1(); - } else { - tmp = data.Columns.Count > 3 ? new PT1(data) : new PT1(); - } - entriesFld.Sort((entry1, entry2) => entry1.EngineSpeed.Value().CompareTo(entry2.EngineSpeed.Value())); - return new EngineFullLoadCurve(entriesFld, tmp); - } - - private static bool HeaderIsValid(DataColumnCollection columns) - { - return columns.Contains(Fields.EngineSpeed) - && columns.Contains(Fields.TorqueFullLoad) - && columns.Contains(Fields.TorqueDrag); - } - - private static List<EngineFullLoadCurve.FullLoadCurveEntry> CreateFromColumnNames(DataTable data) - { - return (from DataRow row in data.Rows - select new EngineFullLoadCurve.FullLoadCurveEntry { - EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(), - TorqueFullLoad = row.ParseDouble(Fields.TorqueFullLoad).SI<NewtonMeter>(), - TorqueDrag = row.ParseDouble(Fields.TorqueDrag).SI<NewtonMeter>() - }).ToList(); - } - - private static List<EngineFullLoadCurve.FullLoadCurveEntry> CreateFromColumnIndizes(DataTable data) - { - return (from DataRow row in data.Rows - select new EngineFullLoadCurve.FullLoadCurveEntry { - EngineSpeed = row.ParseDouble(0).RPMtoRad(), - TorqueFullLoad = row.ParseDouble(1).SI<NewtonMeter>(), - TorqueDrag = row.ParseDouble(2).SI<NewtonMeter>() - }).ToList(); - } - - public static class Fields - { - /// <summary> - /// [rpm] engine speed - /// </summary> - public const string EngineSpeed = "engine speed"; - - /// <summary> - /// [Nm] full load torque - /// </summary> - public const string TorqueFullLoad = "full load torque"; - - /// <summary> - /// [Nm] motoring torque - /// </summary> - public const string TorqueDrag = "motoring torque"; - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.InputData.Reader +{ + public static class FullLoadCurveReader + { + public static EngineFullLoadCurve ReadFromFile(string fileName, bool declarationMode = false) + { + try { + var data = VectoCSVFile.Read(fileName); + return Create(data, declarationMode); + } catch (Exception ex) { + throw new VectoException("ERROR while reading FullLoadCurve File: " + ex.Message, ex); + } + } + + public static EngineFullLoadCurve Create(DataTable data, bool declarationMode = false) + { + if (data.Columns.Count < 3) { + throw new VectoException("Engine FullLoadCurve Data File must consist of at least 3 columns."); + } + + if (data.Rows.Count < 2) { + throw new VectoException( + "FullLoadCurve must consist of at least two lines with numeric values (below file header)"); + } + + List<EngineFullLoadCurve.FullLoadCurveEntry> entriesFld; + if (HeaderIsValid(data.Columns)) { + entriesFld = CreateFromColumnNames(data); + } else { + LoggingObject.Logger<EngineFullLoadCurve>().Warn( + "FullLoadCurve: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: '{3}'. Falling back to column index.", + Fields.EngineSpeed, Fields.TorqueFullLoad, + Fields.TorqueDrag, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName))); + + entriesFld = CreateFromColumnIndizes(data); + } + + LookupData<PerSecond, PT1.PT1Result> tmp; + if (declarationMode) { + tmp = new PT1(); + } else { + tmp = data.Columns.Count > 3 ? new PT1(data) : new PT1(); + } + entriesFld.Sort((entry1, entry2) => entry1.EngineSpeed.Value().CompareTo(entry2.EngineSpeed.Value())); + return new EngineFullLoadCurve(entriesFld, tmp); + } + + private static bool HeaderIsValid(DataColumnCollection columns) + { + return columns.Contains(Fields.EngineSpeed) + && columns.Contains(Fields.TorqueFullLoad) + && columns.Contains(Fields.TorqueDrag); + } + + private static List<EngineFullLoadCurve.FullLoadCurveEntry> CreateFromColumnNames(DataTable data) + { + return (from DataRow row in data.Rows + select new EngineFullLoadCurve.FullLoadCurveEntry { + EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(), + TorqueFullLoad = row.ParseDouble(Fields.TorqueFullLoad).SI<NewtonMeter>(), + TorqueDrag = row.ParseDouble(Fields.TorqueDrag).SI<NewtonMeter>() + }).ToList(); + } + + private static List<EngineFullLoadCurve.FullLoadCurveEntry> CreateFromColumnIndizes(DataTable data) + { + return (from DataRow row in data.Rows + select new EngineFullLoadCurve.FullLoadCurveEntry { + EngineSpeed = row.ParseDouble(0).RPMtoRad(), + TorqueFullLoad = row.ParseDouble(1).SI<NewtonMeter>(), + TorqueDrag = row.ParseDouble(2).SI<NewtonMeter>() + }).ToList(); + } + + public static class Fields + { + /// <summary> + /// [rpm] engine speed + /// </summary> + public const string EngineSpeed = "engine speed"; + + /// <summary> + /// [Nm] full load torque + /// </summary> + public const string TorqueFullLoad = "full load torque"; + + /// <summary> + /// [Nm] motoring torque + /// </summary> + public const string TorqueDrag = "motoring torque"; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index 99b9a05a567f7fdae998099264f16f84e5a7ae94..201451de671cc15783395728810412506986e909 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -29,174 +29,180 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - - -namespace TUGraz.VectoCore.InputData.Reader.Impl -{ - public class DeclarationModeVectoRunDataFactory : LoggingObject, IVectoRunDataFactory - { - private static readonly object CyclesCacheLock = new object(); - - private static readonly Dictionary<MissionType, DrivingCycleData> CyclesCache = - new Dictionary<MissionType, DrivingCycleData>(); - - protected readonly IDeclarationInputDataProvider InputDataProvider; - - protected IDeclarationReport Report; - private DeclarationDataAdapter _dao; - private Segment _segment; - private DriverData _driverdata; - private AirdragData _airdragData; - private CombustionEngineData _engineData; - private AxleGearData _axlegearData; - private AngledriveData _angledriveData; - private GearboxData _gearboxData; - private RetarderData _retarderData; - private PTOData _ptoTransmissionData; - private PTOData _municipalPtoTransmissionData; - private Exception InitException; - - internal DeclarationModeVectoRunDataFactory(IDeclarationInputDataProvider dataProvider, IDeclarationReport report) - { - InputDataProvider = dataProvider; - Report = report; - - try { - Initialize(); - if (Report != null) { - InitializeReport(); - } - } catch (Exception e) { - InitException = e; - } - } - - private void Initialize() - { - _dao = new DeclarationDataAdapter(); - _segment = GetVehicleClassification(InputDataProvider.VehicleInputData.VehicleCategory, - InputDataProvider.VehicleInputData.AxleConfiguration, - InputDataProvider.VehicleInputData.GrossVehicleMassRating, InputDataProvider.VehicleInputData.CurbMassChassis); - _driverdata = _dao.CreateDriverData(InputDataProvider.DriverInputData); - _driverdata.AccelerationCurve = AccelerationCurveReader.ReadFromStream(_segment.AccelerationFile); - - var tempVehicle = _dao.CreateVehicleData(InputDataProvider.VehicleInputData, _segment.Missions.First(), - _segment.Missions.First().Loadings.First().Value, _segment.MunicipalBodyWeight); - _airdragData = _dao.CreateAirdragData(InputDataProvider.AirdragInputData, _segment.Missions.First(), _segment); - _engineData = _dao.CreateEngineData(InputDataProvider.EngineInputData, - InputDataProvider.VehicleInputData.EngineIdleSpeed, - InputDataProvider.GearboxInputData, InputDataProvider.VehicleInputData.TorqueLimits); - _axlegearData = _dao.CreateAxleGearData(InputDataProvider.AxleGearInputData, false); - _angledriveData = _dao.CreateAngledriveData(InputDataProvider.AngledriveInputData, false); - _gearboxData = _dao.CreateGearboxData(InputDataProvider.GearboxInputData, _engineData, _axlegearData.AxleGear.Ratio, - tempVehicle.DynamicTyreRadius, false); - _retarderData = _dao.CreateRetarderData(InputDataProvider.RetarderInputData); - - _ptoTransmissionData = _dao.CreatePTOTransmissionData(InputDataProvider.PTOTransmissionInputData); - - _municipalPtoTransmissionData = CreateDefaultPTOData(); - } - - private void InitializeReport() - { - var powertrainConfig = new VectoRunData() { - VehicleData = - _dao.CreateVehicleData(InputDataProvider.VehicleInputData, _segment.Missions.First(), - _segment.Missions.First().Loadings.First().Value, _segment.MunicipalBodyWeight), - AirdragData = _airdragData, - EngineData = _engineData, - GearboxData = _gearboxData, - AxleGearData = _axlegearData, - Retarder = _retarderData, - Aux = _dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData(), _segment.Missions.First().MissionType, - _segment.VehicleClass), - InputDataHash = InputDataProvider.XMLHash - }; - Report.InitializeReport(powertrainConfig, _segment); - } - - public IEnumerable<VectoRunData> NextRun() - { - if (InitException != null) { - throw InitException; - } - - foreach (var mission in _segment.Missions) { - if (mission.MissionType.IsEMS() && - _engineData.RatedPowerDeclared.IsSmaller(DeclarationData.MinEnginePowerForEMS)) { - continue; - } - DrivingCycleData cycle; - lock (CyclesCacheLock) { - if (CyclesCache.ContainsKey(mission.MissionType)) { - cycle = CyclesCache[mission.MissionType]; - } else { - cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false); - CyclesCache.Add(mission.MissionType, cycle); - } - } - foreach (var loading in mission.Loadings) { - var simulationRunData = new VectoRunData { - Loading = loading.Key, - VehicleData = - _dao.CreateVehicleData(InputDataProvider.VehicleInputData, mission, loading.Value, _segment.MunicipalBodyWeight), - AirdragData = _dao.CreateAirdragData(InputDataProvider.AirdragInputData, mission, _segment), - EngineData = _engineData.Copy(), - GearboxData = _gearboxData, - AxleGearData = _axlegearData, - AngledriveData = _angledriveData, - Aux = _dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData(), mission.MissionType, - _segment.VehicleClass), - Cycle = new DrivingCycleProxy(cycle, mission.MissionType.ToString()), - Retarder = _retarderData, - DriverData = _driverdata, - ExecutionMode = ExecutionMode.Declaration, - JobName = InputDataProvider.JobInputData().JobName, - ModFileSuffix = loading.Key.ToString(), - Report = Report, - Mission = mission, - PTO = mission.MissionType == MissionType.MunicipalUtility - ? _municipalPtoTransmissionData - : _ptoTransmissionData, - InputDataHash = InputDataProvider.XMLHash - }; - simulationRunData.EngineData.FuelConsumptionCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( - mission.MissionType.GetNonEMSMissionType(), _engineData.WHTCRural, _engineData.WHTCUrban, _engineData.WHTCMotorway) * - _engineData.ColdHotCorrectionFactor; - simulationRunData.VehicleData.VehicleClass = _segment.VehicleClass; - yield return simulationRunData; - } - } - } - - private PTOData CreateDefaultPTOData() - { - return new PTOData() { - TransmissionType = DeclarationData.PTO.DefaultPTOTechnology, - LossMap = PTOIdleLossMapReader.ReadFromStream(RessourceHelper.ReadStream(DeclarationData.PTO.DefaultPTOIdleLosses)), - PTOCycle = - DrivingCycleDataReader.ReadFromStream(RessourceHelper.ReadStream(DeclarationData.PTO.DefaultPTOActivationCycle), - CycleType.PTO, "PTO", false) - }; - } - - internal Segment GetVehicleClassification(VehicleCategory category, AxleConfiguration axles, Kilogram grossMassRating, - Kilogram curbWeight) - { - return DeclarationData.Segments.Lookup(category, axles, grossMassRating, curbWeight); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + + +namespace TUGraz.VectoCore.InputData.Reader.Impl +{ + public class DeclarationModeVectoRunDataFactory : LoggingObject, IVectoRunDataFactory + { + private static readonly object CyclesCacheLock = new object(); + + private static readonly Dictionary<MissionType, DrivingCycleData> CyclesCache = + new Dictionary<MissionType, DrivingCycleData>(); + + protected readonly IDeclarationInputDataProvider InputDataProvider; + + protected IDeclarationReport Report; + private DeclarationDataAdapter _dao; + private Segment _segment; + private DriverData _driverdata; + private AirdragData _airdragData; + private CombustionEngineData _engineData; + private AxleGearData _axlegearData; + private AngledriveData _angledriveData; + private GearboxData _gearboxData; + private RetarderData _retarderData; + private PTOData _ptoTransmissionData; + private PTOData _municipalPtoTransmissionData; + private Exception InitException; + + internal DeclarationModeVectoRunDataFactory(IDeclarationInputDataProvider dataProvider, IDeclarationReport report) + { + InputDataProvider = dataProvider; + Report = report; + + try { + Initialize(); + if (Report != null) { + InitializeReport(); + } + } catch (Exception e) { + InitException = e; + } + } + + private void Initialize() + { + _dao = new DeclarationDataAdapter(); + _segment = GetVehicleClassification(InputDataProvider.VehicleInputData.VehicleCategory, + InputDataProvider.VehicleInputData.AxleConfiguration, + InputDataProvider.VehicleInputData.GrossVehicleMassRating, InputDataProvider.VehicleInputData.CurbMassChassis); + if (!_segment.Found) { + throw new VectoException( + "no segment found for vehicle configruation: vehicle category: {0}, axle configuration: {1}, GVMR: {2}", + InputDataProvider.VehicleInputData.VehicleCategory, InputDataProvider.VehicleInputData.AxleConfiguration, + InputDataProvider.VehicleInputData.GrossVehicleMassRating); + } + _driverdata = _dao.CreateDriverData(InputDataProvider.DriverInputData); + _driverdata.AccelerationCurve = AccelerationCurveReader.ReadFromStream(_segment.AccelerationFile); + var tempVehicle = _dao.CreateVehicleData(InputDataProvider.VehicleInputData, _segment.Missions.First(), + _segment.Missions.First().Loadings.First().Value, _segment.MunicipalBodyWeight); + _airdragData = _dao.CreateAirdragData(InputDataProvider.AirdragInputData, _segment.Missions.First(), _segment); + _engineData = _dao.CreateEngineData(InputDataProvider.EngineInputData, + InputDataProvider.VehicleInputData.EngineIdleSpeed, + InputDataProvider.GearboxInputData, InputDataProvider.VehicleInputData.TorqueLimits); + _axlegearData = _dao.CreateAxleGearData(InputDataProvider.AxleGearInputData, false); + _angledriveData = _dao.CreateAngledriveData(InputDataProvider.AngledriveInputData, false); + _gearboxData = _dao.CreateGearboxData(InputDataProvider.GearboxInputData, _engineData, _axlegearData.AxleGear.Ratio, + tempVehicle.DynamicTyreRadius, tempVehicle.VehicleCategory, false); + _retarderData = _dao.CreateRetarderData(InputDataProvider.RetarderInputData); + + _ptoTransmissionData = _dao.CreatePTOTransmissionData(InputDataProvider.PTOTransmissionInputData); + + _municipalPtoTransmissionData = CreateDefaultPTOData(); + } + + private void InitializeReport() + { + var powertrainConfig = new VectoRunData() { + VehicleData = + _dao.CreateVehicleData(InputDataProvider.VehicleInputData, _segment.Missions.First(), + _segment.Missions.First().Loadings.First().Value, _segment.MunicipalBodyWeight), + AirdragData = _airdragData, + EngineData = _engineData, + GearboxData = _gearboxData, + AxleGearData = _axlegearData, + Retarder = _retarderData, + Aux = _dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData(), _segment.Missions.First().MissionType, + _segment.VehicleClass), + InputDataHash = InputDataProvider.XMLHash + }; + Report.InitializeReport(powertrainConfig, _segment); + } + + public IEnumerable<VectoRunData> NextRun() + { + if (InitException != null) { + throw InitException; + } + + foreach (var mission in _segment.Missions) { + if (mission.MissionType.IsEMS() && + _engineData.RatedPowerDeclared.IsSmaller(DeclarationData.MinEnginePowerForEMS)) { + continue; + } + DrivingCycleData cycle; + lock (CyclesCacheLock) { + if (CyclesCache.ContainsKey(mission.MissionType)) { + cycle = CyclesCache[mission.MissionType]; + } else { + cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false); + CyclesCache.Add(mission.MissionType, cycle); + } + } + foreach (var loading in mission.Loadings) { + var simulationRunData = new VectoRunData { + Loading = loading.Key, + VehicleData = + _dao.CreateVehicleData(InputDataProvider.VehicleInputData, mission, loading.Value, _segment.MunicipalBodyWeight), + AirdragData = _dao.CreateAirdragData(InputDataProvider.AirdragInputData, mission, _segment), + EngineData = _engineData.Copy(), + GearboxData = _gearboxData, + AxleGearData = _axlegearData, + AngledriveData = _angledriveData, + Aux = _dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData(), mission.MissionType, + _segment.VehicleClass), + Cycle = new DrivingCycleProxy(cycle, mission.MissionType.ToString()), + Retarder = _retarderData, + DriverData = _driverdata, + ExecutionMode = ExecutionMode.Declaration, + JobName = InputDataProvider.JobInputData().JobName, + ModFileSuffix = loading.Key.ToString(), + Report = Report, + Mission = mission, + PTO = mission.MissionType == MissionType.MunicipalUtility + ? _municipalPtoTransmissionData + : _ptoTransmissionData, + InputDataHash = InputDataProvider.XMLHash + }; + simulationRunData.EngineData.FuelConsumptionCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( + mission.MissionType.GetNonEMSMissionType(), _engineData.WHTCRural, _engineData.WHTCUrban, _engineData.WHTCMotorway) * + _engineData.ColdHotCorrectionFactor; + simulationRunData.VehicleData.VehicleClass = _segment.VehicleClass; + yield return simulationRunData; + } + } + } + + private PTOData CreateDefaultPTOData() + { + return new PTOData() { + TransmissionType = DeclarationData.PTO.DefaultPTOTechnology, + LossMap = PTOIdleLossMapReader.ReadFromStream(RessourceHelper.ReadStream(DeclarationData.PTO.DefaultPTOIdleLosses)), + PTOCycle = + DrivingCycleDataReader.ReadFromStream(RessourceHelper.ReadStream(DeclarationData.PTO.DefaultPTOActivationCycle), + CycleType.PTO, "PTO", false) + }; + } + + internal Segment GetVehicleClassification(VehicleCategory category, AxleConfiguration axles, Kilogram grossMassRating, + Kilogram curbWeight) + { + return DeclarationData.Segments.Lookup(category, axles, grossMassRating, curbWeight); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs index 9a1a7935dbb04f8c4b24252b2334b0d3601559bb..dfcd0c3c747e29c04e293b8c6fff25400f979587 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs @@ -29,72 +29,72 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; - -[assembly: InternalsVisibleTo("VectoCoreTest")] - -namespace TUGraz.VectoCore.InputData.Reader.Impl -{ - public class EngineeringModeVectoRunDataFactory : LoggingObject, IVectoRunDataFactory - { - private static readonly Dictionary<string, DrivingCycleData> CyclesCache = new Dictionary<string, DrivingCycleData>(); - - protected readonly IEngineeringInputDataProvider InputDataProvider; - - internal EngineeringModeVectoRunDataFactory(IEngineeringInputDataProvider dataProvider) - { - InputDataProvider = dataProvider; - } - - /// <summary> - /// Iterate over all cycles defined in the JobFile and create a container with all data required for creating a simulation run - /// </summary> - /// <returns>VectoRunData instance for initializing the powertrain.</returns> - public virtual IEnumerable<VectoRunData> NextRun() - { - var dao = new EngineeringDataAdapter(); - var driver = dao.CreateDriverData(InputDataProvider.DriverInputData); - var engineData = dao.CreateEngineData(InputDataProvider.EngineInputData, InputDataProvider.GearboxInputData, - InputDataProvider.VehicleInputData.TorqueLimits); - - var tempVehicle = dao.CreateVehicleData(InputDataProvider.VehicleInputData); - - var axlegearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData, useEfficiencyFallback: true); - var gearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData, axlegearData.AxleGear.Ratio, - tempVehicle.DynamicTyreRadius, useEfficiencyFallback: true); - var crossWindRequired = InputDataProvider.AirdragInputData.CrossWindCorrectionMode == - CrossWindCorrectionMode.VAirBetaLookupTable; - var angledriveData = dao.CreateAngledriveData(InputDataProvider.AngledriveInputData, useEfficiencyFallback: true); - var ptoTransmissionData = dao.CreatePTOTransmissionData(InputDataProvider.PTOTransmissionInputData); - - return InputDataProvider.JobInputData().Cycles.Select(cycle => { - var drivingCycle = CyclesCache.ContainsKey(cycle.CycleData.Source) - ? CyclesCache[cycle.CycleData.Source] - : DrivingCycleDataReader.ReadFromDataTable(cycle.CycleData, cycle.Name, crossWindRequired); - return new VectoRunData { - JobName = InputDataProvider.JobInputData().JobName, - EngineData = engineData, - GearboxData = gearboxData, - AxleGearData = axlegearData, - AngledriveData = angledriveData, - VehicleData = dao.CreateVehicleData(InputDataProvider.VehicleInputData), - AirdragData = dao.CreateAirdragData(InputDataProvider.AirdragInputData, InputDataProvider.VehicleInputData), - DriverData = driver, - Aux = dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData()), - AdvancedAux = dao.CreateAdvancedAuxData(InputDataProvider.AuxiliaryInputData()), - Retarder = dao.CreateRetarderData(InputDataProvider.RetarderInputData), - PTO = ptoTransmissionData, - Cycle = new DrivingCycleProxy(drivingCycle, cycle.Name), - ExecutionMode = ExecutionMode.Engineering - }; - }); - } - } +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; + +[assembly: InternalsVisibleTo("VectoCoreTest")] + +namespace TUGraz.VectoCore.InputData.Reader.Impl +{ + public class EngineeringModeVectoRunDataFactory : LoggingObject, IVectoRunDataFactory + { + private static readonly Dictionary<string, DrivingCycleData> CyclesCache = new Dictionary<string, DrivingCycleData>(); + + protected readonly IEngineeringInputDataProvider InputDataProvider; + + internal EngineeringModeVectoRunDataFactory(IEngineeringInputDataProvider dataProvider) + { + InputDataProvider = dataProvider; + } + + /// <summary> + /// Iterate over all cycles defined in the JobFile and create a container with all data required for creating a simulation run + /// </summary> + /// <returns>VectoRunData instance for initializing the powertrain.</returns> + public virtual IEnumerable<VectoRunData> NextRun() + { + var dao = new EngineeringDataAdapter(); + var driver = dao.CreateDriverData(InputDataProvider.DriverInputData); + var engineData = dao.CreateEngineData(InputDataProvider.EngineInputData, InputDataProvider.GearboxInputData, + InputDataProvider.VehicleInputData.TorqueLimits); + + var tempVehicle = dao.CreateVehicleData(InputDataProvider.VehicleInputData); + + var axlegearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData, useEfficiencyFallback: true); + var gearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData, axlegearData.AxleGear.Ratio, + tempVehicle.DynamicTyreRadius,tempVehicle.VehicleCategory, useEfficiencyFallback: true); + var crossWindRequired = InputDataProvider.AirdragInputData.CrossWindCorrectionMode == + CrossWindCorrectionMode.VAirBetaLookupTable; + var angledriveData = dao.CreateAngledriveData(InputDataProvider.AngledriveInputData, useEfficiencyFallback: true); + var ptoTransmissionData = dao.CreatePTOTransmissionData(InputDataProvider.PTOTransmissionInputData); + + return InputDataProvider.JobInputData().Cycles.Select(cycle => { + var drivingCycle = CyclesCache.ContainsKey(cycle.CycleData.Source) + ? CyclesCache[cycle.CycleData.Source] + : DrivingCycleDataReader.ReadFromDataTable(cycle.CycleData, cycle.Name, crossWindRequired); + return new VectoRunData { + JobName = InputDataProvider.JobInputData().JobName, + EngineData = engineData, + GearboxData = gearboxData, + AxleGearData = axlegearData, + AngledriveData = angledriveData, + VehicleData = dao.CreateVehicleData(InputDataProvider.VehicleInputData), + AirdragData = dao.CreateAirdragData(InputDataProvider.AirdragInputData, InputDataProvider.VehicleInputData), + DriverData = driver, + Aux = dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData()), + AdvancedAux = dao.CreateAdvancedAuxData(InputDataProvider.AuxiliaryInputData()), + Retarder = dao.CreateRetarderData(InputDataProvider.RetarderInputData), + PTO = ptoTransmissionData, + Cycle = new DrivingCycleProxy(drivingCycle, cycle.Name), + ExecutionMode = ExecutionMode.Engineering + }; + }); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/AuxDemandEntry.cs b/VectoCore/VectoCore/Models/Declaration/AuxDemandEntry.cs new file mode 100644 index 0000000000000000000000000000000000000000..a04ddfb72d6a5c7079b1e5fb4e90dbd5aa3d44d7 --- /dev/null +++ b/VectoCore/VectoCore/Models/Declaration/AuxDemandEntry.cs @@ -0,0 +1,9 @@ +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public struct AuxDemandEntry + { + public Watt PowerDemand; + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 25b74b9bef713ecce1e6622284c721da5e8a4819..98bfc64763ee494c8ee68aaaaf03348216655628 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -88,7 +88,8 @@ namespace TUGraz.VectoCore.Models.Declaration /// </summary> public static Kilogram GetPayloadForTrailerWeight(Kilogram grossVehicleWeight, Kilogram curbWeight, bool lowLoading) { - return Payloads.LookupTrailer(grossVehicleWeight, curbWeight) / (lowLoading ? 7.5 : 1); + return (Payloads.LookupTrailer(grossVehicleWeight, curbWeight) / (lowLoading ? 7.5 : 1)).LimitTo(0.SI<Kilogram>(), + grossVehicleWeight - curbWeight); } public static int PoweredAxle() @@ -175,7 +176,10 @@ namespace TUGraz.VectoCore.Models.Declaration public static readonly MeterPerSquareSecond UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>(); //public static readonly PerSecond TorqueConverterSpeedLimit = 1600.RPMtoRad(); - public static readonly double TorqueConverterSecondGearThreshold = 1.8; + public static double TorqueConverterSecondGearThreshold(VehicleCategory category) + { + return category.IsTruck() ? 1.8 : 1.85; + } public static readonly Second PowershiftShiftTime = 0.8.SI<Second>(); diff --git a/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs b/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs index 4c9d90ef465111e095004010cc87e8e066806260..8bddb989396845919e56d3bc5c45633ab6fd3205 100644 --- a/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs +++ b/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs @@ -37,7 +37,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class ElectricSystem : LookupData<MissionType, string, Watt>, IDeclarationAuxiliaryTable + public sealed class ElectricSystem : LookupData<MissionType, string, AuxDemandEntry>, IDeclarationAuxiliaryTable { private readonly Alternator _alternator = new Alternator(); @@ -58,19 +58,19 @@ namespace TUGraz.VectoCore.Models.Declaration foreach (DataColumn col in table.Columns) { if (col.Caption != "technology") { Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), name)] = - row.ParseDouble(col).SI<Watt>(); + new AuxDemandEntry() { PowerDemand = row.ParseDouble(col).SI<Watt>() }; } } } } - public override Watt Lookup(MissionType missionType, string technology = null) + public override AuxDemandEntry Lookup(MissionType missionType, string technology = null) { if (string.IsNullOrWhiteSpace(technology)) { technology = "Standard technology"; } var value = base.Lookup(missionType, technology); - return value / _alternator.Lookup(missionType); + return new AuxDemandEntry() { PowerDemand = value.PowerDemand / _alternator.Lookup(missionType) }; } internal sealed class Alternator : LookupData<MissionType, string, double> diff --git a/VectoCore/VectoCore/Models/Declaration/Fan.cs b/VectoCore/VectoCore/Models/Declaration/Fan.cs index 6a35c66ede7c0641af79320544ca830db54a029a..3a576c5d04d0a6b6bda5543afe71755c7627e00c 100644 --- a/VectoCore/VectoCore/Models/Declaration/Fan.cs +++ b/VectoCore/VectoCore/Models/Declaration/Fan.cs @@ -37,7 +37,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class Fan : LookupData<MissionType, string, Watt>, IDeclarationAuxiliaryTable + public sealed class Fan : LookupData<MissionType, string, AuxDemandEntry>, IDeclarationAuxiliaryTable { protected override string ResourceId { @@ -56,13 +56,13 @@ namespace TUGraz.VectoCore.Models.Declaration foreach (DataColumn col in table.Columns) { if (col.Caption != "technology") { - Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), name)] = row.ParseDouble(col).SI<Watt>(); + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), name)] = new AuxDemandEntry(){PowerDemand = row.ParseDouble(col).SI<Watt>()}; } } } } - public override Watt Lookup(MissionType mission, string technology = null) + public override AuxDemandEntry Lookup(MissionType mission, string technology = null) { if (string.IsNullOrWhiteSpace(technology)) { technology = "Crankshaft mounted - Electronically controlled visco clutch"; diff --git a/VectoCore/VectoCore/Models/Declaration/FuelData.cs b/VectoCore/VectoCore/Models/Declaration/FuelData.cs index e925bfcd173d38f5229d5d487dcd52f83e5e24c7..6f176a7b0d70c1c976fa78f5ac36a34bb557eef8 100644 --- a/VectoCore/VectoCore/Models/Declaration/FuelData.cs +++ b/VectoCore/VectoCore/Models/Declaration/FuelData.cs @@ -29,73 +29,73 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class FuelData : LookupData<FuelType, FuelData.Entry> - { - private static FuelData _instance; - - public static FuelData Instance() - { - return _instance ?? (_instance = new FuelData()); - } - - private FuelData() {} - - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".FuelTypes.csv"; } - } - - protected override string ErrorMessage - { - get { throw new InvalidOperationException("ErrorMessage not applicable."); } - } - - public static Entry Diesel - { - get { return Instance().Lookup(FuelType.DieselCI); } - } - - protected override void ParseData(DataTable table) - { - Data = table.Rows.Cast<DataRow>() - .Select(r => { - var density = r.Field<string>("fueldensity"); - return new Entry( - r.Field<string>(0).ParseEnum<FuelType>(), - string.IsNullOrWhiteSpace(density) ? null : density.ToDouble(0).SI<KilogramPerCubicMeter>(), - r.ParseDouble("co2perfuelweight"), - r.ParseDouble("lowerheatingvalue").SI().Kilo.Joule.Per.Kilo.Gramm.Cast<JoulePerKilogramm>() - ); - }) - .ToDictionary(e => e.FuelType); - } - - public class Entry - { - public Entry(FuelType type, KilogramPerCubicMeter density, double weight, JoulePerKilogramm heatingValue) - { - FuelType = type; - FuelDensity = density; - CO2PerFuelWeight = weight; - LowerHeatingValue = heatingValue; - } - - public FuelType FuelType { get; private set; } - - public KilogramPerCubicMeter FuelDensity { get; private set; } - - public double CO2PerFuelWeight { get; private set; } - - public JoulePerKilogramm LowerHeatingValue { get; private set; } - } - } +using System; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class FuelData : LookupData<FuelType, FuelData.Entry> + { + private static FuelData _instance; + + public static FuelData Instance() + { + return _instance ?? (_instance = new FuelData()); + } + + private FuelData() {} + + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".FuelTypes.csv"; } + } + + protected override string ErrorMessage + { + get { throw new InvalidOperationException("ErrorMessage not applicable."); } + } + + public static Entry Diesel + { + get { return Instance().Lookup(FuelType.DieselCI); } + } + + protected override void ParseData(DataTable table) + { + Data = table.Rows.Cast<DataRow>() + .Select(r => { + var density = r.Field<string>("fueldensity"); + return new Entry( + r.Field<string>(0).ParseEnum<FuelType>(), + string.IsNullOrWhiteSpace(density) ? null : density.ToDouble(0).SI<KilogramPerCubicMeter>(), + r.ParseDouble("co2perfuelweight"), + r.ParseDouble("lowerheatingvalue").SI().Kilo.Joule.Per.Kilo.Gramm.Cast<JoulePerKilogramm>() + ); + }) + .ToDictionary(e => e.FuelType); + } + + public struct Entry + { + public Entry(FuelType type, KilogramPerCubicMeter density, double weight, JoulePerKilogramm heatingValue) : this() + { + FuelType = type; + FuelDensity = density; + CO2PerFuelWeight = weight; + LowerHeatingValue = heatingValue; + } + + public FuelType FuelType { get; private set; } + + public KilogramPerCubicMeter FuelDensity { get; private set; } + + public double CO2PerFuelWeight { get; private set; } + + public JoulePerKilogramm LowerHeatingValue { get; private set; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/HVAC.cs b/VectoCore/VectoCore/Models/Declaration/HVAC.cs index 5a59d415340dc4a61d732e0aa73cf5120e6655e1..650b6c576ca488b4616201e3a868c3e430517f8b 100644 --- a/VectoCore/VectoCore/Models/Declaration/HVAC.cs +++ b/VectoCore/VectoCore/Models/Declaration/HVAC.cs @@ -29,50 +29,52 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class HeatingVentilationAirConditioning : LookupData<MissionType, string, VehicleClass, Watt>, - IDeclarationAuxiliaryTable - { - private List<string> Technologies; - - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".VAUX.HVAC-Table.csv"; } - } - - protected override string ErrorMessage - { - get { - return "Auxiliary Lookup Error: No value found for HVAC. Mission: '{0}', Technology: '{1}' , HDVClass: '{2}'"; - } - } - - protected override void ParseData(DataTable table) - { - foreach (DataRow row in table.Rows) { - var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); - var technology = row.Field<string>("technology"); - foreach (DataColumn col in table.Columns) { - var value = row.ParseDoubleOrGetDefault(col.Caption, double.NaN); - if (col.Caption != "hdvclass" && col.Caption != "technology" && !double.IsNaN(value)) { - Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), technology, hdvClass)] = value.SI<Watt>(); - } - } - } - Technologies = Data.Select(x => x.Key.Item2).Distinct().ToList(); - } - - public string[] GetTechnologies() - { - return Technologies.ToArray(); - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class HeatingVentilationAirConditioning : LookupData<MissionType, string, VehicleClass, AuxDemandEntry>, + IDeclarationAuxiliaryTable + { + private List<string> Technologies; + + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".VAUX.HVAC-Table.csv"; } + } + + protected override string ErrorMessage + { + get { + return "Auxiliary Lookup Error: No value found for HVAC. Mission: '{0}', Technology: '{1}' , HDVClass: '{2}'"; + } + } + + protected override void ParseData(DataTable table) + { + foreach (DataRow row in table.Rows) { + var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); + var technology = row.Field<string>("technology"); + foreach (DataColumn col in table.Columns) { + var value = row.ParseDoubleOrGetDefault(col.Caption, double.NaN); + if (col.Caption != "hdvclass" && col.Caption != "technology" && !double.IsNaN(value)) { + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), technology, hdvClass)] = new AuxDemandEntry() { + PowerDemand = value.SI<Watt>() + }; + } + } + } + Technologies = Data.Select(x => x.Key.Item2).Distinct().ToList(); + } + + public string[] GetTechnologies() + { + return Technologies.ToArray(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/LookupData.cs b/VectoCore/VectoCore/Models/Declaration/LookupData.cs index 933841f9c4fb0c38702425b2f45a511fb1e7fc9f..18a24da2aaa0ae03aebded43a37ba0a35e3c5847 100644 --- a/VectoCore/VectoCore/Models/Declaration/LookupData.cs +++ b/VectoCore/VectoCore/Models/Declaration/LookupData.cs @@ -29,91 +29,91 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public abstract class LookupData : LoggingObject - { - protected abstract string ResourceId { get; } - protected abstract string ErrorMessage { get; } - protected abstract void ParseData(DataTable table); - - protected LookupData() - { - if (!string.IsNullOrWhiteSpace(ResourceId)) { - var table = ReadCsvResource(ResourceId); - NormalizeTable(table); - ParseData(table); - } - } - - protected static DataTable ReadCsvResource(string resourceId) - { - return VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceId), source: resourceId); - } - - protected static void NormalizeTable(DataTable table) - { - foreach (DataColumn col in table.Columns) { - table.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().RemoveWhitespace(); - } - } - } - - public abstract class LookupData<TKey, TValue> : LookupData - { - protected Dictionary<TKey, TValue> Data = new Dictionary<TKey, TValue>(); - - public virtual TValue Lookup(TKey key) - { - try { - return Data[key]; - } catch (KeyNotFoundException) { - throw new VectoException(string.Format(ErrorMessage, key)); - } - } - } - - public abstract class LookupData<TKey1, TKey2, TValue> : LookupData - { - protected readonly Dictionary<Tuple<TKey1, TKey2>, TValue> Data = new Dictionary<Tuple<TKey1, TKey2>, TValue>(); - - public virtual TValue Lookup(TKey1 key1, TKey2 key2) - { - try { - return Data[Tuple.Create(key1, key2)]; - } catch (KeyNotFoundException) { - throw new VectoException(string.Format(ErrorMessage, key1, key2)); - } - } - } - - public abstract class LookupData<TKey1, TKey2, TKey3, TValue> : LookupData - { - protected readonly Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue> Data = - new Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue>(); - - public virtual TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3) - { - try { - return Data[Tuple.Create(key1, key2, key3)]; - } catch (KeyNotFoundException) { - throw new VectoException(string.Format(ErrorMessage, key1, key2, key3)); - } - } - - //public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3); - } - - public abstract class LookupData<TKey1, TKey2, TKey3, TKey4, TValue> : LookupData - { - public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3, TKey4 key4); - } +using System; +using System.Collections.Generic; +using System.Data; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public abstract class LookupData : LoggingObject + { + protected abstract string ResourceId { get; } + protected abstract string ErrorMessage { get; } + protected abstract void ParseData(DataTable table); + + protected LookupData() + { + if (!string.IsNullOrWhiteSpace(ResourceId)) { + var table = ReadCsvResource(ResourceId); + NormalizeTable(table); + ParseData(table); + } + } + + protected static DataTable ReadCsvResource(string resourceId) + { + return VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceId), source: resourceId); + } + + protected static void NormalizeTable(DataTable table) + { + foreach (DataColumn col in table.Columns) { + table.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().RemoveWhitespace(); + } + } + } + + public abstract class LookupData<TKey, TValue> : LookupData where TValue : struct + { + protected Dictionary<TKey, TValue> Data = new Dictionary<TKey, TValue>(); + + public virtual TValue Lookup(TKey key) + { + try { + return Data[key]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key)); + } + } + } + + public abstract class LookupData<TKey1, TKey2, TValue> : LookupData where TValue : struct + { + protected readonly Dictionary<Tuple<TKey1, TKey2>, TValue> Data = new Dictionary<Tuple<TKey1, TKey2>, TValue>(); + + public virtual TValue Lookup(TKey1 key1, TKey2 key2) + { + try { + return Data[Tuple.Create(key1, key2)]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key1, key2)); + } + } + } + + public abstract class LookupData<TKey1, TKey2, TKey3, TValue> : LookupData where TValue : struct + { + protected readonly Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue> Data = + new Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue>(); + + public virtual TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3) + { + try { + return Data[Tuple.Create(key1, key2, key3)]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key1, key2, key3)); + } + } + + //public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3); + } + + public abstract class LookupData<TKey1, TKey2, TKey3, TKey4, TValue> : LookupData where TValue : struct + { + public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3, TKey4 key4); + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/Mission.cs b/VectoCore/VectoCore/Models/Declaration/Mission.cs index 2e1fac83d741e53777a232c965a96af38d1b904b..e0b15c2687297f5b417dfe312170a5adc512a945 100644 --- a/VectoCore/VectoCore/Models/Declaration/Mission.cs +++ b/VectoCore/VectoCore/Models/Declaration/Mission.cs @@ -29,79 +29,79 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public enum LoadingType - { - FullLoading, - ReferenceLoad, - LowLoading, - EmptyLoading, - } - - public class Mission - { - public MissionType MissionType; - public string CrossWindCorrectionParameters; - public double[] AxleWeightDistribution; - - public Kilogram BodyCurbWeight; - - public Stream CycleFile; - - public List<MissionTrailer> Trailer; - - public Kilogram MinLoad; - public Kilogram LowLoad; - public Kilogram RefLoad; - public Kilogram MaxLoad; - - public CubicMeter TotalCargoVolume; - - public Dictionary<LoadingType, Kilogram> Loadings - { - get { - return new Dictionary<LoadingType, Kilogram> { - { LoadingType.LowLoading, LowLoad }, - { LoadingType.ReferenceLoad, RefLoad }, - }; - } - } - } - - public class MissionTrailer - { - public TrailerType TrailerType; - public Kilogram TrailerCurbWeight; - public Kilogram TrailerGrossVehicleWeight; - public List<Wheels.Entry> TrailerWheels; - public double TrailerAxleWeightShare; - public SquareMeter DeltaCdA; - public CubicMeter CargoVolume; - } - - public enum TrailerType - { - //None, - T1, - T2, - ST1, - Dolly - } - - public static class TrailterTypeHelper - { - public static TrailerType Parse(string trailer) - { - if ("d".Equals(trailer, StringComparison.InvariantCultureIgnoreCase)) { - return TrailerType.Dolly; - } - return trailer.ParseEnum<TrailerType>(); - } - } +using System; +using System.Collections.Generic; +using System.IO; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public enum LoadingType + { + FullLoading, + ReferenceLoad, + LowLoading, + EmptyLoading, + } + + public class Mission + { + public MissionType MissionType; + public string CrossWindCorrectionParameters; + public double[] AxleWeightDistribution; + + public Kilogram BodyCurbWeight; + + public Stream CycleFile; + + public List<MissionTrailer> Trailer; + + public Kilogram MinLoad; + public Kilogram LowLoad; + public Kilogram RefLoad; + public Kilogram MaxLoad; + + public CubicMeter TotalCargoVolume; + + public Dictionary<LoadingType, Kilogram> Loadings + { + get { + return new Dictionary<LoadingType, Kilogram> { + { LoadingType.LowLoading, LowLoad }, + { LoadingType.ReferenceLoad, RefLoad }, + }; + } + } + } + + public class MissionTrailer + { + public TrailerType TrailerType; + public Kilogram TrailerCurbWeight; + public Kilogram TrailerGrossVehicleWeight; + public List<Wheels.Entry> TrailerWheels; + public double TrailerAxleWeightShare; + public SquareMeter DeltaCdA; + public CubicMeter CargoVolume; + } + + public enum TrailerType + { + //None, + T1, + T2, + ST1, + Dolly + } + + public static class TrailterTypeHelper + { + public static TrailerType Parse(string trailer) + { + if ("d".Equals(trailer, StringComparison.InvariantCultureIgnoreCase)) { + return TrailerType.Dolly; + } + return trailer.ParseEnum<TrailerType>(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/PT1.cs b/VectoCore/VectoCore/Models/Declaration/PT1.cs index 085011993d36a09c8c38a32853a15d12ceca7209..f4737177eccfedc65f67dc12f3d09f6fd6b2c402 100644 --- a/VectoCore/VectoCore/Models/Declaration/PT1.cs +++ b/VectoCore/VectoCore/Models/Declaration/PT1.cs @@ -29,101 +29,101 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class PT1 : LookupData<PerSecond, PT1.PT1Result> - { - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".PT1.csv"; } - } - - protected override string ErrorMessage - { - get { throw new InvalidOperationException("ErrorMessage not applicable."); } - } - - private List<KeyValuePair<PerSecond, Second>> _entries; - - public PT1() - { - ParseData(ReadCsvResource(ResourceId)); - } - - public PT1(DataTable data) - { - ParseDataFromFld(data); - } - - protected override void ParseData(DataTable table) - { - _entries = table.Rows.Cast<DataRow>() - .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble("rpm").RPMtoRad(), r.ParseDouble("PT1").SI<Second>())) - .OrderBy(x => x.Key) - .ToList(); - } - - private void ParseDataFromFld(DataTable data) - { - if (data.Columns.Count < 3) { - throw new VectoException("FullLoadCurve/PT1 Data File must consist of at least 4 columns."); - } - - if (data.Rows.Count < 2) { - throw new VectoException( - "FullLoadCurve/PT1 must consist of at least two lines with numeric values (below file header)"); - } - - if (data.Columns.Contains(Fields.EngineSpeed) && data.Columns.Contains(Fields.PT1)) { - _entries = data.Rows.Cast<DataRow>() - .Select( - r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(Fields.EngineSpeed).RPMtoRad(), - r.ParseDouble(Fields.PT1).SI<Second>())) - .OrderBy(x => x.Key).ToList(); - } else { - _entries = data.Rows.Cast<DataRow>() - .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(0).RPMtoRad(), r.ParseDouble(3).SI<Second>())) - .OrderBy(x => x.Key).ToList(); - } - } - - public override PT1Result Lookup(PerSecond key) - { - var extrapolated = key.IsSmaller(_entries[0].Key) || key.IsGreater(_entries.Last().Key); - - var index = _entries.FindIndex(x => x.Key.IsGreater(key)); - if (index <= 0) { - index = key.IsGreater(_entries[0].Key) ? _entries.Count - 1 : 1; - } - - var pt1 = VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value, - _entries[index].Value, key); - if (pt1 < 0) { - pt1 = 0.SI<Second>(); - extrapolated = true; - //throw new VectoException("The calculated pt1 value must not be smaller than 0. Value: " + pt1); - } - return new PT1Result() { Value = pt1, Extrapolated = extrapolated }; - } - - private static class Fields - { - public const string PT1 = "PT1"; - public const string EngineSpeed = "engine speed"; - } - - public class PT1Result - { - public Second Value; - public bool Extrapolated; - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class PT1 : LookupData<PerSecond, PT1.PT1Result> + { + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".PT1.csv"; } + } + + protected override string ErrorMessage + { + get { throw new InvalidOperationException("ErrorMessage not applicable."); } + } + + private List<KeyValuePair<PerSecond, Second>> _entries; + + public PT1() + { + ParseData(ReadCsvResource(ResourceId)); + } + + public PT1(DataTable data) + { + ParseDataFromFld(data); + } + + protected override void ParseData(DataTable table) + { + _entries = table.Rows.Cast<DataRow>() + .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble("rpm").RPMtoRad(), r.ParseDouble("PT1").SI<Second>())) + .OrderBy(x => x.Key) + .ToList(); + } + + private void ParseDataFromFld(DataTable data) + { + if (data.Columns.Count < 3) { + throw new VectoException("FullLoadCurve/PT1 Data File must consist of at least 4 columns."); + } + + if (data.Rows.Count < 2) { + throw new VectoException( + "FullLoadCurve/PT1 must consist of at least two lines with numeric values (below file header)"); + } + + if (data.Columns.Contains(Fields.EngineSpeed) && data.Columns.Contains(Fields.PT1)) { + _entries = data.Rows.Cast<DataRow>() + .Select( + r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(Fields.EngineSpeed).RPMtoRad(), + r.ParseDouble(Fields.PT1).SI<Second>())) + .OrderBy(x => x.Key).ToList(); + } else { + _entries = data.Rows.Cast<DataRow>() + .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(0).RPMtoRad(), r.ParseDouble(3).SI<Second>())) + .OrderBy(x => x.Key).ToList(); + } + } + + public override PT1Result Lookup(PerSecond key) + { + var extrapolated = key.IsSmaller(_entries[0].Key) || key.IsGreater(_entries.Last().Key); + + var index = _entries.FindIndex(x => x.Key.IsGreater(key)); + if (index <= 0) { + index = key.IsGreater(_entries[0].Key) ? _entries.Count - 1 : 1; + } + + var pt1 = VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value, + _entries[index].Value, key); + if (pt1 < 0) { + pt1 = 0.SI<Second>(); + extrapolated = true; + //throw new VectoException("The calculated pt1 value must not be smaller than 0. Value: " + pt1); + } + return new PT1Result() { Value = pt1, Extrapolated = extrapolated }; + } + + private static class Fields + { + public const string PT1 = "PT1"; + public const string EngineSpeed = "engine speed"; + } + + public struct PT1Result + { + public Second Value; + public bool Extrapolated; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/PTOTransmission.cs b/VectoCore/VectoCore/Models/Declaration/PTOTransmission.cs index ffbfd1fe09992698d6005baebbdd03d6b0a355d4..1231691fafa4537d39eeae34daa7b8928bceb9d3 100644 --- a/VectoCore/VectoCore/Models/Declaration/PTOTransmission.cs +++ b/VectoCore/VectoCore/Models/Declaration/PTOTransmission.cs @@ -36,7 +36,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class PTOTransmission : LookupData<string, Watt>, IDeclarationAuxiliaryTable + public sealed class PTOTransmission : LookupData<string, AuxDemandEntry>, IDeclarationAuxiliaryTable { public const string NoPTO = "None"; @@ -54,7 +54,7 @@ namespace TUGraz.VectoCore.Models.Declaration { Data = table.Rows.Cast<DataRow>().ToDictionary( r => r.Field<string>("technology"), - r => r.ParseDouble("powerloss").SI<Watt>()); + r => new AuxDemandEntry { PowerDemand = r.ParseDouble("powerloss").SI<Watt>() }); } public string[] GetTechnologies() diff --git a/VectoCore/VectoCore/Models/Declaration/Payloads.cs b/VectoCore/VectoCore/Models/Declaration/Payloads.cs index 1203a2743e97da58e26745287bd0808b86a2d8b6..be9d124b14d6a4971662cba681b86d05173723ce 100644 --- a/VectoCore/VectoCore/Models/Declaration/Payloads.cs +++ b/VectoCore/VectoCore/Models/Declaration/Payloads.cs @@ -29,72 +29,72 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class Payloads : LookupData<Kilogram, Payloads.PayloadEntry> - { - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".Payloads.csv"; } - } - - protected override string ErrorMessage - { - get { throw new InvalidOperationException("ErrorMessage not applicable."); } - } - - public Kilogram Lookup10Percent(Kilogram grossVehicleWeight) - { - var section = Data.GetSection(d => d.Key > grossVehicleWeight); - return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, - section.Item1.Value.Payload10Percent, section.Item2.Value.Payload10Percent, - grossVehicleWeight); - } - - public Kilogram Lookup50Percent(Kilogram grossVehicleWeight) - { - var section = Data.GetSection(d => d.Key > grossVehicleWeight); - return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, - section.Item1.Value.Payload50Percent, section.Item2.Value.Payload50Percent, - grossVehicleWeight); - } - - public Kilogram Lookup75Percent(Kilogram grossVehicleWeight) - { - var section = Data.GetSection(d => d.Key > grossVehicleWeight); - return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, - section.Item1.Value.Payload75Percent, section.Item2.Value.Payload75Percent, - grossVehicleWeight); - } - - public Kilogram LookupTrailer(Kilogram grossVehicleWeight, Kilogram curbWeight) - { - return 0.75 * (grossVehicleWeight - curbWeight); - } - - protected override void ParseData(DataTable table) - { - Data = table.Rows.Cast<DataRow>() - .ToDictionary( - kv => kv.ParseDouble("grossvehicleweight").SI<Kilogram>(), - kv => new PayloadEntry { - Payload10Percent = kv.ParseDouble("payload10%").SI<Kilogram>(), - Payload50Percent = kv.ParseDouble("payload50%").SI<Kilogram>(), - Payload75Percent = kv.ParseDouble("payload75%").SI<Kilogram>() - }); - } - - public sealed class PayloadEntry - { - public Kilogram Payload10Percent; - public Kilogram Payload50Percent; - public Kilogram Payload75Percent; - } - } +using System; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class Payloads : LookupData<Kilogram, Payloads.PayloadEntry> + { + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".Payloads.csv"; } + } + + protected override string ErrorMessage + { + get { throw new InvalidOperationException("ErrorMessage not applicable."); } + } + + public Kilogram Lookup10Percent(Kilogram grossVehicleWeight) + { + var section = Data.GetSection(d => d.Key > grossVehicleWeight); + return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, + section.Item1.Value.Payload10Percent, section.Item2.Value.Payload10Percent, + grossVehicleWeight); + } + + public Kilogram Lookup50Percent(Kilogram grossVehicleWeight) + { + var section = Data.GetSection(d => d.Key > grossVehicleWeight); + return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, + section.Item1.Value.Payload50Percent, section.Item2.Value.Payload50Percent, + grossVehicleWeight); + } + + public Kilogram Lookup75Percent(Kilogram grossVehicleWeight) + { + var section = Data.GetSection(d => d.Key > grossVehicleWeight); + return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, + section.Item1.Value.Payload75Percent, section.Item2.Value.Payload75Percent, + grossVehicleWeight); + } + + public Kilogram LookupTrailer(Kilogram grossVehicleWeight, Kilogram curbWeight) + { + return 0.75 * (grossVehicleWeight - curbWeight); + } + + protected override void ParseData(DataTable table) + { + Data = table.Rows.Cast<DataRow>() + .ToDictionary( + kv => kv.ParseDouble("grossvehicleweight").SI<Kilogram>(), + kv => new PayloadEntry { + Payload10Percent = kv.ParseDouble("payload10%").SI<Kilogram>(), + Payload50Percent = kv.ParseDouble("payload50%").SI<Kilogram>(), + Payload75Percent = kv.ParseDouble("payload75%").SI<Kilogram>() + }); + } + + public struct PayloadEntry + { + public Kilogram Payload10Percent; + public Kilogram Payload50Percent; + public Kilogram Payload75Percent; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs b/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs index 4f4194b90a29696a8db9f54f66968853a85d6403..ef291b23cd70ad0a2d0e478a3f61b2041245cc1a 100644 --- a/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs +++ b/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs @@ -37,7 +37,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class PneumaticSystem : LookupData<MissionType, string, Watt>, IDeclarationAuxiliaryTable + public sealed class PneumaticSystem : LookupData<MissionType, string, AuxDemandEntry>, IDeclarationAuxiliaryTable { protected override string ResourceId { @@ -55,7 +55,9 @@ namespace TUGraz.VectoCore.Models.Declaration var technology = row.Field<string>("technology"); foreach (DataColumn col in table.Columns) { if (col.Caption != "technology") { - Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), technology)] = row.ParseDouble(col.Caption).SI<Watt>(); + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), technology)] = new AuxDemandEntry() { + PowerDemand = row.ParseDouble(col.Caption).SI<Watt>() + }; } } } diff --git a/VectoCore/VectoCore/Models/Declaration/Segment.cs b/VectoCore/VectoCore/Models/Declaration/Segment.cs index 16abc25895037280bf41566fa923085da223b0e7..2dee8dfb6e52a66d25d37cc9d200cce51224c156 100644 --- a/VectoCore/VectoCore/Models/Declaration/Segment.cs +++ b/VectoCore/VectoCore/Models/Declaration/Segment.cs @@ -29,38 +29,40 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.IO; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public class Segment - { - public VehicleClass VehicleClass { get; internal set; } - - public VehicleCategory VehicleCategory { get; set; } - - public AxleConfiguration AxleConfiguration { get; set; } - - public Kilogram GrossVehicleWeightMin { get; set; } - - public Kilogram GrossVehicleWeightMax { get; set; } - - public Kilogram GrossVehicleMassRating { get; set; } - - public Stream AccelerationFile { get; internal set; } - - public Mission[] Missions { get; internal set; } - - public Meter VehicleHeight { get; internal set; } - - public MeterPerSecond DesignSpeed { get; internal set; } - - public SquareMeter CdADefault { get; internal set; } - - public SquareMeter CdAConstruction { get; internal set; } - - public Kilogram MunicipalBodyWeight { get; internal set; } - } +using System.IO; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public struct Segment + { + public bool Found; + + public VehicleClass VehicleClass { get; internal set; } + + public VehicleCategory VehicleCategory { get; set; } + + public AxleConfiguration AxleConfiguration { get; set; } + + public Kilogram GrossVehicleWeightMin { get; set; } + + public Kilogram GrossVehicleWeightMax { get; set; } + + public Kilogram GrossVehicleMassRating { get; set; } + + public Stream AccelerationFile { get; internal set; } + + public Mission[] Missions { get; internal set; } + + public Meter VehicleHeight { get; internal set; } + + public MeterPerSecond DesignSpeed { get; internal set; } + + public SquareMeter CdADefault { get; internal set; } + + public SquareMeter CdAConstruction { get; internal set; } + + public Kilogram MunicipalBodyWeight { get; internal set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/Segments.cs b/VectoCore/VectoCore/Models/Declaration/Segments.cs index 1d6997e14eb7ddfd5db7cb1ef874ac3d7c56497a..f9e89983f303ea9f82d50780d58d349e85b910d9 100644 --- a/VectoCore/VectoCore/Models/Declaration/Segments.cs +++ b/VectoCore/VectoCore/Models/Declaration/Segments.cs @@ -29,132 +29,136 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class Segments : LookupData<VehicleCategory, AxleConfiguration, Kilogram, Kilogram, Segment> - { - private DataTable _segmentTable; - - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".SegmentTable.csv"; } - } - - protected override string ErrorMessage - { - get { - return - "ERROR: Could not find the declaration segment for vehicle. Category: {0}, AxleConfiguration: {1}, GrossVehicleWeight: {2}"; - } - } - - protected override void ParseData(DataTable table) - { - _segmentTable = table.Copy(); - } - - public override Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, - Kilogram grossVehicleMassRating, Kilogram curbWeight) - { - return Lookup(vehicleCategory, axleConfiguration, grossVehicleMassRating, curbWeight, false); - } - - public Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, - Kilogram grossVehicleMassRating, Kilogram curbWeight, bool considerInvalid) - { - if (grossVehicleMassRating == null || grossVehicleMassRating < 7.5.SI().Ton) { - throw new VectoException("Gross vehicle mass must be greater than 7.5 tons"); - } - - var row = GetSegmentDataRow(vehicleCategory, axleConfiguration, grossVehicleMassRating, considerInvalid); - - var segment = new Segment { - GrossVehicleWeightMin = row.ParseDouble("gvw_min").SI().Ton.Cast<Kilogram>(), - GrossVehicleWeightMax = row.ParseDouble("gvw_max").SI().Ton.Cast<Kilogram>(), - VehicleCategory = vehicleCategory, - AxleConfiguration = axleConfiguration, - VehicleClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")), - AccelerationFile = - RessourceHelper.ReadStream(DeclarationData.DeclarationDataResourcePrefix + ".VACC." + - row.Field<string>(".vaccfile")), - Missions = CreateMissions(ref grossVehicleMassRating, curbWeight, row), - VehicleHeight = LookupHeight(vehicleCategory, axleConfiguration, grossVehicleMassRating), - DesignSpeed = row.ParseDouble("designspeed").KMPHtoMeterPerSecond(), - GrossVehicleMassRating = grossVehicleMassRating, - CdADefault = row.ParseDouble("cdxa_default").SI<SquareMeter>(), - CdAConstruction = string.IsNullOrEmpty(row["cdxa_construction"].ToString()) - ? null - : row.ParseDouble("cdxa_construction").SI<SquareMeter>(), - MunicipalBodyWeight = string.IsNullOrEmpty(row["bodyweight_municipalutility"].ToString()) - ? null - : row.ParseDouble("bodyweight_municipalutility").SI<Kilogram>() - }; - - return segment; - } - - private DataRow GetSegmentDataRow(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, - Kilogram grossVehicleMassRating, bool considerInvalid) - { - DataRow row; - try { - row = _segmentTable.AsEnumerable().First(r => { - var isValid = r.Field<string>("valid"); - var category = r.Field<string>("vehiclecategory"); - var axleConf = r.Field<string>("axleconf."); - var massMin = r.ParseDouble("gvw_min").SI().Ton; - var massMax = r.ParseDouble("gvw_max").SI().Ton; - return (considerInvalid || isValid == "1") - && category == vehicleCategory.ToString() - && axleConf == axleConfiguration.GetName() - // MK 2016-06-07: normally the next condition should be "mass > massMin", except for 7.5t where is should be ">=" - // in any case ">=" is also correct, because the segment table is sorted by weight. - && massMin <= grossVehicleMassRating && grossVehicleMassRating <= massMax; - }); - } catch (InvalidOperationException e) { - var errorMessage = string.Format(ErrorMessage, vehicleCategory, axleConfiguration.GetName(), - grossVehicleMassRating); - Log.Fatal(errorMessage); - throw new VectoException(errorMessage, e); - } - return row; - } - - public Meter LookupHeight(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, - Kilogram grossVehicleMassRating) - { - var row = GetSegmentDataRow(vehicleCategory, axleConfiguration, grossVehicleMassRating, true); - - var vehicleHeight = row.ParseDouble("height").SI<Meter>(); - var vehicleClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); - - if (vehicleClass == VehicleClass.Class9) { - // VECTO-471: for class 9 take similar height than rigid with same maximum gross vehicle weight (class 1, 2, 3 or 4). - var rigidGVWrow = _segmentTable.AsEnumerable().FirstOrDefault(r => { - var massMin = r.ParseDouble("gvw_min").SI().Ton; - var massMax = r.ParseDouble("gvw_max").SI().Ton; - return new[] { "1", "2", "3", "4" }.Contains(r.Field<string>("hdvclass")) - && massMin <= grossVehicleMassRating && grossVehicleMassRating <= massMax; - }); - if (rigidGVWrow != null) { - vehicleHeight = rigidGVWrow.ParseDouble("height").SI<Meter>(); - } - } - - return vehicleHeight; - } - +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class Segments : LookupData<VehicleCategory, AxleConfiguration, Kilogram, Kilogram, Segment> + { + private DataTable _segmentTable; + + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".SegmentTable.csv"; } + } + + protected override string ErrorMessage + { + get { + return + "ERROR: Could not find the declaration segment for vehicle. Category: {0}, AxleConfiguration: {1}, GrossVehicleWeight: {2}"; + } + } + + protected override void ParseData(DataTable table) + { + _segmentTable = table.Copy(); + } + + public override Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + Kilogram grossVehicleMassRating, Kilogram curbWeight) + { + return Lookup(vehicleCategory, axleConfiguration, grossVehicleMassRating, curbWeight, false); + } + + public Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + Kilogram grossVehicleMassRating, Kilogram curbWeight, bool considerInvalid) + { + if (grossVehicleMassRating == null || grossVehicleMassRating < 7.5.SI().Ton) { + throw new VectoException("Gross vehicle mass must be greater than 7.5 tons"); + } + + var row = GetSegmentDataRow(vehicleCategory, axleConfiguration, grossVehicleMassRating, considerInvalid); + if (row == null) { + return new Segment() { Found = false }; + } + + var segment = new Segment { + Found = true, + GrossVehicleWeightMin = row.ParseDouble("gvw_min").SI().Ton.Cast<Kilogram>(), + GrossVehicleWeightMax = row.ParseDouble("gvw_max").SI().Ton.Cast<Kilogram>(), + VehicleCategory = vehicleCategory, + AxleConfiguration = axleConfiguration, + VehicleClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")), + AccelerationFile = + RessourceHelper.ReadStream(DeclarationData.DeclarationDataResourcePrefix + ".VACC." + + row.Field<string>(".vaccfile")), + Missions = CreateMissions(ref grossVehicleMassRating, curbWeight, row), + VehicleHeight = LookupHeight(vehicleCategory, axleConfiguration, grossVehicleMassRating), + DesignSpeed = row.ParseDouble("designspeed").KMPHtoMeterPerSecond(), + GrossVehicleMassRating = grossVehicleMassRating, + CdADefault = row.ParseDouble("cdxa_default").SI<SquareMeter>(), + CdAConstruction = string.IsNullOrEmpty(row["cdxa_construction"].ToString()) + ? null + : row.ParseDouble("cdxa_construction").SI<SquareMeter>(), + MunicipalBodyWeight = string.IsNullOrEmpty(row["bodyweight_municipalutility"].ToString()) + ? null + : row.ParseDouble("bodyweight_municipalutility").SI<Kilogram>() + }; + + return segment; + } + + private DataRow GetSegmentDataRow(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + Kilogram grossVehicleMassRating, bool considerInvalid) + { + DataRow row; + try { + row = _segmentTable.AsEnumerable().First(r => { + var isValid = r.Field<string>("valid"); + var category = r.Field<string>("vehiclecategory"); + var axleConf = r.Field<string>("axleconf."); + var massMin = r.ParseDouble("gvw_min").SI().Ton; + var massMax = r.ParseDouble("gvw_max").SI().Ton; + return (considerInvalid || isValid == "1") + && category == vehicleCategory.ToString() + && axleConf == axleConfiguration.GetName() + // MK 2016-06-07: normally the next condition should be "mass > massMin", except for 7.5t where is should be ">=" + // in any case ">=" is also correct, because the segment table is sorted by weight. + && massMin <= grossVehicleMassRating && grossVehicleMassRating <= massMax; + }); + } catch (InvalidOperationException e) { + var errorMessage = string.Format(ErrorMessage, vehicleCategory, axleConfiguration.GetName(), + grossVehicleMassRating); + Log.Fatal(errorMessage); + throw new VectoException(errorMessage, e); + } + return row; + } + + public Meter LookupHeight(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + Kilogram grossVehicleMassRating) + { + var row = GetSegmentDataRow(vehicleCategory, axleConfiguration, grossVehicleMassRating, true); + + var vehicleHeight = row.ParseDouble("height").SI<Meter>(); + var vehicleClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); + + if (vehicleClass == VehicleClass.Class9) { + // VECTO-471: for class 9 take similar height than rigid with same maximum gross vehicle weight (class 1, 2, 3 or 4). + var rigidGVWrow = _segmentTable.AsEnumerable().FirstOrDefault(r => { + var massMin = r.ParseDouble("gvw_min").SI().Ton; + var massMax = r.ParseDouble("gvw_max").SI().Ton; + return new[] { "1", "2", "3", "4" }.Contains(r.Field<string>("hdvclass")) + && massMin <= grossVehicleMassRating && grossVehicleMassRating <= massMax; + }); + if (rigidGVWrow != null) { + vehicleHeight = rigidGVWrow.ParseDouble("height").SI<Meter>(); + } + } + + return vehicleHeight; + } + /// <summary> /// Looks up the default CdxA value for the cross wind correction. /// </summary> @@ -165,143 +169,146 @@ namespace TUGraz.VectoCore.Models.Declaration return row.SI<SquareMeter>("cdxa_default"); } - private static Mission[] CreateMissions(ref Kilogram grossVehicleWeight, Kilogram curbWeight, DataRow row) - { - var missionTypes = Enum.GetValues(typeof(MissionType)).Cast<MissionType>(); - var missions = new List<Mission>(); - foreach (var missionType in missionTypes.Where(m => row.Field<string>(m.ToString()) != "-")) { - var body = DeclarationData.StandardBodies.Lookup(row.Field<string>("body")); - - var maxGVW = Constants.SimulationSettings.MaximumGrossVehicleWeight; - var trailers = new List<MissionTrailer>(); - if (missionType.IsEMS()) { - maxGVW = Constants.SimulationSettings.MaximumGrossVehicleWeightEMS; - var trailerList = row.Field<string>("ems").Split('+'); - var trailerWeightShares = row.Field<string>("traileraxles" + GetMissionSuffix(missionType)).Split('/'); - if (trailerList.Length != trailerWeightShares.Length) { - throw new VectoException( - "Error in segmentation table: number of trailers and list of weight shares does not match!"); - } - trailers.AddRange( - trailerWeightShares.Select((t, i) => CreateTrailer(trailerList[i], t.ToDouble() / 100.0, i == 0))); - } else { - if (ShouldTrailerBeUsed(row, missionType)) { - var trailerValue = row.Field<string>("trailer"); - if (string.IsNullOrWhiteSpace(trailerValue)) { - throw new VectoException("Error in segmentation table: trailer weight share is defined but not trailer type!"); - } - trailers.Add(CreateTrailer(trailerValue, GetTrailerAxleWeightDistribution(row, missionType), true)); - } - } - - //var semiTrailerField = row.Field<string>("semitrailer"); - //var semiTrailer = !string.IsNullOrWhiteSpace(semiTrailerField) - // ? DeclarationData.StandardBodies.Lookup(semiTrailerField) - // : StandardBodies.Empty; - - //trailer += semiTrailer; - - // limit gvw to MaxGVW (40t) - var gvw = - VectoMath.Min( - grossVehicleWeight + trailers.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0), - maxGVW); - var maxLoad = gvw - curbWeight - body.CurbWeight - - trailers.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0); - - var payloads = row.Field<string>(missionType.ToString()).Split('/'); - Kilogram refLoad, lowLoad = 0.SI<Kilogram>(); - if (payloads.Length == 2) { - lowLoad = GetLoading(payloads[0], grossVehicleWeight, trailers, true); - refLoad = GetLoading(payloads[1], grossVehicleWeight, trailers, false); - } else { - refLoad = GetLoading(row.Field<string>(missionType.ToString()), grossVehicleWeight, trailers, false); - } - - refLoad = refLoad.LimitTo(0.SI<Kilogram>(), maxLoad); - lowLoad = lowLoad.LimitTo(0.SI<Kilogram>(), maxLoad); - - var mission = new Mission { - MissionType = missionType, - CrossWindCorrectionParameters = row.Field<string>("crosswindcorrection" + GetMissionSuffix(missionType, true)), - CycleFile = - RessourceHelper.ReadStream(DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." + - missionType.ToString().Replace("EMS", "") + - Constants.FileExtensions.CycleFile), - AxleWeightDistribution = GetAxleWeightDistribution(row, missionType), - BodyCurbWeight = body.CurbWeight, - Trailer = trailers, - MinLoad = 0.SI<Kilogram>(), - MaxLoad = maxLoad, - RefLoad = refLoad, - LowLoad = lowLoad, - TotalCargoVolume = body.CargoVolume + trailers.Sum(t => t.CargoVolume).DefaultIfNull(0), - }; - missions.Add(mission); - } - return missions.ToArray(); - } - - private static Kilogram GetLoading(string payloadStr, Kilogram grossVehicleWeight, - IEnumerable<MissionTrailer> trailers, bool lowLoading) - { - var refLoadValue = payloadStr.ToDouble(double.NaN); - if (double.IsNaN(refLoadValue)) { - return DeclarationData.GetPayloadForGrossVehicleWeight(grossVehicleWeight, payloadStr) + - trailers.Sum( - t => DeclarationData.GetPayloadForTrailerWeight(t.TrailerGrossVehicleWeight, t.TrailerCurbWeight, lowLoading)) - .DefaultIfNull(0); - } - return refLoadValue.SI<Kilogram>(); - } - - /// <summary> - /// Checks if a trailer should be used for the current missionType. - /// </summary> - private static bool ShouldTrailerBeUsed(DataRow row, MissionType missionType) - { - return !string.IsNullOrWhiteSpace(row.Field<string>("traileraxles" + GetMissionSuffix(missionType))); - } - - private static double GetTrailerAxleWeightDistribution(DataRow row, MissionType missionType) - { - var trailerAxles = - row.Field<string>("traileraxles" + GetMissionSuffix(missionType)); - if (!string.IsNullOrWhiteSpace(trailerAxles)) { - return trailerAxles.ToDouble() / 100.0; - } - return 0; - } - - private static double[] GetAxleWeightDistribution(DataRow row, MissionType missionType) - { - return - row.Field<string>("truckaxles" + GetMissionSuffix(missionType)) - .Split('/').ToDouble().Select(x => x / 100.0).ToArray(); - } - - private static string GetMissionSuffix(MissionType missionType, bool ignoreEMS = false) - { - return "-" + - (missionType.IsEMS() && ignoreEMS - ? "" - : (missionType.GetNonEMSMissionType() == MissionType.LongHaul ? "longhaul" : "other")) + - (missionType.IsEMS() ? "ems" : ""); - } - - private static MissionTrailer CreateTrailer(string trailerValue, double axleWeightShare, bool firstTrailer) - { - var trailerType = TrailterTypeHelper.Parse(trailerValue); - var trailer = DeclarationData.StandardBodies.Lookup(trailerType.ToString()); - return new MissionTrailer { - TrailerType = trailerType, - TrailerWheels = trailer.Wheels, - TrailerAxleWeightShare = axleWeightShare, - TrailerCurbWeight = trailer.CurbWeight, - TrailerGrossVehicleWeight = trailer.GrossVehicleWeight, - DeltaCdA = trailer.DeltaCrossWindArea[firstTrailer ? 0 : 1], - CargoVolume = trailer.CargoVolume - }; - } - } + private static Mission[] CreateMissions(ref Kilogram grossVehicleWeight, Kilogram curbWeight, DataRow row) + { + var missionTypes = Enum.GetValues(typeof(MissionType)).Cast<MissionType>(); + var missions = new List<Mission>(); + foreach (var missionType in missionTypes.Where(m => row.Field<string>(m.ToString()) != "-")) { + var body = DeclarationData.StandardBodies.Lookup(row.Field<string>("body")); + + var maxGVW = Constants.SimulationSettings.MaximumGrossVehicleWeight; + var trailers = new List<MissionTrailer>(); + if (missionType.IsEMS()) { + maxGVW = Constants.SimulationSettings.MaximumGrossVehicleWeightEMS; + var trailerList = row.Field<string>("ems").Split('+'); + var trailerWeightShares = row.Field<string>("traileraxles" + GetMissionSuffix(missionType)).Split('/'); + if (trailerList.Length != trailerWeightShares.Length) { + throw new VectoException( + "Error in segmentation table: number of trailers and list of weight shares does not match!"); + } + trailers.AddRange( + trailerWeightShares.Select((t, i) => CreateTrailer(trailerList[i], t.ToDouble() / 100.0, i == 0))); + } else { + if (ShouldTrailerBeUsed(row, missionType)) { + var trailerValue = row.Field<string>("trailer"); + if (string.IsNullOrWhiteSpace(trailerValue)) { + throw new VectoException("Error in segmentation table: trailer weight share is defined but not trailer type!"); + } + trailers.Add(CreateTrailer(trailerValue, GetTrailerAxleWeightDistribution(row, missionType), true)); + } + } + + //var semiTrailerField = row.Field<string>("semitrailer"); + //var semiTrailer = !string.IsNullOrWhiteSpace(semiTrailerField) + // ? DeclarationData.StandardBodies.Lookup(semiTrailerField) + // : StandardBodies.Empty; + + //trailer += semiTrailer; + + // limit gvw to MaxGVW (40t) + var gvw = + VectoMath.Min( + grossVehicleWeight + trailers.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0), + maxGVW); + var maxLoad = gvw - curbWeight - body.CurbWeight - + trailers.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0); + + var payloads = row.Field<string>(missionType.ToString()).Split('/'); + var vehicleWeight = curbWeight + body.CurbWeight; + Kilogram refLoad, lowLoad = 0.SI<Kilogram>(); + if (payloads.Length == 2) { + lowLoad = GetLoading(payloads[0], grossVehicleWeight, vehicleWeight, trailers, true); + refLoad = GetLoading(payloads[1], grossVehicleWeight, vehicleWeight, trailers, false); + } else { + refLoad = GetLoading(row.Field<string>(missionType.ToString()), grossVehicleWeight, vehicleWeight, trailers, false); + } + + refLoad = refLoad.LimitTo(0.SI<Kilogram>(), maxLoad); + lowLoad = lowLoad.LimitTo(0.SI<Kilogram>(), maxLoad); + + var mission = new Mission { + MissionType = missionType, + CrossWindCorrectionParameters = row.Field<string>("crosswindcorrection" + GetMissionSuffix(missionType, true)), + CycleFile = + RessourceHelper.ReadStream(DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." + + missionType.ToString().Replace("EMS", "") + + Constants.FileExtensions.CycleFile), + AxleWeightDistribution = GetAxleWeightDistribution(row, missionType), + BodyCurbWeight = body.CurbWeight, + Trailer = trailers, + MinLoad = 0.SI<Kilogram>(), + MaxLoad = maxLoad, + RefLoad = refLoad, + LowLoad = lowLoad, + TotalCargoVolume = body.CargoVolume + trailers.Sum(t => t.CargoVolume).DefaultIfNull(0), + }; + missions.Add(mission); + } + return missions.ToArray(); + } + + private static Kilogram GetLoading(string payloadStr, Kilogram grossVehicleWeight, Kilogram vehicleWeight, + IEnumerable<MissionTrailer> trailers, bool lowLoading) + { + var refLoadValue = payloadStr.ToDouble(double.NaN); + if (double.IsNaN(refLoadValue)) { + var vehiclePayload = DeclarationData.GetPayloadForGrossVehicleWeight(grossVehicleWeight, payloadStr) + .LimitTo(0.SI<Kilogram>(), grossVehicleWeight - vehicleWeight); + var trailerPayload = trailers.Sum( + t => DeclarationData.GetPayloadForTrailerWeight(t.TrailerGrossVehicleWeight, t.TrailerCurbWeight, lowLoading)) + .DefaultIfNull(0); + return vehiclePayload + trailerPayload; + } + return refLoadValue.SI<Kilogram>(); + } + + /// <summary> + /// Checks if a trailer should be used for the current missionType. + /// </summary> + private static bool ShouldTrailerBeUsed(DataRow row, MissionType missionType) + { + return !string.IsNullOrWhiteSpace(row.Field<string>("traileraxles" + GetMissionSuffix(missionType))); + } + + private static double GetTrailerAxleWeightDistribution(DataRow row, MissionType missionType) + { + var trailerAxles = + row.Field<string>("traileraxles" + GetMissionSuffix(missionType)); + if (!string.IsNullOrWhiteSpace(trailerAxles)) { + return trailerAxles.ToDouble() / 100.0; + } + return 0; + } + + private static double[] GetAxleWeightDistribution(DataRow row, MissionType missionType) + { + return + row.Field<string>("truckaxles" + GetMissionSuffix(missionType)) + .Split('/').ToDouble().Select(x => x / 100.0).ToArray(); + } + + private static string GetMissionSuffix(MissionType missionType, bool ignoreEMS = false) + { + return "-" + + (missionType.IsEMS() && ignoreEMS + ? "" + : (missionType.GetNonEMSMissionType() == MissionType.LongHaul ? "longhaul" : "other")) + + (missionType.IsEMS() ? "ems" : ""); + } + + private static MissionTrailer CreateTrailer(string trailerValue, double axleWeightShare, bool firstTrailer) + { + var trailerType = TrailterTypeHelper.Parse(trailerValue); + var trailer = DeclarationData.StandardBodies.Lookup(trailerType.ToString()); + return new MissionTrailer { + TrailerType = trailerType, + TrailerWheels = trailer.Wheels, + TrailerAxleWeightShare = axleWeightShare, + TrailerCurbWeight = trailer.CurbWeight, + TrailerGrossVehicleWeight = trailer.GrossVehicleWeight, + DeltaCdA = trailer.DeltaCrossWindArea[firstTrailer ? 0 : 1], + CargoVolume = trailer.CargoVolume + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs b/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs index 9b34acee42590d6b9733112cfda713842f067a21..f19aa9fb02fee03c6bef1810adbe47b8aeb565ef 100644 --- a/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs +++ b/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs @@ -29,105 +29,105 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class StandardBody - { - public readonly Kilogram CurbWeight; - public readonly Kilogram GrossVehicleWeight; - public readonly SquareMeter[] DeltaCrossWindArea; - public readonly string Name; - public readonly List<Wheels.Entry> Wheels; - public readonly CubicMeter CargoVolume; - - public Kilogram MaxPayLoad - { - get { return GrossVehicleWeight - CurbWeight; } - } - - public StandardBody(string name, Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter[] deltaCrossWindArea, - Wheels.Entry wheels, int axleCount, CubicMeter volume) : - this(name, curbWeight, grossVehicleWeight, deltaCrossWindArea, - wheels == null ? new List<Wheels.Entry>() : Enumerable.Repeat(wheels, axleCount).ToList(), volume) {} - - private StandardBody(string name, Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter[] deltaCrossWindArea, - List<Wheels.Entry> wheels, CubicMeter volume) - { - Name = name; - CurbWeight = curbWeight; - GrossVehicleWeight = grossVehicleWeight; - DeltaCrossWindArea = deltaCrossWindArea; - Wheels = wheels; - CargoVolume = volume; - } - - //public static StandardBody operator +(StandardBody first, StandardBody second) - //{ - // var wheels = new List<Wheels.Entry>(first.Wheels); - // wheels.AddRange(second.Wheels); - // return new StandardBody(first.Name + second.Name, first.CurbWeight + second.CurbWeight, - // first.GrossVehicleWeight + second.GrossVehicleWeight, - // first.DeltaCrossWindArea + second.DeltaCrossWindArea, - // wheels, first.CargoVolume + second.TotalCargoVolume); - //} - } - - /// <summary> - /// Lookup Class for Standard Weights of Bodies, Trailers and Semitrailers. - /// Standard Weights include - /// CurbWeight (=Empty Weight), - /// Gross Vehicle Weight (=Maximum Allowed Weight), - /// MaxPayload, - /// DeltaCrossWindArea, - /// Wheels - /// </summary> - public sealed class StandardBodies : LookupData<string, StandardBody> - { - public static readonly StandardBody Empty = new StandardBody("", 0.SI<Kilogram>(), 0.SI<Kilogram>(), - new[] { 0.SI<SquareMeter>(), 0.SI<SquareMeter>() }, null, 0, 0.SI<CubicMeter>()); - - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".Body_Trailers_Weights.csv"; } - } - - protected override string ErrorMessage - { - get { return "StandardWeigths Lookup Error: No value found for ID '{0}'"; } - } - - public override StandardBody Lookup(string id) - { - return string.IsNullOrWhiteSpace(id) ? Empty : base.Lookup(id); - } - - protected override void ParseData(DataTable table) - { - Data = table.Rows.Cast<DataRow>().Select(k => { - var deltaCdxAStr = k.Field<string>("deltacdxafortraileroperationinlonghaul"); - var deltaCdxA = new[] { 0.SI<SquareMeter>(), 0.SI<SquareMeter>() }; - if (!deltaCdxAStr.Equals("-")) { - deltaCdxA = deltaCdxAStr.Split('/').Select(x => x.ToDouble().SI<SquareMeter>()).ToArray(); - } - return new StandardBody( - k.Field<string>("name"), - k.ParseDoubleOrGetDefault("curbmass").SI<Kilogram>(), - k.ParseDoubleOrGetDefault("maxgrossmass").SI<Kilogram>(), - deltaCdxA, - !string.IsNullOrWhiteSpace(k.Field<string>("wheels")) - ? DeclarationData.Wheels.Lookup(k.Field<string>("wheels")) - : null, - Int32.Parse(k.Field<string>("axlecount")), - k.ParseDouble("cargovolume").SI<CubicMeter>()); - }) - .ToDictionary(kv => kv.Name); - } - } +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public struct StandardBody + { + public readonly Kilogram CurbWeight; + public readonly Kilogram GrossVehicleWeight; + public readonly SquareMeter[] DeltaCrossWindArea; + public readonly string Name; + public readonly List<Wheels.Entry> Wheels; + public readonly CubicMeter CargoVolume; + + public Kilogram MaxPayLoad + { + get { return GrossVehicleWeight - CurbWeight; } + } + + public StandardBody(string name, Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter[] deltaCrossWindArea, + Wheels.Entry? wheels, int axleCount, CubicMeter volume) : + this(name, curbWeight, grossVehicleWeight, deltaCrossWindArea, + !wheels.HasValue ? new List<Wheels.Entry>() : Enumerable.Repeat(wheels.Value, axleCount).ToList(), volume) {} + + private StandardBody(string name, Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter[] deltaCrossWindArea, + List<Wheels.Entry> wheels, CubicMeter volume) + { + Name = name; + CurbWeight = curbWeight; + GrossVehicleWeight = grossVehicleWeight; + DeltaCrossWindArea = deltaCrossWindArea; + Wheels = wheels; + CargoVolume = volume; + } + + //public static StandardBody operator +(StandardBody first, StandardBody second) + //{ + // var wheels = new List<Wheels.Entry>(first.Wheels); + // wheels.AddRange(second.Wheels); + // return new StandardBody(first.Name + second.Name, first.CurbWeight + second.CurbWeight, + // first.GrossVehicleWeight + second.GrossVehicleWeight, + // first.DeltaCrossWindArea + second.DeltaCrossWindArea, + // wheels, first.CargoVolume + second.TotalCargoVolume); + //} + } + + /// <summary> + /// Lookup Class for Standard Weights of Bodies, Trailers and Semitrailers. + /// Standard Weights include + /// CurbWeight (=Empty Weight), + /// Gross Vehicle Weight (=Maximum Allowed Weight), + /// MaxPayload, + /// DeltaCrossWindArea, + /// Wheels + /// </summary> + public sealed class StandardBodies : LookupData<string, StandardBody> + { + public static readonly StandardBody Empty = new StandardBody("", 0.SI<Kilogram>(), 0.SI<Kilogram>(), + new[] { 0.SI<SquareMeter>(), 0.SI<SquareMeter>() }, null, 0, 0.SI<CubicMeter>()); + + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".Body_Trailers_Weights.csv"; } + } + + protected override string ErrorMessage + { + get { return "StandardWeigths Lookup Error: No value found for ID '{0}'"; } + } + + public override StandardBody Lookup(string id) + { + return string.IsNullOrWhiteSpace(id) ? Empty : base.Lookup(id); + } + + protected override void ParseData(DataTable table) + { + Data = table.Rows.Cast<DataRow>().Select(k => { + var deltaCdxAStr = k.Field<string>("deltacdxafortraileroperationinlonghaul"); + var deltaCdxA = new[] { 0.SI<SquareMeter>(), 0.SI<SquareMeter>() }; + if (!deltaCdxAStr.Equals("-")) { + deltaCdxA = deltaCdxAStr.Split('/').Select(x => x.ToDouble().SI<SquareMeter>()).ToArray(); + } + return new StandardBody( + k.Field<string>("name"), + k.ParseDoubleOrGetDefault("curbmass").SI<Kilogram>(), + k.ParseDoubleOrGetDefault("maxgrossmass").SI<Kilogram>(), + deltaCdxA, + !string.IsNullOrWhiteSpace(k.Field<string>("wheels")) + ? DeclarationData.Wheels.Lookup(k.Field<string>("wheels")) + : (Wheels.Entry?)null, + int.Parse(k.Field<string>("axlecount")), + k.ParseDouble("cargovolume").SI<CubicMeter>()); + }) + .ToDictionary(kv => kv.Name); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs index 8b0ec360f361a9866664f2ac8cf29f26b5c5161a..2089c310f32077c1d6e54338a784dd03a9e089c8 100644 --- a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs +++ b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs @@ -178,7 +178,7 @@ namespace TUGraz.VectoCore.Models.Declaration } } - private class SteeringPumpValues<T> + private struct SteeringPumpValues<T> { public T UnloadedFriction; public T Banking; diff --git a/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs b/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs index 48f214845805dfe649099f9247f5a8773dcfbbf8..94e7ea1ed6641251467d3161d48b9a7c2605ab65 100644 --- a/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs +++ b/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs @@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.Models.Declaration } } - private class Entry + private struct Entry { public double Rural; public double Urban; diff --git a/VectoCore/VectoCore/Models/Declaration/Wheels.cs b/VectoCore/VectoCore/Models/Declaration/Wheels.cs index c19a08e0a288a8899ae8a80dc1d0ec2b80069ab3..9bf7e401338c9498168ed13b54796e9384125aee 100644 --- a/VectoCore/VectoCore/Models/Declaration/Wheels.cs +++ b/VectoCore/VectoCore/Models/Declaration/Wheels.cs @@ -29,61 +29,61 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Data; -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public sealed class Wheels : LookupData<string, Wheels.Entry> - { - private string[] _dimensions; - - protected override string ResourceId - { - get { return DeclarationData.DeclarationDataResourcePrefix + ".Wheels.csv"; } - } - - protected override string ErrorMessage - { - get { return "Wheels Lookup Error: No value found for Wheels. Key: '{0}'"; } - } - - public override Entry Lookup(string key) - { - return base.Lookup(key.RemoveWhitespace()); - } - - protected override void ParseData(DataTable table) - { - Data = table.Rows.Cast<DataRow>() - .Select(row => new Entry { - WheelType = row.Field<string>(0).RemoveWhitespace(), - Inertia = row.ParseDouble("inertia").SI<KilogramSquareMeter>(), - WheelsDiameter = row.ParseDouble("d").SI().Milli.Meter.Cast<Meter>(), - CircumferenceFactor = row.ParseDouble("f") - }).ToDictionary(e => e.WheelType); - _dimensions = table.Rows.Cast<DataRow>().Select(row => row.Field<string>(0)).ToArray(); - } - - public class Entry - { - public string WheelType; - public KilogramSquareMeter Inertia; - public Meter WheelsDiameter; - public double CircumferenceFactor; - - public Meter DynamicTyreRadius - { - get { return WheelsDiameter * CircumferenceFactor / (2 * Math.PI); } - } - } - - public string[] GetWheelsDimensions() - { - return _dimensions; - } - } +using System; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public sealed class Wheels : LookupData<string, Wheels.Entry> + { + private string[] _dimensions; + + protected override string ResourceId + { + get { return DeclarationData.DeclarationDataResourcePrefix + ".Wheels.csv"; } + } + + protected override string ErrorMessage + { + get { return "Wheels Lookup Error: No value found for Wheels. Key: '{0}'"; } + } + + public override Entry Lookup(string key) + { + return base.Lookup(key.RemoveWhitespace()); + } + + protected override void ParseData(DataTable table) + { + Data = table.Rows.Cast<DataRow>() + .Select(row => new Entry { + WheelType = row.Field<string>(0).RemoveWhitespace(), + Inertia = row.ParseDouble("inertia").SI<KilogramSquareMeter>(), + WheelsDiameter = row.ParseDouble("d").SI().Milli.Meter.Cast<Meter>(), + CircumferenceFactor = row.ParseDouble("f") + }).ToDictionary(e => e.WheelType); + _dimensions = table.Rows.Cast<DataRow>().Select(row => row.Field<string>(0)).ToArray(); + } + + public struct Entry + { + public string WheelType; + public KilogramSquareMeter Inertia; + public Meter WheelsDiameter; + public double CircumferenceFactor; + + public Meter DynamicTyreRadius + { + get { return WheelsDiameter * CircumferenceFactor / (2 * Math.PI); } + } + } + + public string[] GetWheelsDimensions() + { + return _dimensions; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index 37846d8653cff369a62ea4b6d0636c9ad7c2128c..83f67a12679fe968c8b94cb4cd8e7e0f9f8ef023 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -29,176 +29,200 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Xml.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData; - -namespace TUGraz.VectoCore.Models.Simulation.Data -{ - [CustomValidation(typeof(VectoRunData), "ValidateRunData")] - public class VectoRunData : SimulationComponentData - { - [ValidateObject] - public VehicleData VehicleData { get; internal set; } - - [ValidateObject] - public AirdragData AirdragData { get; internal set; } - - [ValidateObject] - public CombustionEngineData EngineData { get; internal set; } - - [ValidateObject] - public GearboxData GearboxData { get; internal set; } - - [ValidateObject] - public AxleGearData AxleGearData { get; internal set; } - - [ValidateObject] - public AngledriveData AngledriveData { get; internal set; } - - [Required, ValidateObject] - public IDrivingCycleData Cycle { get; internal set; } - - [ValidateObject] - public IEnumerable<AuxData> Aux { get; internal set; } - - public AdvancedAuxData AdvancedAux { get; internal set; } - - [ValidateObject] - public RetarderData Retarder { get; internal set; } - - [ValidateObject] - public PTOData PTO { get; internal set; } - - [ValidateObject] - public DriverData DriverData { get; internal set; } - - public ExecutionMode ExecutionMode { get; internal set; } - - [Required, MinLength(1)] - public string JobName { get; internal set; } - - public string ModFileSuffix { get; internal set; } - - [ValidateObject] - public IDeclarationReport Report { get; internal set; } - - [Required, ValidateObject] - public LoadingType Loading { get; internal set; } - - [ValidateObject] - public Mission Mission { get; internal set; } - - public XElement InputDataHash { get; internal set; } - - public class AuxData - { - // ReSharper disable once InconsistentNaming - public string ID; - - public IList<string> Technology; - - [SIRange(0, 100 * Constants.Kilo)] public Watt PowerDemand; - - [Required] public AuxiliaryDemandType DemandType; - - [ValidateObject] public AuxiliaryData Data; - } - - public static ValidationResult ValidateRunData(VectoRunData runData, ValidationContext validationContext) - { - var gearboxData = runData.GearboxData; - var engineData = runData.EngineData; - - var maxSpeed = 95.KMPHtoMeterPerSecond(); - - if (gearboxData != null) { - var axleGearData = runData.AxleGearData; - var angledriveData = runData.AngledriveData; - var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null; - var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive - ? angledriveData.Angledrive.Ratio - : 1.0; - var axlegearRatio = axleGearData != null ? axleGearData.AxleGear.Ratio : 1.0; - var dynamicTyreRadius = runData.VehicleData != null ? runData.VehicleData.DynamicTyreRadius : 0.0.SI<Meter>(); - - if (gearboxData.Gears.Count + 1 != engineData.FullLoadCurves.Count) { - return - new ValidationResult( - string.Format("number of full-load curves in engine does not match gear count. engine fld: {0}, gears: {1}", - engineData.FullLoadCurves.Count, gearboxData.Gears.Count)); - } - - foreach (var gear in gearboxData.Gears) { - for (var angularVelocity = engineData.IdleSpeed; - angularVelocity < engineData.FullLoadCurves[gear.Key].RatedSpeed; - angularVelocity += 2.0 / 3.0 * (engineData.FullLoadCurves[gear.Key].RatedSpeed - engineData.IdleSpeed) / 10.0) { - if (!gear.Value.HasLockedGear) { - continue; - } - - var velocity = angularVelocity / gear.Value.Ratio / angledriveRatio / axlegearRatio * dynamicTyreRadius; - - if (velocity > maxSpeed) { - continue; - } - - for (var inTorque = engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 3; - inTorque < engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity); - inTorque += 2.0 / 3.0 * engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 10.0) { - NewtonMeter angledriveTorque; - try { - angledriveTorque = gear.Value.LossMap.GetOutTorque(angularVelocity, inTorque); - } catch (VectoException) { - return new ValidationResult( - string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key, - inTorque, angularVelocity.ConvertTo().Rounds.Per.Minute)); - } - var axlegearTorque = angledriveTorque; - try { - if (hasAngleDrive) { - axlegearTorque = angledriveData.Angledrive.LossMap.GetOutTorque(angularVelocity / gear.Value.Ratio, - angledriveTorque); - } - } catch (VectoException) { - return new ValidationResult( - string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}", - angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertTo().Rounds.Per.Minute)); - } - - if (axleGearData != null) { - var axleAngularVelocity = angularVelocity / gear.Value.Ratio / angledriveRatio; - try { - axleGearData.AxleGear.LossMap.GetOutTorque(axleAngularVelocity, axlegearTorque); - } catch (VectoException) { - return - new ValidationResult( - string.Format( - "Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})", - axlegearTorque, axleAngularVelocity.ConvertTo().Rounds.Per.Minute, gear.Key, velocity)); - } - } - } - } - } - } - - if (runData.Cycle != null && runData.Cycle.Entries.Any(e => e.PTOActive)) { - if (runData.PTO == null || runData.PTO.PTOCycle == null) { - return new ValidationResult("PTOCycle is used in DrivingCycle, but is not defined in Vehicle-Data."); - } - } - - return ValidationResult.Success; - } - } +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; +using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData; + +namespace TUGraz.VectoCore.Models.Simulation.Data +{ + [CustomValidation(typeof(VectoRunData), "ValidateRunData")] + public class VectoRunData : SimulationComponentData + { + [ValidateObject] + public VehicleData VehicleData { get; internal set; } + + [ValidateObject] + public AirdragData AirdragData { get; internal set; } + + [ValidateObject] + public CombustionEngineData EngineData { get; internal set; } + + [ValidateObject] + public GearboxData GearboxData { get; internal set; } + + [ValidateObject] + public AxleGearData AxleGearData { get; internal set; } + + [ValidateObject] + public AngledriveData AngledriveData { get; internal set; } + + [Required, ValidateObject] + public IDrivingCycleData Cycle { get; internal set; } + + [ValidateObject] + public IEnumerable<AuxData> Aux { get; internal set; } + + public AdvancedAuxData AdvancedAux { get; internal set; } + + [ValidateObject] + public RetarderData Retarder { get; internal set; } + + [ValidateObject] + public PTOData PTO { get; internal set; } + + [ValidateObject] + public DriverData DriverData { get; internal set; } + + public ExecutionMode ExecutionMode { get; internal set; } + + [Required, MinLength(1)] + public string JobName { get; internal set; } + + public string ModFileSuffix { get; internal set; } + + [ValidateObject] + public IDeclarationReport Report { get; internal set; } + + [Required, ValidateObject] + public LoadingType Loading { get; internal set; } + + [ValidateObject] + public Mission Mission { get; internal set; } + + public XElement InputDataHash { get; internal set; } + + public class AuxData + { + // ReSharper disable once InconsistentNaming + public string ID; + + public IList<string> Technology; + + [SIRange(0, 100 * Constants.Kilo)] public Watt PowerDemand; + + [Required] public AuxiliaryDemandType DemandType; + + [ValidateObject] public AuxiliaryData Data; + } + + public static ValidationResult ValidateRunData(VectoRunData runData, ValidationContext validationContext) + { + var gearboxData = runData.GearboxData; + var engineData = runData.EngineData; + + if (gearboxData != null) { + var validationResult = CheckPowertrainLossMapsSize(runData, gearboxData, engineData); + if (validationResult != null) { + return validationResult; + } + } + + if (runData.Cycle != null && runData.Cycle.Entries.Any(e => e.PTOActive)) { + if (runData.PTO == null || runData.PTO.PTOCycle == null) { + return new ValidationResult("PTOCycle is used in DrivingCycle, but is not defined in Vehicle-Data."); + } + } + + return ValidationResult.Success; + } + + private static ValidationResult CheckPowertrainLossMapsSize(VectoRunData runData, GearboxData gearboxData, + CombustionEngineData engineData) + { + var maxSpeed = 95.KMPHtoMeterPerSecond(); + var axleGearData = runData.AxleGearData; + var angledriveData = runData.AngledriveData; + var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null; + var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive + ? angledriveData.Angledrive.Ratio + : 1.0; + var axlegearRatio = axleGearData != null ? axleGearData.AxleGear.Ratio : 1.0; + var dynamicTyreRadius = runData.VehicleData != null ? runData.VehicleData.DynamicTyreRadius : 0.0.SI<Meter>(); + + if (gearboxData.Gears.Count + 1 != engineData.FullLoadCurves.Count) { + return + new ValidationResult( + string.Format("number of full-load curves in engine does not match gear count. engine fld: {0}, gears: {1}", + engineData.FullLoadCurves.Count, gearboxData.Gears.Count)); + } + + foreach (var gear in gearboxData.Gears) { + for (var angularVelocity = engineData.IdleSpeed; + angularVelocity < engineData.FullLoadCurves[gear.Key].RatedSpeed; + angularVelocity += 2.0 / 3.0 * (engineData.FullLoadCurves[gear.Key].RatedSpeed - engineData.IdleSpeed) / 10.0) { + if (!gear.Value.HasLockedGear) { + continue; + } + + var velocity = angularVelocity / gear.Value.Ratio / angledriveRatio / axlegearRatio * dynamicTyreRadius; + + if (velocity > maxSpeed) { + continue; + } + + for (var inTorque = engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 3; + inTorque < engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity); + inTorque += 2.0 / 3.0 * engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 10.0) { + var validateRunData = CheckLossMapsEntries(gear, angularVelocity, inTorque, angledriveData, axleGearData, velocity); + if (validateRunData != null) { + return validateRunData; + } + } + } + } + return null; + } + + private static ValidationResult CheckLossMapsEntries(KeyValuePair<uint, GearData> gear, PerSecond angularVelocity, + NewtonMeter inTorque, AngledriveData angledriveData, AxleGearData axleGearData, SI velocity) + { + var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null; + var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive + ? angledriveData.Angledrive.Ratio + : 1.0; + NewtonMeter angledriveTorque; + try { + angledriveTorque = gear.Value.LossMap.GetOutTorque(angularVelocity, inTorque); + } catch (VectoException) { + return new ValidationResult( + string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key, + inTorque, angularVelocity.ConvertTo().Rounds.Per.Minute)); + } + var axlegearTorque = angledriveTorque; + try { + if (hasAngleDrive) { + axlegearTorque = angledriveData.Angledrive.LossMap.GetOutTorque(angularVelocity / gear.Value.Ratio, + angledriveTorque); + } + } catch (VectoException) { + return new ValidationResult( + string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}", + angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertTo().Rounds.Per.Minute)); + } + + if (axleGearData != null) { + var axleAngularVelocity = angularVelocity / gear.Value.Ratio / angledriveRatio; + try { + axleGearData.AxleGear.LossMap.GetOutTorque(axleAngularVelocity, axlegearTorque); + } catch (VectoException) { + return + new ValidationResult( + string.Format( + "Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})", + axlegearTorque, axleAngularVelocity.ConvertTo().Rounds.Per.Minute, gear.Key, velocity)); + } + } + return null; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs index 775c19f5ccd8861a42cccb59e153412c68f7a446..39f257b9139e565522136b35194128c4ac6aa2d0 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -29,203 +29,205 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - /// <summary> - /// Container for simulation jobs. - /// </summary> - public class JobContainer : LoggingObject - { - internal readonly List<RunEntry> Runs = new List<RunEntry>(); - private readonly SummaryDataContainer _sumWriter; - - private static int _jobNumber; - - /// <summary> - /// Initializes a new empty instance of the <see cref="JobContainer"/> class. - /// </summary> - /// <param name="sumWriter">The sum writer.</param> - public JobContainer(SummaryDataContainer sumWriter) - { - _sumWriter = sumWriter; - } - - public void AddRun(IVectoRun run) - { - Interlocked.Increment(ref _jobNumber); - Runs.Add(new RunEntry { Run = run, JobContainer = this }); - } - - public struct CycleTypeDescription - { - public string Name; - public CycleType CycleType; - } - - public IEnumerable<CycleTypeDescription> GetCycleTypes() - { - return - Runs.Select( - r => new CycleTypeDescription { Name = r.Run.CycleName, CycleType = r.Run.GetContainer().RunData.Cycle.CycleType }) - .Distinct(); - } - - /// <summary> - /// Adds the runs from the factory to the job container. - /// </summary> - /// <returns>A List of Run-Identifiers (unique), int</returns> - public List<int> AddRuns(SimulatorFactory factory) - { - var runIDs = new List<int>(); - - factory.SumData = _sumWriter; - factory.JobNumber = Interlocked.Increment(ref _jobNumber); - - foreach (var run in factory.SimulationRuns()) { - var entry = new RunEntry { Run = run, JobContainer = this }; - Runs.Add(entry); - runIDs.Add(entry.Run.RunIdentifier); - } - return runIDs; - } - - /// <summary> - /// Execute all runs, waits until finished. - /// </summary> - public void Execute(bool multithreaded = true) - { - Log.Info("VectoRun started running. Executing Runs."); - if (multithreaded) { - Runs.ForEach(r => r.RunWorkerAsync()); - } else { - var first = new Task(() => { }); - var task = first; - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var run in Runs) { - var r = run; - task = task.ContinueWith(t => r.RunWorkerAsync().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion); - } - first.Start(); - } - } - - public void Cancel() - { - foreach (var job in Runs) { - job.CancelAsync(); - } - WaitFinished(); - } - - public void CancelCurrent() - { - foreach (var job in Runs) { - job.CancelAsync(); - } - } - - public void WaitFinished() - { - try { - Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); - } catch (Exception) { - // ignored - } - } - - private void JobCompleted() - { - if (AllCompleted) { - _sumWriter.Finish(); - } - } - - public bool AllCompleted - { - get { return Runs.All(r => r.Done); } - } - - public Dictionary<int, ProgressEntry> GetProgress() - { - return Runs.ToDictionary( - r => r.Run.RunIdentifier, - r => new ProgressEntry { - RunName = r.Run.RunName, - CycleName = r.Run.CycleName, - RunSuffix = r.Run.RunSuffix, - Progress = r.Run.Progress, - Done = r.Done, - ExecTime = r.ExecTime, - Success = r.Success, - Canceled = r.Canceled, - Error = r.ExecException - }); - } - - public class ProgressEntry - { - public string RunName; - public double Progress; - public double ExecTime; - public Exception Error; - public bool Canceled; - public bool Success; - public bool Done; - public string CycleName; - public string RunSuffix; - } - - [DebuggerDisplay("{Run.RunIdentifier}: {Run.RunName}, {Run.CycleName}")] - internal class RunEntry : LoggingObject - { - public IVectoRun Run; - public JobContainer JobContainer; - public bool Done; - public bool Success; - public bool Canceled; - public double ExecTime; - public Exception ExecException; - public readonly Task RunTask; - - public RunEntry() - { - RunTask = new Task(() => { - var stopWatch = Stopwatch.StartNew(); - try { - Run.Run(); - } catch (Exception ex) { - Log.Error(ex, "Error during simulation run!"); - ExecException = ex; - } - stopWatch.Stop(); - Success = Run.FinishedWithoutErrors && ExecException == null; - Done = true; - ExecTime = stopWatch.Elapsed.TotalMilliseconds; - JobContainer.JobCompleted(); - }); - } - - public Task RunWorkerAsync() - { - RunTask.Start(); - return RunTask; - } - - public void CancelAsync() - { - Run.Cancel(); - Canceled = true; - } - } - } +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + /// <summary> + /// Container for simulation jobs. + /// </summary> + public class JobContainer : LoggingObject + { + internal readonly List<RunEntry> Runs = new List<RunEntry>(); + private readonly SummaryDataContainer _sumWriter; + + private static int _jobNumber; + + /// <summary> + /// Initializes a new empty instance of the <see cref="JobContainer"/> class. + /// </summary> + /// <param name="sumWriter">The sum writer.</param> + public JobContainer(SummaryDataContainer sumWriter) + { + _sumWriter = sumWriter; + } + + public void AddRun(IVectoRun run) + { + Interlocked.Increment(ref _jobNumber); + Runs.Add(new RunEntry { Run = run, JobContainer = this }); + } + + public struct CycleTypeDescription + { + public string Name; + public CycleType CycleType; + } + + public IEnumerable<CycleTypeDescription> GetCycleTypes() + { + return + Runs.Select( + r => new CycleTypeDescription { Name = r.Run.CycleName, CycleType = r.Run.GetContainer().RunData.Cycle.CycleType }) + .Distinct(); + } + + /// <summary> + /// Adds the runs from the factory to the job container. + /// </summary> + /// <returns>A List of Run-Identifiers (unique), int</returns> + public List<int> AddRuns(SimulatorFactory factory) + { + var runIDs = new List<int>(); + + factory.SumData = _sumWriter; + factory.JobNumber = Interlocked.Increment(ref _jobNumber); + + foreach (var run in factory.SimulationRuns()) { + var entry = new RunEntry { Run = run, JobContainer = this }; + Runs.Add(entry); + runIDs.Add(entry.Run.RunIdentifier); + } + return runIDs; + } + + /// <summary> + /// Execute all runs, waits until finished. + /// </summary> + public void Execute(bool multithreaded = true) + { + Log.Info("VectoRun started running. Executing Runs."); + if (multithreaded) { + Runs.ForEach(r => r.RunWorkerAsync()); + } else { + var first = new Task(() => { }); + var task = first; + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var run in Runs) { + var r = run; + task = task.ContinueWith(t => r.RunWorkerAsync().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion); + } + first.Start(); + } + } + + public void Cancel() + { + foreach (var job in Runs) { + job.CancelAsync(); + } + WaitFinished(); + } + + public void CancelCurrent() + { + foreach (var job in Runs) { + job.CancelAsync(); + } + } + + public void WaitFinished() + { + try { + Task.WaitAll(Runs.Select(r => r.RunTask).ToArray()); + } catch (Exception) { + // ignored + } + } + + [MethodImpl(MethodImplOptions.Synchronized)] + private void JobCompleted() + { + if (AllCompleted) { + _sumWriter.Finish(); + } + } + + public bool AllCompleted + { + get { return Runs.All(r => r.Done); } + } + + public Dictionary<int, ProgressEntry> GetProgress() + { + return Runs.ToDictionary( + r => r.Run.RunIdentifier, + r => new ProgressEntry { + RunName = r.Run.RunName, + CycleName = r.Run.CycleName, + RunSuffix = r.Run.RunSuffix, + Progress = r.Run.Progress, + Done = r.Done, + ExecTime = r.ExecTime, + Success = r.Success, + Canceled = r.Canceled, + Error = r.ExecException + }); + } + + public class ProgressEntry + { + public string RunName; + public double Progress; + public double ExecTime; + public Exception Error; + public bool Canceled; + public bool Success; + public bool Done; + public string CycleName; + public string RunSuffix; + } + + [DebuggerDisplay("{Run.RunIdentifier}: {Run.RunName}, {Run.CycleName}")] + internal class RunEntry : LoggingObject + { + public IVectoRun Run; + public JobContainer JobContainer; + public bool Done; + public bool Success; + public bool Canceled; + public double ExecTime; + public Exception ExecException; + public readonly Task RunTask; + + public RunEntry() + { + RunTask = new Task(() => { + var stopWatch = Stopwatch.StartNew(); + try { + Run.Run(); + } catch (Exception ex) { + Log.Error(ex, "Error during simulation run!"); + ExecException = ex; + } + stopWatch.Stop(); + Success = Run.FinishedWithoutErrors && ExecException == null; + Done = true; + ExecTime = stopWatch.Elapsed.TotalMilliseconds; + JobContainer.JobCompleted(); + }); + } + + public Task RunWorkerAsync() + { + RunTask.Start(); + return RunTask; + } + + public void CancelAsync() + { + Run.Cancel(); + Canceled = true; + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index d9368e83f6a6efb131d79b3a2e2217d3b32ddb95..f677315e4e085472ae482fcf597976cf8ad75c4a 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -29,271 +29,271 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - /// <summary> - /// Provides Methods to build a simulator with a powertrain step by step. - /// </summary> - public class PowertrainBuilder - { - private readonly IModalDataContainer _modData; - private readonly WriteSumData _sumWriter; - - public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) - { - if (modData == null) { - throw new VectoException("Modal Data Container can't be null"); - } - _modData = modData; - _sumWriter = sumWriter; - } - - public VehicleContainer Build(VectoRunData data) - { - switch (data.Cycle.CycleType) { - case CycleType.EngineOnly: - return BuildEngineOnly(data); - case CycleType.PWheel: - return BuildPWheel(data); - case CycleType.MeasuredSpeed: - return BuildMeasuredSpeed(data); - case CycleType.MeasuredSpeedGear: - return BuildMeasuredSpeedGear(data); - case CycleType.DistanceBased: - return BuildFullPowertrain(data); - default: - throw new VectoException("Powertrain Builder cannot build Powertrain for CycleType: {0}", data.Cycle.CycleType); - } - } - - private VehicleContainer BuildEngineOnly(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.EngineOnly) { - throw new VectoException("CycleType must be EngineOnly."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - var cycle = new PowertrainDrivingCycle(container, data.Cycle); - - var directAux = new EngineAuxiliary(container); - directAux.AddCycle(Constants.Auxiliaries.Cycle); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.Cycle); - var engine = new EngineOnlyCombustionEngine(container, data.EngineData); - engine.Connect(directAux.Port()); - - cycle.InPort().Connect(engine.OutPort()); - return container; - } - - private VehicleContainer BuildPWheel(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.PWheel) { - throw new VectoException("CycleType must be PWheel."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - var gearbox = new CycleGearbox(container, data); - - // PWheelCycle --> AxleGear --> Clutch --> Engine <-- Aux - var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio, data.VehicleData, - gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(gearbox, data.Retarder, container) - .AddComponent(new Clutch(container, data.EngineData)); - var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true); - var idleController = GetIdleController(data.PTO, engine, container); - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - - return container; - } - - private VehicleContainer BuildMeasuredSpeed(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.MeasuredSpeed) { - throw new VectoException("CycleType must be MeasuredSpeed."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - - // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes - // --> axleGear --> (retarder) --> GearBox --> (retarder) --> Clutch --> engine <-- Aux - var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle); - var powertrain = cycle - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(GetGearbox(container, data), data.Retarder, container); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - - var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private VehicleContainer BuildMeasuredSpeedGear(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.MeasuredSpeedGear) { - throw new VectoException("CycleType must be MeasuredSpeed with Gear."); - } - - var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; - - // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes - // --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux - var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle) - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(new CycleGearbox(container, data)); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - powertrain.AddComponent(new CombustionEngine(container, data.EngineData)) - .AddAuxiliaries(container, data); - - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private VehicleContainer BuildFullPowertrain(VectoRunData data) - { - if (data.Cycle.CycleType != CycleType.DistanceBased) { - throw new VectoException("CycleType must be DistanceBased"); - } - - var container = new VehicleContainer(data.ExecutionMode, _modData, _sumWriter) { RunData = data }; - - // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels - // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux - var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); - var powertrain = cycle.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) - .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, data.AxleGearData)) - .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) - .AddComponent(GetGearbox(container, data), data.Retarder, container); - if (data.GearboxData.Type.ManualTransmission()) { - powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); - } - - var engine = new CombustionEngine(container, data.EngineData); - var idleController = GetIdleController(data.PTO, engine, container); - cycle.IdleController = idleController as IdleControllerSwitcher; - - powertrain.AddComponent(engine, idleController) - .AddAuxiliaries(container, data); - - _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); - - return container; - } - - private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, IVehicleContainer container) - { - var controller = engine.IdleController; - - if (pto != null && pto.PTOCycle != null) { - var ptoController = new PTOCycleController(container, pto.PTOCycle); - controller = new IdleControllerSwitcher(engine.IdleController, ptoController); - } - - return controller; - } - - internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) - { - var conventionalAux = CreateAuxiliaries(data, container); - var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name, - data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); - return busAux; - } - - internal static EngineAuxiliary CreateAuxiliaries(VectoRunData data, IVehicleContainer container) - { - var aux = new EngineAuxiliary(container); - foreach (var auxData in data.Aux) { - // id's in upper case - var id = auxData.ID.ToUpper(); - - switch (auxData.DemandType) { - case AuxiliaryDemandType.Constant: - aux.AddConstant(id, auxData.PowerDemand); - break; - case AuxiliaryDemandType.Direct: - aux.AddCycle(id); - break; - case AuxiliaryDemandType.Mapping: - aux.AddMapping(id, auxData.Data); - break; - default: - throw new ArgumentOutOfRangeException("AuxiliaryDemandType", auxData.DemandType.ToString()); - } - container.ModalData.AddAuxiliary(id); - } - - if (data.PTO != null) { - aux.AddConstant(Constants.Auxiliaries.IDs.PTOTransmission, - DeclarationData.PTOTransmission.Lookup(data.PTO.TransmissionType)); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOTransmission, - Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOTransmission); - - aux.Add(Constants.Auxiliaries.IDs.PTOConsumer, - n => container.PTOActive ? null : data.PTO.LossMap.GetTorqueLoss(n) * n); - container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOConsumer, - Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOConsumer); - } - - return aux; - } - - private static IGearbox GetGearbox(IVehicleContainer container, VectoRunData runData) - { - IShiftStrategy strategy; - switch (runData.GearboxData.Type) { - case GearboxType.AMT: - strategy = new AMTShiftStrategy(runData, container); - break; - case GearboxType.MT: - strategy = new MTShiftStrategy(runData, container); - break; - case GearboxType.ATPowerSplit: - case GearboxType.ATSerial: - strategy = new ATShiftStrategy(runData.GearboxData, container); - return new ATGearbox(container, strategy, runData); - default: - throw new ArgumentOutOfRangeException("Unknown Gearbox Type", runData.GearboxData.Type.ToString()); - } - return new Gearbox(container, strategy, runData); - } - } +using System; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + /// <summary> + /// Provides Methods to build a simulator with a powertrain step by step. + /// </summary> + public class PowertrainBuilder + { + private readonly IModalDataContainer _modData; + private readonly WriteSumData _sumWriter; + + public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) + { + if (modData == null) { + throw new VectoException("Modal Data Container can't be null"); + } + _modData = modData; + _sumWriter = sumWriter; + } + + public VehicleContainer Build(VectoRunData data) + { + switch (data.Cycle.CycleType) { + case CycleType.EngineOnly: + return BuildEngineOnly(data); + case CycleType.PWheel: + return BuildPWheel(data); + case CycleType.MeasuredSpeed: + return BuildMeasuredSpeed(data); + case CycleType.MeasuredSpeedGear: + return BuildMeasuredSpeedGear(data); + case CycleType.DistanceBased: + return BuildFullPowertrain(data); + default: + throw new VectoException("Powertrain Builder cannot build Powertrain for CycleType: {0}", data.Cycle.CycleType); + } + } + + private VehicleContainer BuildEngineOnly(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.EngineOnly) { + throw new VectoException("CycleType must be EngineOnly."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + var cycle = new PowertrainDrivingCycle(container, data.Cycle); + + var directAux = new EngineAuxiliary(container); + directAux.AddCycle(Constants.Auxiliaries.Cycle); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.Cycle); + var engine = new EngineOnlyCombustionEngine(container, data.EngineData); + engine.Connect(directAux.Port()); + + cycle.InPort().Connect(engine.OutPort()); + return container; + } + + private VehicleContainer BuildPWheel(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.PWheel) { + throw new VectoException("CycleType must be PWheel."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + var gearbox = new CycleGearbox(container, data); + + // PWheelCycle --> AxleGear --> Clutch --> Engine <-- Aux + var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio, data.VehicleData, + gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(gearbox, data.Retarder, container) + .AddComponent(new Clutch(container, data.EngineData)); + var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true); + var idleController = GetIdleController(data.PTO, engine, container); + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + + return container; + } + + private VehicleContainer BuildMeasuredSpeed(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.MeasuredSpeed) { + throw new VectoException("CycleType must be MeasuredSpeed."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + + // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes + // --> axleGear --> (retarder) --> GearBox --> (retarder) --> Clutch --> engine <-- Aux + var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle); + var powertrain = cycle + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(GetGearbox(container, data), data.Retarder, container); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + + var engine = new CombustionEngine(container, data.EngineData); + var idleController = GetIdleController(data.PTO, engine, container); + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private VehicleContainer BuildMeasuredSpeedGear(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.MeasuredSpeedGear) { + throw new VectoException("CycleType must be MeasuredSpeed with Gear."); + } + + var container = new VehicleContainer(ExecutionMode.Engineering, _modData, _sumWriter) { RunData = data }; + + // MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes + // --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux + var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle) + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(new CycleGearbox(container, data)); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + powertrain.AddComponent(new CombustionEngine(container, data.EngineData)) + .AddAuxiliaries(container, data); + + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private VehicleContainer BuildFullPowertrain(VectoRunData data) + { + if (data.Cycle.CycleType != CycleType.DistanceBased) { + throw new VectoException("CycleType must be DistanceBased"); + } + + var container = new VehicleContainer(data.ExecutionMode, _modData, _sumWriter) { RunData = data }; + + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels + // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux + var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); + var powertrain = cycle.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, data.VehicleData, data.AirdragData)) + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(GetGearbox(container, data), data.Retarder, container); + if (data.GearboxData.Type.ManualTransmission()) { + powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData)); + } + + var engine = new CombustionEngine(container, data.EngineData); + var idleController = GetIdleController(data.PTO, engine, container); + cycle.IdleController = idleController as IdleControllerSwitcher; + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + + _modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission(); + + return container; + } + + private static IIdleController GetIdleController(PTOData pto, ICombustionEngine engine, IVehicleContainer container) + { + var controller = engine.IdleController; + + if (pto != null && pto.PTOCycle != null) { + var ptoController = new PTOCycleController(container, pto.PTOCycle); + controller = new IdleControllerSwitcher(engine.IdleController, ptoController); + } + + return controller; + } + + internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) + { + var conventionalAux = CreateAuxiliaries(data, container); + var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name, + data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); + return busAux; + } + + internal static EngineAuxiliary CreateAuxiliaries(VectoRunData data, IVehicleContainer container) + { + var aux = new EngineAuxiliary(container); + foreach (var auxData in data.Aux) { + // id's in upper case + var id = auxData.ID.ToUpper(); + + switch (auxData.DemandType) { + case AuxiliaryDemandType.Constant: + aux.AddConstant(id, auxData.PowerDemand); + break; + case AuxiliaryDemandType.Direct: + aux.AddCycle(id); + break; + case AuxiliaryDemandType.Mapping: + aux.AddMapping(id, auxData.Data); + break; + default: + throw new ArgumentOutOfRangeException("AuxiliaryDemandType", auxData.DemandType.ToString()); + } + container.ModalData.AddAuxiliary(id); + } + + if (data.PTO != null) { + aux.AddConstant(Constants.Auxiliaries.IDs.PTOTransmission, + DeclarationData.PTOTransmission.Lookup(data.PTO.TransmissionType).PowerDemand); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOTransmission, + Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOTransmission); + + aux.Add(Constants.Auxiliaries.IDs.PTOConsumer, + n => container.PTOActive ? null : data.PTO.LossMap.GetTorqueLoss(n) * n); + container.ModalData.AddAuxiliary(Constants.Auxiliaries.IDs.PTOConsumer, + Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOConsumer); + } + + return aux; + } + + private static IGearbox GetGearbox(IVehicleContainer container, VectoRunData runData) + { + IShiftStrategy strategy; + switch (runData.GearboxData.Type) { + case GearboxType.AMT: + strategy = new AMTShiftStrategy(runData, container); + break; + case GearboxType.MT: + strategy = new MTShiftStrategy(runData, container); + break; + case GearboxType.ATPowerSplit: + case GearboxType.ATSerial: + strategy = new ATShiftStrategy(runData.GearboxData, container); + return new ATGearbox(container, strategy, runData); + default: + throw new ArgumentOutOfRangeException("Unknown Gearbox Type", runData.GearboxData.Type.ToString()); + } + return new Gearbox(container, strategy, runData); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 8d72fe26083182bd5cedd333b70d9ff088840611..2c395c3bdecff8629c84e037a59256f356582539 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -29,166 +29,203 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData; -using TUGraz.VectoCore.InputData.Reader.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.ModFilter; -using TUGraz.VectoCore.OutputData.XML; - -namespace TUGraz.VectoCore.Models.Simulation.Impl -{ - public class SimulatorFactory : LoggingObject - { - private static int _jobNumberCounter; - - private readonly ExecutionMode _mode; - private readonly bool _engineOnlyMode; - - public SimulatorFactory(ExecutionMode mode, IInputDataProvider dataProvider, IOutputDataWriter writer, - IDeclarationReport declarationReport = null, bool validate = true) - { - Log.Info("########## VectoCore Version {0} ##########", Assembly.GetExecutingAssembly().GetName().Version); - JobNumber = Interlocked.Increment(ref _jobNumberCounter); - _mode = mode; - ModWriter = writer; - Validate = validate; - - int workerThreads; - int completionThreads; - ThreadPool.GetMinThreads(out workerThreads, out completionThreads); - if (workerThreads < 12) { - workerThreads = 12; - } - ThreadPool.SetMinThreads(workerThreads, completionThreads); - - switch (mode) { - case ExecutionMode.Declaration: - var declDataProvider = dataProvider as IDeclarationInputDataProvider; - if (declDataProvider == null) { - throw new VectoException("InputDataProvider does not implement DeclarationData interface"); - } - var report = declarationReport ?? new XMLDeclarationReport(writer); - DataReader = new DeclarationModeVectoRunDataFactory(declDataProvider, report); - break; - case ExecutionMode.Engineering: - var engDataProvider = dataProvider as IEngineeringInputDataProvider; - if (engDataProvider == null) { - throw new VectoException("InputDataProvider does not implement Engineering interface"); - } - if (engDataProvider.JobInputData().EngineOnlyMode) { - DataReader = new EngineOnlyVectoRunDataFactory(engDataProvider); - _engineOnlyMode = true; - } else { - DataReader = new EngineeringModeVectoRunDataFactory(engDataProvider); - } - break; - default: - throw new VectoException("Unkown factory mode in SimulatorFactory: {0}", mode); - } - } - - public bool Validate { get; set; } - - public IVectoRunDataFactory DataReader { get; private set; } - - public SummaryDataContainer SumData { get; set; } - - public IOutputDataWriter ModWriter { get; private set; } - - public int JobNumber { get; set; } - - public bool WriteModalResults { get; set; } - public bool ModalResults1Hz { get; set; } - public bool ActualModalData { get; set; } - - /// <summary> - /// Creates powertrain and initializes it with the component's data. - /// </summary> - /// <returns>new VectoRun Instance</returns> - public IEnumerable<IVectoRun> SimulationRuns() - { - var i = 0; - var modDataFilter = ModalResults1Hz - ? new IModalDataFilter[] { new ModalData1HzFilter() } - : null; - - if (ActualModalData) { - modDataFilter = new IModalDataFilter[] { new ActualModalDataFilter(), }; - } - - - var warning1Hz = false; - - foreach (var data in DataReader.NextRun()) { - var d = data; - if (d.Report != null) { - d.Report.PrepareResult(d.Loading, d.Mission, d); - } - Action<ModalDataContainer> addReportResult = writer => { - if (d.Report != null) { - d.Report.AddResult(d.Loading, d.Mission, d, writer); - } - }; - if (!data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz && !warning1Hz) { - Log.Error("Output filter for 1Hz results is only available for distance-based cycles!"); - warning1Hz = true; - } - IModalDataContainer modContainer = - new ModalDataContainer(data, ModWriter, - addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null, - writeEngineOnly: _engineOnlyMode, - filter: data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz || ActualModalData ? modDataFilter : null) { - WriteAdvancedAux = data.AdvancedAux != null && data.AdvancedAux.AuxiliaryAssembly == AuxiliaryModel.Advanced, - WriteModalResults = _mode != ExecutionMode.Declaration || WriteModalResults - }; - var current = i++; - var builder = new PowertrainBuilder(modContainer, modData => { - if (SumData != null) { - SumData.Write(modData, JobNumber, current, d); - //SumData.Write(modContainer, d.JobName, string.Format("{0}-{1}", JobNumber, current), - // d.Cycle.Name + Constants.FileExtensions.CycleFile, mass, loading, volume ?? 0.SI<CubicMeter>(), gearCount); - } - }); - - VectoRun run; - - switch (data.Cycle.CycleType) { - case CycleType.DistanceBased: - run = new DistanceRun(builder.Build(data)); - break; - case CycleType.EngineOnly: - case CycleType.PWheel: - case CycleType.MeasuredSpeed: - case CycleType.MeasuredSpeedGear: - run = new TimeRun(builder.Build(data)); - break; - case CycleType.PTO: - throw new VectoException("PTO Cycle can not be used as main cycle!"); - default: - throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType); - } - - if (Validate) { - var validationErrors = run.Validate(_mode, data.GearboxData == null ? (GearboxType?)null : data.GearboxData.Type, - data.Mission != null && data.Mission.MissionType.IsEMS()); - if (validationErrors.Any()) { - throw new VectoException("Validation of Run-Data Failed: " + - string.Join("\n", validationErrors.Select(r => r.ErrorMessage + string.Join("; ", r.MemberNames)))); - } - } - yield return run; - } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData; +using TUGraz.VectoCore.InputData.Reader.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.ModFilter; +using TUGraz.VectoCore.OutputData.XML; + +namespace TUGraz.VectoCore.Models.Simulation.Impl +{ + public class SimulatorFactory : LoggingObject + { + private static int _jobNumberCounter; + + private readonly ExecutionMode _mode; + private bool _engineOnlyMode; + + public SimulatorFactory(ExecutionMode mode, IInputDataProvider dataProvider, IOutputDataWriter writer, + IDeclarationReport declarationReport = null, bool validate = true) + { + Log.Info("########## VectoCore Version {0} ##########", Assembly.GetExecutingAssembly().GetName().Version); + JobNumber = Interlocked.Increment(ref _jobNumberCounter); + _mode = mode; + ModWriter = writer; + Validate = validate; + + int workerThreads; + int completionThreads; + ThreadPool.GetMinThreads(out workerThreads, out completionThreads); + if (workerThreads < 12) { + workerThreads = 12; + } + ThreadPool.SetMinThreads(workerThreads, completionThreads); + + switch (mode) { + case ExecutionMode.Declaration: + var declDataProvider = ToDeclarationInputDataProvider(dataProvider); + var report = declarationReport ?? new XMLDeclarationReport(writer); + DataReader = new DeclarationModeVectoRunDataFactory(declDataProvider, report); + break; + case ExecutionMode.Engineering: + CreateEngineeringDataReader(dataProvider); + break; + default: + throw new VectoException("Unkown factory mode in SimulatorFactory: {0}", mode); + } + } + + private void CreateEngineeringDataReader(IInputDataProvider dataProvider) + { + var engDataProvider = ToEngineeringInputDataProvider(dataProvider); + if (engDataProvider.JobInputData().EngineOnlyMode) { + DataReader = new EngineOnlyVectoRunDataFactory(engDataProvider); + _engineOnlyMode = true; + } else { + DataReader = new EngineeringModeVectoRunDataFactory(engDataProvider); + } + } + + private static IDeclarationInputDataProvider ToDeclarationInputDataProvider(IInputDataProvider dataProvider) + { + var declDataProvider = dataProvider as IDeclarationInputDataProvider; + if (declDataProvider == null) { + throw new VectoException("InputDataProvider does not implement DeclarationData interface"); + } + return declDataProvider; + } + + private static IEngineeringInputDataProvider ToEngineeringInputDataProvider(IInputDataProvider dataProvider) + { + var engDataProvider = dataProvider as IEngineeringInputDataProvider; + if (engDataProvider == null) { + throw new VectoException("InputDataProvider does not implement Engineering interface"); + } + return engDataProvider; + } + + public bool Validate { get; set; } + + public IVectoRunDataFactory DataReader { get; private set; } + + public SummaryDataContainer SumData { get; set; } + + public IOutputDataWriter ModWriter { get; private set; } + + public int JobNumber { get; set; } + + public bool WriteModalResults { get; set; } + public bool ModalResults1Hz { get; set; } + public bool ActualModalData { get; set; } + + /// <summary> + /// Creates powertrain and initializes it with the component's data. + /// </summary> + /// <returns>new VectoRun Instance</returns> + public IEnumerable<IVectoRun> SimulationRuns() + { + var i = 0; + + + var warning1Hz = false; + + foreach (var data in DataReader.NextRun()) { + var d = data; + var addReportResult = PrepareReport(data); + if (!data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz && !warning1Hz) { + Log.Error("Output filter for 1Hz results is only available for distance-based cycles!"); + warning1Hz = true; + } + IModalDataContainer modContainer = + new ModalDataContainer(data, ModWriter, + addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null, + writeEngineOnly: _engineOnlyMode, + filter: GetModDataFilter(data)) { + WriteAdvancedAux = data.AdvancedAux != null && data.AdvancedAux.AuxiliaryAssembly == AuxiliaryModel.Advanced, + WriteModalResults = _mode != ExecutionMode.Declaration || WriteModalResults + }; + var current = i++; + var builder = new PowertrainBuilder(modContainer, modData => { + if (SumData != null) { + SumData.Write(modData, JobNumber, current, d); + } + }); + + var run = GetVectoRun(data, builder); + + if (Validate) { + ValidateVectoRunData(run, data.GearboxData == null ? (GearboxType?)null : data.GearboxData.Type, + data.Mission != null && data.Mission.MissionType.IsEMS()); + } + yield return run; + } + } + + private IModalDataFilter[] GetModDataFilter(VectoRunData data) + { + var modDataFilter = ModalResults1Hz + ? new IModalDataFilter[] { new ModalData1HzFilter() } + : null; + + if (ActualModalData) { + modDataFilter = new IModalDataFilter[] { new ActualModalDataFilter(), }; + } + return data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz || ActualModalData ? modDataFilter : null; + } + + private void ValidateVectoRunData(VectoRun run, GearboxType? gearboxtype, bool isEms) + { + var validationErrors = run.Validate(_mode, gearboxtype, isEms); + if (validationErrors.Any()) { + throw new VectoException("Validation of Run-Data Failed: " + + string.Join("\n", validationErrors.Select(r => r.ErrorMessage + string.Join("; ", r.MemberNames)))); + } + } + + private static VectoRun GetVectoRun(VectoRunData data, PowertrainBuilder builder) + { + VectoRun run; + switch (data.Cycle.CycleType) { + case CycleType.DistanceBased: + run = new DistanceRun(builder.Build(data)); + break; + case CycleType.EngineOnly: + case CycleType.PWheel: + case CycleType.MeasuredSpeed: + case CycleType.MeasuredSpeedGear: + run = new TimeRun(builder.Build(data)); + break; + case CycleType.PTO: + throw new VectoException("PTO Cycle can not be used as main cycle!"); + default: + throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType); + } + return run; + } + + private static Action<ModalDataContainer> PrepareReport(VectoRunData data) + { + if (data.Report != null) { + data.Report.PrepareResult(data.Loading, data.Mission, data); + } + Action<ModalDataContainer> addReportResult = writer => { + if (data.Report != null) { + data.Report.AddResult(data.Loading, data.Mission, data, writer); + } + }; + return addReportResult; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs index 49bcd6c601efeb2f4f8142e03cfe32712afa8bee..2422a84ff6faa1154fef0106916db14c0267ee7c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/VehicleData.cs @@ -29,262 +29,268 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Data -{ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Data +{ [CustomValidation(typeof(AirdragData), "ValidateAirDragData")] - public class AirdragData : SimulationComponentData - { - public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; } - - [Required, ValidateObject] - public ICrossWindCorrection CrossWindCorrectionCurve { get; internal set; } - - public SquareMeter DeclaredAirdragArea { get; internal set; } + public class AirdragData : SimulationComponentData + { + public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; } + + [Required, ValidateObject] + public ICrossWindCorrection CrossWindCorrectionCurve { get; internal set; } + + public SquareMeter DeclaredAirdragArea { get; internal set; } // ReSharper disable once UnusedMember.Global -- used via Validation public static ValidationResult ValidateAirDragData(AirdragData airDragData, ValidationContext validationContext) { if (airDragData.CrossWindCorrectionMode != CrossWindCorrectionMode.DeclarationModeCorrection && - airDragData.CrossWindCorrectionCurve.AirDragArea == null) + airDragData.CrossWindCorrectionCurve.AirDragArea == null) { return new ValidationResult( "AirDrag Area (CdxA) must not be empty when the cross wind correction mode is not \"Speed dependent (Declaration Mode)\""); + } + + return ValidationResult.Success; + } + } + + /// <summary> + /// Data Class for the Vehicle + /// </summary> + [CustomValidation(typeof(VehicleData), "ValidateVehicleData")] + public class VehicleData : SimulationComponentData + { + public string VIN { get; internal set; } + + public LegislativeClass LegislativeClass { get; internal set; } + + public VehicleCategory VehicleCategory { get; internal set; } + + public VehicleClass VehicleClass { get; internal set; } + + public AxleConfiguration AxleConfiguration { get; internal set; } + + public string ManufacturerAddress { get; internal set; } + + + [Required, ValidateObject] private List<Axle> _axleData; + + private KilogramSquareMeter _wheelsInertia; + private double? _totalRollResistanceCoefficient; + private double? _rollResistanceCoefficientWithoutTrailer; + + public List<Axle> AxleData + { + get { return _axleData; } + internal set { + _axleData = value; + _wheelsInertia = null; + _totalRollResistanceCoefficient = null; + } + } + + /// <summary> + /// The Curb Weight of the vehicle + /// (+ Curb Weight of Standard-Body if it has one) + /// (+ Curb Weight of Trailer if it has one) + /// </summary> + [Required, SIRange(500, 40000, emsMission: false), + SIRange(0, 60000, emsMission: true)] + public Kilogram CurbWeight { get; internal set; } + + /// <summary> + /// Curb Weight of Standard-Body (if it has one) + /// + Curb Weight of Trailer (if it has one) + /// </summary> + public Kilogram BodyAndTrailerWeight { get; internal set; } + + [Required, SIRange(0, 40000, emsMission: false), + SIRange(0, 60000, emsMission: true)] + public Kilogram Loading { get; internal set; } + + [SIRange(0, 500)] + public CubicMeter CargoVolume { get; internal set; } + + /// <summary> + /// The Gross Vehicle Weight of the Vehicle. + /// </summary> + [Required, + SIRange(3500, 40000, ExecutionMode.Declaration, emsMission: false), + SIRange(0, 60000, ExecutionMode.Declaration, emsMission: true), + SIRange(0, 1000000, ExecutionMode.Engineering)] + public Kilogram GrossVehicleWeight { get; internal set; } + + /// <summary> + /// The Gross Vehicle Weight of the Trailer (if the vehicle has one). + /// </summary> + [Required, SIRange(0, 40000, emsMission: false), + SIRange(0, 60000, emsMission: true)] + public Kilogram TrailerGrossVehicleWeight { get; internal set; } + + [Required, SIRange(0.1, 0.7)] + public Meter DynamicTyreRadius { get; internal set; } + + public KilogramSquareMeter WheelsInertia + { + get { + if (_wheelsInertia == null) { + ComputeRollResistanceAndReducedMassWheels(); + } + return _wheelsInertia; + } + internal set { _wheelsInertia = value; } + } + + //[Required, SIRange(0, 1E12)] + public double TotalRollResistanceCoefficient + { + get { + if (_totalRollResistanceCoefficient == null) { + ComputeRollResistanceAndReducedMassWheels(); + } + return _totalRollResistanceCoefficient.GetValueOrDefault(); + } + protected internal set { _totalRollResistanceCoefficient = value; } + } + + public double RollResistanceCoefficientWithoutTrailer + { + get { + if (_rollResistanceCoefficientWithoutTrailer == null) { + ComputeRollResistanceAndReducedMassWheels(); + } + return _rollResistanceCoefficientWithoutTrailer.GetValueOrDefault(); + } + protected internal set { _rollResistanceCoefficientWithoutTrailer = value; } + } + + public Kilogram TotalVehicleWeight + { + get { + var retVal = 0.0.SI<Kilogram>(); + retVal += CurbWeight ?? 0.SI<Kilogram>(); + retVal += BodyAndTrailerWeight ?? 0.SI<Kilogram>(); + retVal += Loading ?? 0.SI<Kilogram>(); + return retVal; + } + } + + public Kilogram TotalCurbWeight + { + get { return (CurbWeight ?? 0.SI<Kilogram>()) + (BodyAndTrailerWeight ?? 0.SI<Kilogram>()); } + } + + protected void ComputeRollResistanceAndReducedMassWheels() + { + if (TotalVehicleWeight == 0.SI<Kilogram>()) { + throw new VectoException("Total vehicle weight must be greater than 0! Set CurbWeight and Loading before!"); + } + if (DynamicTyreRadius == null) { + throw new VectoException("Dynamic tyre radius must be set before axles!"); + } + + var g = Physics.GravityAccelleration; + + var rrc = 0.0.SI<Scalar>(); + var rrcVehicle = 0.0.SI<Scalar>(); + + var wheelsInertia = 0.0.SI<KilogramSquareMeter>(); + var vehicleWeightShare = 0.0; + foreach (var axle in _axleData) { + if (axle.AxleWeightShare.IsEqual(0, 1e-12)) { + continue; + } + var nrWheels = axle.TwinTyres ? 4 : 2; + var baseValue = (axle.AxleWeightShare * TotalVehicleWeight * g / axle.TyreTestLoad / nrWheels).Value(); + + var rrcShare = axle.AxleWeightShare * axle.RollResistanceCoefficient * + Math.Pow(baseValue, Physics.RollResistanceExponent - 1); + + if (axle.AxleType != AxleType.Trailer) { + rrcVehicle += rrcShare; + vehicleWeightShare += axle.AxleWeightShare; + } + rrc += rrcShare; + wheelsInertia += nrWheels * axle.Inertia; + } + RollResistanceCoefficientWithoutTrailer = rrcVehicle / vehicleWeightShare; + TotalRollResistanceCoefficient = rrc; + WheelsInertia = wheelsInertia; + } + + // ReSharper disable once UnusedMember.Global -- used via Validation + public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext) + { + var mode = GetExecutionMode(validationContext); + var emsCycle = GetEmsMode(validationContext); + + if (vehicleData.AxleData.Count < 1) { + return new ValidationResult("At least two axles need to be specified"); + } + + var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare); + if (!weightShareSum.IsEqual(1.0, 1E-10)) { + return new ValidationResult( + string.Format("Sum of axle weight share is not 1! sum: {0}, difference: {1}", + weightShareSum, 1 - weightShareSum)); + } + for (var i = 0; i < vehicleData.AxleData.Count; i++) { + if (vehicleData.AxleData[i].TyreTestLoad.IsSmallerOrEqual(0)) { + return new ValidationResult(string.Format("Tyre test load (FzISO) for axle {0} must be greater than 0.", i)); + } + } + + if (vehicleData.TotalRollResistanceCoefficient <= 0) { + return + new ValidationResult(string.Format("Total rolling resistance must be greater than 0! {0}", + vehicleData.TotalRollResistanceCoefficient)); + } + + // total gvw is limited by max gvw (40t) + var gvwTotal = VectoMath.Min(vehicleData.GrossVehicleWeight + vehicleData.TrailerGrossVehicleWeight, + emsCycle + ? Constants.SimulationSettings.MaximumGrossVehicleWeightEMS + : Constants.SimulationSettings.MaximumGrossVehicleWeight); + if (mode != ExecutionMode.Declaration) { + return ValidationResult.Success; + } + // vvvvvvv these checks apply only for declaration mode! vvvvvv + + //if (vehicleData.AxleConfiguration.NumAxles() != vehicleData.AxleData.Count) { + // return + // new ValidationResult( + // string.Format("For a {0} type vehicle exactly {1} number of axles have to pe specified. Found {2}", + // vehicleData.AxleConfiguration.GetName(), vehicleData.AxleConfiguration.NumAxles(), vehicleData.AxleData.Count)); + //} + + if (vehicleData.TotalVehicleWeight > gvwTotal) { + return new ValidationResult( + string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}", + vehicleData.TotalVehicleWeight, gvwTotal)); + } + + var numDrivenAxles = vehicleData._axleData.Count(x => x.AxleType == AxleType.VehicleDriven); + if (numDrivenAxles != vehicleData.AxleConfiguration.NumDrivenAxles()) { + return + new ValidationResult(string.Format( + vehicleData.AxleConfiguration.NumAxles() == 1 + ? "Exactly {0} axle has to be defined as driven, given {1}!" + : "Exactly {0} axles have to be defined as driven, given {1}!", vehicleData.AxleConfiguration.NumDrivenAxles(), + numDrivenAxles)); + } return ValidationResult.Success; } - } - - /// <summary> - /// Data Class for the Vehicle - /// </summary> - [CustomValidation(typeof(VehicleData), "ValidateVehicleData")] - public class VehicleData : SimulationComponentData - { - public string VIN { get; internal set; } - - public string LegislativeClass { get; internal set; } - - public VehicleCategory VehicleCategory { get; internal set; } - - public VehicleClass VehicleClass { get; internal set; } - - public AxleConfiguration AxleConfiguration { get; internal set; } - - public string ManufacturerAddress { get; internal set; } - - - [Required, ValidateObject] private List<Axle> _axleData; - - private KilogramSquareMeter _wheelsInertia; - private double? _totalRollResistanceCoefficient; - private double? _rollResistanceCoefficientWithoutTrailer; - - public List<Axle> AxleData - { - get { return _axleData; } - internal set { - _axleData = value; - _wheelsInertia = null; - _totalRollResistanceCoefficient = null; - } - } - - /// <summary> - /// The Curb Weight of the vehicle - /// (+ Curb Weight of Standard-Body if it has one) - /// (+ Curb Weight of Trailer if it has one) - /// </summary> - [Required, SIRange(500, 40000, emsMission: false), - SIRange(0, 60000, emsMission: true)] - public Kilogram CurbWeight { get; internal set; } - - /// <summary> - /// Curb Weight of Standard-Body (if it has one) - /// + Curb Weight of Trailer (if it has one) - /// </summary> - public Kilogram BodyAndTrailerWeight { get; internal set; } - - [Required, SIRange(0, 40000, emsMission: false), - SIRange(0, 60000, emsMission: true)] - public Kilogram Loading { get; internal set; } - - [SIRange(0, 500)] - public CubicMeter CargoVolume { get; internal set; } - - /// <summary> - /// The Gross Vehicle Weight of the Vehicle. - /// </summary> - [Required, - SIRange(3500, 40000, ExecutionMode.Declaration, emsMission: false), - SIRange(0, 60000, ExecutionMode.Declaration, emsMission: true), - SIRange(0, 1000000, ExecutionMode.Engineering)] - public Kilogram GrossVehicleWeight { get; internal set; } - - /// <summary> - /// The Gross Vehicle Weight of the Trailer (if the vehicle has one). - /// </summary> - [Required, SIRange(0, 40000, emsMission: false), - SIRange(0, 60000, emsMission: true)] - public Kilogram TrailerGrossVehicleWeight { get; internal set; } - - [Required, SIRange(0.1, 0.7)] - public Meter DynamicTyreRadius { get; internal set; } - - public KilogramSquareMeter WheelsInertia - { - get { - if (_wheelsInertia == null) { - ComputeRollResistanceAndReducedMassWheels(); - } - return _wheelsInertia; - } - internal set { _wheelsInertia = value; } - } - - //[Required, SIRange(0, 1E12)] - public double TotalRollResistanceCoefficient - { - get { - if (_totalRollResistanceCoefficient == null) { - ComputeRollResistanceAndReducedMassWheels(); - } - return _totalRollResistanceCoefficient.GetValueOrDefault(); - } - protected internal set { _totalRollResistanceCoefficient = value; } - } - - public double RollResistanceCoefficientWithoutTrailer - { - get { - if (_rollResistanceCoefficientWithoutTrailer == null) { - ComputeRollResistanceAndReducedMassWheels(); - } - return _rollResistanceCoefficientWithoutTrailer.GetValueOrDefault(); - } - protected internal set { _rollResistanceCoefficientWithoutTrailer = value; } - } - - public Kilogram TotalVehicleWeight - { - get { - var retVal = 0.0.SI<Kilogram>(); - retVal += CurbWeight ?? 0.SI<Kilogram>(); - retVal += BodyAndTrailerWeight ?? 0.SI<Kilogram>(); - retVal += Loading ?? 0.SI<Kilogram>(); - return retVal; - } - } - - public Kilogram TotalCurbWeight - { - get { return (CurbWeight ?? 0.SI<Kilogram>()) + (BodyAndTrailerWeight ?? 0.SI<Kilogram>()); } - } - - protected void ComputeRollResistanceAndReducedMassWheels() - { - if (TotalVehicleWeight == 0.SI<Kilogram>()) { - throw new VectoException("Total vehicle weight must be greater than 0! Set CurbWeight and Loading before!"); - } - if (DynamicTyreRadius == null) { - throw new VectoException("Dynamic tyre radius must be set before axles!"); - } - - var g = Physics.GravityAccelleration; - - var rrc = 0.0.SI<Scalar>(); - var rrcVehicle = 0.0.SI<Scalar>(); - - var wheelsInertia = 0.0.SI<KilogramSquareMeter>(); - var vehicleWeightShare = 0.0; - foreach (var axle in _axleData) { - if (axle.AxleWeightShare.IsEqual(0, 1e-12)) { - continue; - } - var nrWheels = axle.TwinTyres ? 4 : 2; - var baseValue = (axle.AxleWeightShare * TotalVehicleWeight * g / axle.TyreTestLoad / nrWheels).Value(); - - var rrcShare = axle.AxleWeightShare * axle.RollResistanceCoefficient * - Math.Pow(baseValue, Physics.RollResistanceExponent - 1); - - if (axle.AxleType != AxleType.Trailer) { - rrcVehicle += rrcShare; - vehicleWeightShare += axle.AxleWeightShare; - } - rrc += rrcShare; - wheelsInertia += nrWheels * axle.Inertia; - } - RollResistanceCoefficientWithoutTrailer = rrcVehicle / vehicleWeightShare; - TotalRollResistanceCoefficient = rrc; - WheelsInertia = wheelsInertia; - } - - // ReSharper disable once UnusedMember.Global -- used via Validation - public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext) - { - var mode = GetExecutionMode(validationContext); - var emsCycle = GetEmsMode(validationContext); - - if (vehicleData.AxleData.Count < 1) { - return new ValidationResult("At least two axles need to be specified"); - } - - var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare); - if (!weightShareSum.IsEqual(1.0, 1E-10)) { - return new ValidationResult( - string.Format("Sum of axle weight share is not 1! sum: {0}, difference: {1}", - weightShareSum, 1 - weightShareSum)); - } - for (var i = 0; i < vehicleData.AxleData.Count; i++) { - if (vehicleData.AxleData[i].TyreTestLoad.IsSmallerOrEqual(0)) { - return new ValidationResult(string.Format("Tyre test load (FzISO) for axle {0} must be greater than 0.", i)); - } - } - - if (vehicleData.TotalRollResistanceCoefficient <= 0) { - return - new ValidationResult(string.Format("Total rolling resistance must be greater than 0! {0}", - vehicleData.TotalRollResistanceCoefficient)); - } - - // total gvw is limited by max gvw (40t) - var gvwTotal = VectoMath.Min(vehicleData.GrossVehicleWeight + vehicleData.TrailerGrossVehicleWeight, - emsCycle - ? Constants.SimulationSettings.MaximumGrossVehicleWeightEMS - : Constants.SimulationSettings.MaximumGrossVehicleWeight); - if (mode != ExecutionMode.Declaration) { - return ValidationResult.Success; - } - // vvvvvvv these checks apply only for declaration mode! vvvvvv - - //if (vehicleData.AxleConfiguration.NumAxles() != vehicleData.AxleData.Count) { - // return - // new ValidationResult( - // string.Format("For a {0} type vehicle exactly {1} number of axles have to pe specified. Found {2}", - // vehicleData.AxleConfiguration.GetName(), vehicleData.AxleConfiguration.NumAxles(), vehicleData.AxleData.Count)); - //} - - if (vehicleData.TotalVehicleWeight > gvwTotal) { - return new ValidationResult( - string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}", - vehicleData.TotalVehicleWeight, gvwTotal)); - } - - var numDrivenAxles = vehicleData._axleData.Count(x => x.AxleType == AxleType.VehicleDriven); - if (numDrivenAxles != 1) { - return new ValidationResult("Exactly one axle has to be defined as driven!"); - } - - return ValidationResult.Success; - } - } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs index 1aa3d8a4ad9e4af5af8a753c9b2cf7514a13cc6b..137d9a7e9123283d7c2f732fe0a4d21169002507 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs @@ -29,301 +29,306 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Linq; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// AMTShiftStrategy implements the AMT Shifting Behaviour. - /// </summary> - public class AMTShiftStrategy : ShiftStrategy - { - protected readonly uint MaxStartGear; - protected uint _nextGear; - - public AMTShiftStrategy(VectoRunData runData, IDataBus dataBus) : base(runData.GearboxData, dataBus) - { - EarlyShiftUp = true; - SkipGears = true; - - var transmissionRatio = runData.AxleGearData.AxleGear.Ratio * - (runData.AngledriveData == null ? 1.0 : runData.AngledriveData.Angledrive.Ratio) / - runData.VehicleData.DynamicTyreRadius; - var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) * - Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed; - foreach (var gearData in ModelData.Gears.Reverse()) { - if (ModelData.StartSpeed * transmissionRatio * gearData.Value.Ratio > minEngineSpeed) { - MaxStartGear = gearData.Key; - break; - } - } - } - - private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed) - { - return (outAngularSpeed * ModelData.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed); - } - - private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed) - { - return - (outAngularSpeed * ModelData.Gears[gear].Ratio).IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? - DataBus.EngineN95hSpeed); - } - - public override GearInfo NextGear - { - get { return new GearInfo(_nextGear, false); } - } - - public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - while (_nextGear > 1 && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) { - _nextGear--; - } - while (_nextGear < ModelData.Gears.Count && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) { - _nextGear++; - } - - return _nextGear; - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) {} - - public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - if (DataBus.VehicleSpeed.IsEqual(0)) { - for (var gear = MaxStartGear; gear > 1; gear--) { - var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; - - var ratedSpeed = DataBus.EngineRatedSpeed; - if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) { - continue; - } - - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); - - var fullLoadPower = response.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.EnginePowerRequest / fullLoadPower; - - if (response.EngineSpeed > DataBus.EngineIdleSpeed && reserve >= ModelData.StartTorqueReserve) { - _nextGear = gear; - return gear; - } - } - _nextGear = 1; - return 1; - } - for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) { - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); - - var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; - var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.EnginePowerRequest / fullLoadPower; - var inTorque = response.ClutchPowerRequest / inAngularSpeed; - - // if in shift curve and torque reserve is provided: return the current gear - if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && - reserve >= ModelData.StartTorqueReserve) { - if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) < - Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) { - gear--; - } - _nextGear = gear; - return gear; - } - - // if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve) - if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < ModelData.Gears.Count) { - _nextGear = gear; - return gear + 1; - } - } - - // fallback: return first gear - _nextGear = 1; - return 1; - } - - public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - // no shift when vehicle stands - if (DataBus.VehicleStopped) { - return false; - } - - // emergency shift to not stall the engine ------------------------ - if (gear == 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { - return true; - } - _nextGear = gear; - while (_nextGear > 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { - _nextGear--; - } - while (_nextGear < ModelData.Gears.Count && - SpeedTooHighForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { - _nextGear++; - } - if (_nextGear != gear) { - return true; - } - - // normal shift when all requirements are fullfilled ------------------ - var minimumShiftTimePassed = (lastShiftTime + ModelData.ShiftTime).IsSmallerOrEqual(absTime); - if (!minimumShiftTimePassed) { - return false; - } - - _nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear); - if (_nextGear != gear) { - return true; - } - - _nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear); - - //if ((ModelData.Gears[_nextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) / - // (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) < - // Constants.SimulationSettings.ClutchClosingSpeedNorm && _nextGear > 1) { - // _nextGear--; - //} - - return _nextGear != gear; - } - - protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) - { - // if the driver's intention is _not_ to accelerate or drive along then don't upshift - if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) { - return currentGear; - } - if ((absTime - _gearbox.LastDownshift).IsSmaller(_gearbox.ModelData.UpshiftAfterDownshiftDelay)) { - return currentGear; - } - var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear); - if (nextGear == currentGear) { - return nextGear; - } - - // estimate acceleration for selected gear - if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(_gearbox.ModelData.UpshiftMinAcceleration)) { - // if less than 0.1 for next gear, don't shift - if (nextGear - currentGear == 1) { - return currentGear; - } - // if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift! - if (nextGear > currentGear && - EstimateAccelerationForGear(currentGear + 1, outAngularVelocity) - .IsSmaller(_gearbox.ModelData.UpshiftMinAcceleration)) { - return currentGear; - } - nextGear = currentGear + 1; - } - - return nextGear; - } - - protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) - { - if ((absTime - _gearbox.LastUpshift).IsSmaller(_gearbox.ModelData.DownshiftAfterUpshiftDelay)) { - return currentGear; - } - return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear); - } - - protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) - { - // upshift - if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear++; - - while (SkipGears && currentGear < ModelData.Gears.Count) { - currentGear++; - var tmpGear = Gearbox.Gear; - _gearbox.Gear = currentGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = response.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; - inTorque = response.ClutchPowerRequest / inAngularVelocity; - - var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), - currentGear > 1 - ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) - : double.MaxValue.SI<NewtonMeter>()); - var reserve = 1 - inTorque / maxTorque; - - if (reserve >= ModelData.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - continue; - } - - currentGear--; - break; - } - } - - // early up shift to higher gear --------------------------------------- - if (EarlyShiftUp && currentGear < ModelData.Gears.Count) { - // try if next gear would provide enough torque reserve - var tryNextGear = currentGear + 1; - var tmpGear = Gearbox.Gear; - _gearbox.Gear = tryNextGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = ModelData.Gears[tryNextGear].Ratio * outAngularVelocity; - inTorque = response.ClutchPowerRequest / inAngularVelocity; - - // if next gear supplied enough power reserve: take it - // otherwise take - if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { - var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.EnginePowerRequest / fullLoadPower; - - if (reserve >= ModelData.TorqueReserve) { - currentGear = tryNextGear; - } - } - } - return currentGear; - } - - protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) - { - // down shift - if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear--; - while (SkipGears && currentGear > 1) { - currentGear--; - var tmpGear = Gearbox.Gear; - _gearbox.Gear = currentGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity; - inTorque = response.ClutchPowerRequest / inAngularVelocity; - var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), - currentGear > 1 - ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) - : double.MaxValue.SI<NewtonMeter>()); - var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); - if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - continue; - } - currentGear++; - break; - } - } - return currentGear; - } - } +using System.Linq; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// AMTShiftStrategy implements the AMT Shifting Behaviour. + /// </summary> + public class AMTShiftStrategy : ShiftStrategy + { + protected readonly uint MaxStartGear; + protected uint _nextGear; + + public AMTShiftStrategy(VectoRunData runData, IDataBus dataBus) : base(runData.GearboxData, dataBus) + { + EarlyShiftUp = true; + SkipGears = true; + + var transmissionRatio = runData.AxleGearData.AxleGear.Ratio * + (runData.AngledriveData == null ? 1.0 : runData.AngledriveData.Angledrive.Ratio) / + runData.VehicleData.DynamicTyreRadius; + var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) * + Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed; + foreach (var gearData in ModelData.Gears.Reverse()) { + if (ModelData.StartSpeed * transmissionRatio * gearData.Value.Ratio > minEngineSpeed) { + MaxStartGear = gearData.Key; + break; + } + } + } + + private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed) + { + return (outAngularSpeed * ModelData.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed); + } + + private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed) + { + return + (outAngularSpeed * ModelData.Gears[gear].Ratio).IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? + DataBus.EngineN95hSpeed); + } + + public override GearInfo NextGear + { + get { return new GearInfo(_nextGear, false); } + } + + public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + while (_nextGear > 1 && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) { + _nextGear--; + } + while (_nextGear < ModelData.Gears.Count && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) { + _nextGear++; + } + + return _nextGear; + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) {} + + public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleSpeed.IsEqual(0)) { + return InitStartGear(outTorque, outAngularVelocity); + } + for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) { + var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + + var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; + var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.EnginePowerRequest / fullLoadPower; + var inTorque = response.ClutchPowerRequest / inAngularSpeed; + + // if in shift curve and torque reserve is provided: return the current gear + if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && + reserve >= ModelData.StartTorqueReserve) { + if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) < + Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) { + gear--; + } + _nextGear = gear; + return gear; + } + + // if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve) + if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < ModelData.Gears.Count) { + _nextGear = gear; + return gear + 1; + } + } + + // fallback: return first gear + _nextGear = 1; + return 1; + } + + private uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + for (var gear = MaxStartGear; gear > 1; gear--) { + var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; + + var ratedSpeed = DataBus.EngineRatedSpeed; + if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) { + continue; + } + + var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + + var fullLoadPower = response.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.EnginePowerRequest / fullLoadPower; + + if (response.EngineSpeed > DataBus.EngineIdleSpeed && reserve >= ModelData.StartTorqueReserve) { + _nextGear = gear; + return gear; + } + } + _nextGear = 1; + return 1; + } + + public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + // no shift when vehicle stands + if (DataBus.VehicleStopped) { + return false; + } + + // emergency shift to not stall the engine ------------------------ + if (gear == 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { + return true; + } + _nextGear = gear; + while (_nextGear > 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { + _nextGear--; + } + while (_nextGear < ModelData.Gears.Count && + SpeedTooHighForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) { + _nextGear++; + } + if (_nextGear != gear) { + return true; + } + + // normal shift when all requirements are fullfilled ------------------ + var minimumShiftTimePassed = (lastShiftTime + ModelData.ShiftTime).IsSmallerOrEqual(absTime); + if (!minimumShiftTimePassed) { + return false; + } + + _nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear); + if (_nextGear != gear) { + return true; + } + + _nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear); + + //if ((ModelData.Gears[_nextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) / + // (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) < + // Constants.SimulationSettings.ClutchClosingSpeedNorm && _nextGear > 1) { + // _nextGear--; + //} + + return _nextGear != gear; + } + + protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) + { + // if the driver's intention is _not_ to accelerate or drive along then don't upshift + if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) { + return currentGear; + } + if ((absTime - _gearbox.LastDownshift).IsSmaller(_gearbox.ModelData.UpshiftAfterDownshiftDelay)) { + return currentGear; + } + var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear); + if (nextGear == currentGear) { + return nextGear; + } + + // estimate acceleration for selected gear + if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(_gearbox.ModelData.UpshiftMinAcceleration)) { + // if less than 0.1 for next gear, don't shift + if (nextGear - currentGear == 1) { + return currentGear; + } + // if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift! + if (nextGear > currentGear && + EstimateAccelerationForGear(currentGear + 1, outAngularVelocity) + .IsSmaller(_gearbox.ModelData.UpshiftMinAcceleration)) { + return currentGear; + } + nextGear = currentGear + 1; + } + + return nextGear; + } + + protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) + { + if ((absTime - _gearbox.LastUpshift).IsSmaller(_gearbox.ModelData.DownshiftAfterUpshiftDelay)) { + return currentGear; + } + return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear); + } + + protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) + { + // upshift + if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear++; + + while (SkipGears && currentGear < ModelData.Gears.Count) { + currentGear++; + var tmpGear = Gearbox.Gear; + _gearbox.Gear = currentGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = response.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; + inTorque = response.ClutchPowerRequest / inAngularVelocity; + + var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), + currentGear > 1 + ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) + : double.MaxValue.SI<NewtonMeter>()); + var reserve = 1 - inTorque / maxTorque; + + if (reserve >= ModelData.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + continue; + } + + currentGear--; + break; + } + } + + // early up shift to higher gear --------------------------------------- + if (EarlyShiftUp && currentGear < ModelData.Gears.Count) { + // try if next gear would provide enough torque reserve + var tryNextGear = currentGear + 1; + var tmpGear = Gearbox.Gear; + _gearbox.Gear = tryNextGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = ModelData.Gears[tryNextGear].Ratio * outAngularVelocity; + inTorque = response.ClutchPowerRequest / inAngularVelocity; + + // if next gear supplied enough power reserve: take it + // otherwise take + if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { + var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.EnginePowerRequest / fullLoadPower; + + if (reserve >= ModelData.TorqueReserve) { + currentGear = tryNextGear; + } + } + } + return currentGear; + } + + protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear) + { + // down shift + if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear--; + while (SkipGears && currentGear > 1) { + currentGear--; + var tmpGear = Gearbox.Gear; + _gearbox.Gear = currentGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity; + inTorque = response.ClutchPowerRequest / inAngularVelocity; + var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), + currentGear > 1 + ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) + : double.MaxValue.SI<NewtonMeter>()); + var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); + if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + continue; + } + currentGear++; + break; + } + } + return currentGear; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index d9f0b0341354b449747a868b53ad183e4080f860..d9fb06e6d86da8aa421209671e5ca90f2a3385aa 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -29,386 +29,395 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class ATGearbox : AbstractGearbox<ATGearbox.ATGearboxState> - { - private readonly IShiftStrategy _strategy; - protected internal readonly TorqueConverter TorqueConverter; - private IIdleController _idleController; - protected bool RequestAfterGearshift; - - public bool TorqueConverterLocked - { - get { return CurrentState.TorqueConverterLocked; } - set { CurrentState.TorqueConverterLocked = value; } - } - - public ATGearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) - : base(container, runData) - { - _strategy = strategy; - _strategy.Gearbox = this; - LastShift = -double.MaxValue.SI<Second>(); - TorqueConverter = new TorqueConverter(this, _strategy, container, ModelData.TorqueConverterData, - runData); - } - - public IIdleController IdleController - { - get { return _idleController; } - set { - _idleController = value; - _idleController.RequestPort = NextComponent; - } - } - - public bool Disengaged - { - get { return CurrentState.Disengaged; } - set { CurrentState.Disengaged = value; } - } - - public override void Connect(ITnOutPort other) - { - base.Connect(other); - TorqueConverter.NextComponent = other; - } - - public override GearInfo NextGear - { - get { return _strategy.NextGear; } - } - - public override bool ClutchClosed(Second absTime) - { - return absTime.IsGreater(DataBus.AbsTime) || - !(CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)); - } - - public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - if (CurrentState.Disengaged) { - Gear = _strategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, outTorque, - outAngularVelocity); - } - var inAngularVelocity = 0.SI<PerSecond>(); - var inTorque = 0.SI<NewtonMeter>(); - var effectiveRatio = ModelData.Gears[Gear].Ratio; - var effectiveLossMap = ModelData.Gears[Gear].LossMap; - if (!CurrentState.TorqueConverterLocked) { - effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; - effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; - } - if (!DataBus.VehicleStopped) { - inAngularVelocity = outAngularVelocity * effectiveRatio; - var torqueLossResult = effectiveLossMap.GetTorqueLoss(outAngularVelocity, outTorque); - CurrentState.TorqueLossResult = torqueLossResult; - - inTorque = outTorque / effectiveRatio + torqueLossResult.Value; - } - if (CurrentState.Disengaged) { - return NextComponent.Initialize(0.SI<NewtonMeter>(), null); - } - - if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { - throw new VectoSimulationException( - "Torque converter requested by strategy for gear without torque converter!"); - } - var response = CurrentState.TorqueConverterLocked - ? NextComponent.Initialize(inTorque, inAngularVelocity) - : TorqueConverter.Initialize(inTorque, inAngularVelocity); - - CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() { - Value = 0.SI<NewtonMeter>(), - Extrapolated = false - }; - - PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.Gear = Gear; - PreviousState.TorqueConverterLocked = CurrentState.TorqueConverterLocked; - return response; - } - - internal ResponseDryRun Initialize(uint gear, bool torqueConverterLocked, NewtonMeter outTorque, - PerSecond outAngularVelocity) - { - var effectiveRatio = torqueConverterLocked - ? ModelData.Gears[gear].Ratio - : ModelData.Gears[gear].TorqueConverterRatio; - - var inAngularVelocity = outAngularVelocity * effectiveRatio; - var torqueLossResult = torqueConverterLocked - ? ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque) - : ModelData.Gears[gear].TorqueConverterGearLossMap.GetTorqueLoss(outAngularVelocity, outTorque); - - var inTorque = outTorque / effectiveRatio + torqueLossResult.Value; - - IResponse response; - if (torqueConverterLocked) { - response = NextComponent.Initialize(inTorque, inAngularVelocity); - } else { - if (!ModelData.Gears[gear].HasTorqueConverter) { - throw new VectoSimulationException( - "Torque converter requested by strategy for gear without torque converter!"); - } - response = TorqueConverter.Initialize(inTorque, inAngularVelocity); - } - - response.Switch(). - Case<ResponseSuccess>(). // accept - Case<ResponseUnderload>(). // accept - Case<ResponseOverload>(). // accept - Default(r => { throw new UnexpectedResponseException("AT-Gearbox.Initialize", r); }); - - return new ResponseDryRun { - Source = this, - EngineSpeed = response.EngineSpeed, - EnginePowerRequest = response.EnginePowerRequest, - GearboxPowerRequest = outTorque * outAngularVelocity, - }; - } - - public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - IterationStatistics.Increment(this, "Requests"); - - Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - - if (!dryRun && - ((DataBus.VehicleStopped && outAngularVelocity > 0) || - (CurrentState.Disengaged && outTorque.IsGreater(0, 1e-3)))) { - Gear = 1; - CurrentState.TorqueConverterLocked = false; - LastShift = absTime; - CurrentState.Disengaged = false; - } - - IResponse retVal; - var count = 0; - var loop = false; - if (RequestAfterGearshift) { - LastShift = absTime; - Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); - CurrentState.PowershiftLossEnergy = ComputeShiftLosses(outTorque, outAngularVelocity); - } else { - if (PreviousState.PowershiftLossEnergy != null && PreviousState.PowershiftLossEnergy.IsGreater(0)) { - CurrentState.PowershiftLossEnergy = PreviousState.PowershiftLossEnergy; - } - } - do { - if (CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)) { - // only when vehicle is halted or close before halting - retVal = RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - } else { - CurrentState.Disengaged = false; - retVal = RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - IdleController.Reset(); - } - if (retVal is ResponseGearShift) { - if (ConsiderShiftLosses(_strategy.NextGear, outTorque)) { - retVal = new ResponseFailTimeInterval { - Source = this, - DeltaT = ModelData.PowershiftShiftTime, - GearboxPowerRequest = - outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 - }; - RequestAfterGearshift = true; - LastShift = absTime; - } else { - loop = true; - Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); - LastShift = absTime; - } - } - } while (loop && ++count < 2); - - retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - return retVal; - } - - private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { - throw new VectoSimulationException( - "Torque converter requested by strategy for gear without torque converter!"); - } - - var effectiveRatio = ModelData.Gears[Gear].Ratio; - var effectiveLossMap = ModelData.Gears[Gear].LossMap; - if (!CurrentState.TorqueConverterLocked) { - effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; - effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; - } - - var inAngularVelocity = outAngularVelocity * effectiveRatio; - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; - var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); - var inTorque = outTorque * (avgOutAngularVelocity / avgInAngularVelocity) + inTorqueLossResult.Value; - - var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) - ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity - : 0.SI<NewtonMeter>(); - inTorque += inertiaTorqueLossOut / effectiveRatio; - - if (CurrentState.PowershiftLossEnergy != null) { - var remainingShiftLossLime = ModelData.PowershiftShiftTime - (absTime - LastShift); - if (remainingShiftLossLime.IsGreater(0)) { - var aliquotEnergyLoss = CurrentState.PowershiftLossEnergy * VectoMath.Min(1.0, dt / remainingShiftLossLime); - var avgEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; - CurrentState.PowershiftLoss = aliquotEnergyLoss / dt / avgEngineSpeed; - inTorque += CurrentState.PowershiftLoss; - CurrentState.PowershiftLossEnergy -= aliquotEnergyLoss; - //inTorque += CurrentState.PowershiftLossEnergy; - } - } - - if (!dryRun) { - CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut; - CurrentState.TorqueLossResult = inTorqueLossResult; - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.Gear = Gear; - CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; - TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, - CurrentState.InAngularVelocity); - } - - if (!CurrentState.TorqueConverterLocked) { - return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, dryRun); - } - var retVal = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, dryRun); - if (!dryRun && retVal is ResponseSuccess && - _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, Gear, - LastShift)) { - return new ResponseGearShift { Source = this }; - } - - return retVal; - } - - private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - if (dryRun) { - // if gearbox is disengaged the 0[W]-line is the limit for drag and full load. - return new ResponseDryRun { - Source = this, - GearboxPowerRequest = outTorque * avgAngularVelocity, - DeltaDragLoad = outTorque * avgAngularVelocity, - DeltaFullLoad = outTorque * avgAngularVelocity, - }; - } - if ((outTorque * avgAngularVelocity).IsGreater(0.SI<Watt>(), - Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseOverload { - Source = this, - Delta = outTorque * avgAngularVelocity, - GearboxPowerRequest = outTorque * avgAngularVelocity - }; - } - - if ((outTorque * avgAngularVelocity).IsSmaller(0.SI<Watt>(), - Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseUnderload { - Source = this, - Delta = outTorque * avgAngularVelocity, - GearboxPowerRequest = outTorque * avgAngularVelocity - }; - } - - Log.Debug("Invoking IdleController..."); - - var retval = IdleController.Request(absTime, dt, 0.SI<NewtonMeter>(), null); - retval.ClutchPowerRequest = 0.SI<Watt>(); - - // no dry-run - update state - var effectiveRatio = ModelData.Gears[Gear].Ratio; - if (!CurrentState.TorqueConverterLocked) { - effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; - } - CurrentState.SetState(0.SI<NewtonMeter>(), outAngularVelocity * effectiveRatio, outTorque, - outAngularVelocity); - CurrentState.Gear = 1; - CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter; - CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() { - Extrapolated = false, - Value = 0.SI<NewtonMeter>() - }; - TorqueConverter.Locked(DataBus.VehicleStopped ? 0.SI<NewtonMeter>() : CurrentState.InTorque, retval.EngineSpeed, - CurrentState.InTorque, - outAngularVelocity * effectiveRatio); - - - return retval; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - - container[ModalResultField.Gear] = CurrentState.Disengaged || DataBus.VehicleStopped ? 0 : Gear; - container[ModalResultField.TC_Locked] = CurrentState.TorqueConverterLocked; - container[ModalResultField.P_gbx_loss] = CurrentState.InTorque * avgInAngularSpeed - - CurrentState.OutTorque * avgOutAngularSpeed; - container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; - container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; - container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLoss.DefaultIfNull(0) * avgInAngularSpeed; - container[ModalResultField.n_gbx_out_avg] = avgOutAngularSpeed; - container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; - } - - protected override void DoCommitSimulationStep() - { - if (!CurrentState.Disengaged && CurrentState.TorqueLossResult != null && - CurrentState.TorqueLossResult.Extrapolated) { - Log.Warn( - "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque, - ModelData.Gears[Gear].Ratio); - if (DataBus.ExecutionMode == ExecutionMode.Declaration) { - throw new VectoException( - "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", - Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque, - ModelData.Gears[Gear].Ratio); - } - } - RequestAfterGearshift = false; - - if (DataBus.VehicleStopped) { - CurrentState.Disengaged = true; - } - - AdvanceState(); - - CurrentState.TorqueConverterLocked = PreviousState.TorqueConverterLocked; - CurrentState.Disengaged = PreviousState.Disengaged; - } - - public class ATGearboxState : GearboxState - { - public bool TorqueConverterLocked; - public bool Disengaged = true; - public WattSecond PowershiftLossEnergy; - public NewtonMeter PowershiftLoss; - } - } +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class ATGearbox : AbstractGearbox<ATGearbox.ATGearboxState> + { + private readonly IShiftStrategy _strategy; + protected internal readonly TorqueConverter TorqueConverter; + private IIdleController _idleController; + protected bool RequestAfterGearshift; + + public bool TorqueConverterLocked + { + get { return CurrentState.TorqueConverterLocked; } + set { CurrentState.TorqueConverterLocked = value; } + } + + public ATGearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) + : base(container, runData) + { + _strategy = strategy; + _strategy.Gearbox = this; + LastShift = -double.MaxValue.SI<Second>(); + TorqueConverter = new TorqueConverter(this, _strategy, container, ModelData.TorqueConverterData, + runData); + } + + public IIdleController IdleController + { + get { return _idleController; } + set + { + _idleController = value; + _idleController.RequestPort = NextComponent; + } + } + + public bool Disengaged + { + get { return CurrentState.Disengaged; } + set { CurrentState.Disengaged = value; } + } + + public override void Connect(ITnOutPort other) + { + base.Connect(other); + TorqueConverter.NextComponent = other; + } + + public override GearInfo NextGear + { + get { return _strategy.NextGear; } + } + + public override bool ClutchClosed(Second absTime) + { + return absTime.IsGreater(DataBus.AbsTime) || + !(CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)); + } + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (CurrentState.Disengaged) { + Gear = _strategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, outTorque, + outAngularVelocity); + } + var inAngularVelocity = 0.SI<PerSecond>(); + var inTorque = 0.SI<NewtonMeter>(); + var effectiveRatio = ModelData.Gears[Gear].Ratio; + var effectiveLossMap = ModelData.Gears[Gear].LossMap; + if (!CurrentState.TorqueConverterLocked) { + effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; + effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; + } + if (!DataBus.VehicleStopped) { + inAngularVelocity = outAngularVelocity * effectiveRatio; + var torqueLossResult = effectiveLossMap.GetTorqueLoss(outAngularVelocity, outTorque); + CurrentState.TorqueLossResult = torqueLossResult; + + inTorque = outTorque / effectiveRatio + torqueLossResult.Value; + } + if (CurrentState.Disengaged) { + return NextComponent.Initialize(0.SI<NewtonMeter>(), null); + } + + if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { + throw new VectoSimulationException( + "Torque converter requested by strategy for gear without torque converter!"); + } + var response = CurrentState.TorqueConverterLocked + ? NextComponent.Initialize(inTorque, inAngularVelocity) + : TorqueConverter.Initialize(inTorque, inAngularVelocity); + + CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() { + Value = 0.SI<NewtonMeter>(), + Extrapolated = false + }; + + PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.Gear = Gear; + PreviousState.TorqueConverterLocked = CurrentState.TorqueConverterLocked; + return response; + } + + internal ResponseDryRun Initialize(uint gear, bool torqueConverterLocked, NewtonMeter outTorque, + PerSecond outAngularVelocity) + { + var effectiveRatio = torqueConverterLocked + ? ModelData.Gears[gear].Ratio + : ModelData.Gears[gear].TorqueConverterRatio; + + var inAngularVelocity = outAngularVelocity * effectiveRatio; + var torqueLossResult = torqueConverterLocked + ? ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque) + : ModelData.Gears[gear].TorqueConverterGearLossMap.GetTorqueLoss(outAngularVelocity, outTorque); + + var inTorque = outTorque / effectiveRatio + torqueLossResult.Value; + + IResponse response; + if (torqueConverterLocked) { + response = NextComponent.Initialize(inTorque, inAngularVelocity); + } else { + if (!ModelData.Gears[gear].HasTorqueConverter) { + throw new VectoSimulationException( + "Torque converter requested by strategy for gear without torque converter!"); + } + response = TorqueConverter.Initialize(inTorque, inAngularVelocity); + } + + response.Switch(). + Case<ResponseSuccess>(). // accept + Case<ResponseUnderload>(). // accept + Case<ResponseOverload>(). // accept + Default(r => { + throw new UnexpectedResponseException("AT-Gearbox.Initialize", r); + }); + + return new ResponseDryRun { + Source = this, + EngineSpeed = response.EngineSpeed, + EnginePowerRequest = response.EnginePowerRequest, + GearboxPowerRequest = outTorque * outAngularVelocity, + }; + } + + public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + IterationStatistics.Increment(this, "Requests"); + + Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); + + var driveOffSpeed = DataBus.VehicleStopped && outAngularVelocity > 0; + var driveOffTorque = CurrentState.Disengaged && outTorque.IsGreater(0, 1e-3); + if (!dryRun && (driveOffSpeed || driveOffTorque)) { + Gear = 1; + CurrentState.TorqueConverterLocked = false; + LastShift = absTime; + CurrentState.Disengaged = false; + } + + IResponse retVal; + var count = 0; + var loop = false; + SetPowershiftLossEnergy(absTime, dt, outTorque, outAngularVelocity); + do { + if (CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)) { + // only when vehicle is halted or close before halting + retVal = RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + } else { + CurrentState.Disengaged = false; + retVal = RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + IdleController.Reset(); + } + if (!(retVal is ResponseGearShift)) { + continue; + } + if (ConsiderShiftLosses(_strategy.NextGear, outTorque)) { + retVal = new ResponseFailTimeInterval { + Source = this, + DeltaT = ModelData.PowershiftShiftTime, + GearboxPowerRequest = + outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 + }; + RequestAfterGearshift = true; + LastShift = absTime; + } else { + loop = true; + Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); + LastShift = absTime; + } + } while (loop && ++count < 2); + + retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + return retVal; + } + + private void SetPowershiftLossEnergy(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (RequestAfterGearshift) { + LastShift = absTime; + Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); + CurrentState.PowershiftLossEnergy = ComputeShiftLosses(outTorque, outAngularVelocity); + } else { + if (PreviousState.PowershiftLossEnergy != null && PreviousState.PowershiftLossEnergy.IsGreater(0)) { + CurrentState.PowershiftLossEnergy = PreviousState.PowershiftLossEnergy; + } + } + } + + private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { + throw new VectoSimulationException( + "Torque converter requested by strategy for gear without torque converter!"); + } + + var effectiveRatio = ModelData.Gears[Gear].Ratio; + var effectiveLossMap = ModelData.Gears[Gear].LossMap; + if (!CurrentState.TorqueConverterLocked) { + effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; + effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; + } + + var inAngularVelocity = outAngularVelocity * effectiveRatio; + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; + var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); + var inTorque = outTorque * (avgOutAngularVelocity / avgInAngularVelocity) + inTorqueLossResult.Value; + + var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) + ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity + : 0.SI<NewtonMeter>(); + inTorque += inertiaTorqueLossOut / effectiveRatio; + + if (CurrentState.PowershiftLossEnergy != null) { + var remainingShiftLossLime = ModelData.PowershiftShiftTime - (absTime - LastShift); + if (remainingShiftLossLime.IsGreater(0)) { + var aliquotEnergyLoss = CurrentState.PowershiftLossEnergy * VectoMath.Min(1.0, dt / remainingShiftLossLime); + var avgEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; + CurrentState.PowershiftLoss = aliquotEnergyLoss / dt / avgEngineSpeed; + inTorque += CurrentState.PowershiftLoss; + CurrentState.PowershiftLossEnergy -= aliquotEnergyLoss; + //inTorque += CurrentState.PowershiftLossEnergy; + } + } + + if (!dryRun) { + CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut; + CurrentState.TorqueLossResult = inTorqueLossResult; + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; + TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, + CurrentState.InAngularVelocity); + } + + if (!CurrentState.TorqueConverterLocked) { + return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, dryRun); + } + var retVal = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, dryRun); + if (!dryRun && retVal is ResponseSuccess && + _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, Gear, + LastShift)) { + return new ResponseGearShift { Source = this }; + } + + return retVal; + } + + private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + if (dryRun) { + // if gearbox is disengaged the 0[W]-line is the limit for drag and full load. + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = outTorque * avgAngularVelocity, + DeltaDragLoad = outTorque * avgAngularVelocity, + DeltaFullLoad = outTorque * avgAngularVelocity, + }; + } + if ((outTorque * avgAngularVelocity).IsGreater(0.SI<Watt>(), + Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseOverload { + Source = this, + Delta = outTorque * avgAngularVelocity, + GearboxPowerRequest = outTorque * avgAngularVelocity + }; + } + + if ((outTorque * avgAngularVelocity).IsSmaller(0.SI<Watt>(), + Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseUnderload { + Source = this, + Delta = outTorque * avgAngularVelocity, + GearboxPowerRequest = outTorque * avgAngularVelocity + }; + } + + Log.Debug("Invoking IdleController..."); + + var retval = IdleController.Request(absTime, dt, 0.SI<NewtonMeter>(), null); + retval.ClutchPowerRequest = 0.SI<Watt>(); + + // no dry-run - update state + var effectiveRatio = ModelData.Gears[Gear].Ratio; + if (!CurrentState.TorqueConverterLocked) { + effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; + } + CurrentState.SetState(0.SI<NewtonMeter>(), outAngularVelocity * effectiveRatio, outTorque, + outAngularVelocity); + CurrentState.Gear = 1; + CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter; + CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() { + Extrapolated = false, + Value = 0.SI<NewtonMeter>() + }; + TorqueConverter.Locked(DataBus.VehicleStopped ? 0.SI<NewtonMeter>() : CurrentState.InTorque, retval.EngineSpeed, + CurrentState.InTorque, + outAngularVelocity * effectiveRatio); + + + return retval; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + + container[ModalResultField.Gear] = CurrentState.Disengaged || DataBus.VehicleStopped ? 0 : Gear; + container[ModalResultField.TC_Locked] = CurrentState.TorqueConverterLocked; + container[ModalResultField.P_gbx_loss] = CurrentState.InTorque * avgInAngularSpeed - + CurrentState.OutTorque * avgOutAngularSpeed; + container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; + container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; + container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLoss.DefaultIfNull(0) * avgInAngularSpeed; + container[ModalResultField.n_gbx_out_avg] = avgOutAngularSpeed; + container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; + } + + protected override void DoCommitSimulationStep() + { + if (!CurrentState.Disengaged && CurrentState.TorqueLossResult != null && + CurrentState.TorqueLossResult.Extrapolated) { + Log.Warn( + "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque, + ModelData.Gears[Gear].Ratio); + if (DataBus.ExecutionMode == ExecutionMode.Declaration) { + throw new VectoException( + "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", + Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque, + ModelData.Gears[Gear].Ratio); + } + } + RequestAfterGearshift = false; + + if (DataBus.VehicleStopped) { + CurrentState.Disengaged = true; + } + + AdvanceState(); + + CurrentState.TorqueConverterLocked = PreviousState.TorqueConverterLocked; + CurrentState.Disengaged = PreviousState.Disengaged; + } + + public class ATGearboxState : GearboxState + { + public bool TorqueConverterLocked; + public bool Disengaged = true; + public WattSecond PowershiftLossEnergy; + public NewtonMeter PowershiftLoss; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index d70578e50ffec17b881e327011aab48b359559a8..7d2f64e0de6e6b511db0b0a8a1f1f86bf267409b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -29,326 +29,356 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class ATShiftStrategy : BaseShiftStrategy - { - private ATGearbox _gearbox; - private readonly NextGearState _nextGear = new NextGearState(); - - public override IGearbox Gearbox - { - get { return _gearbox; } - set { - _gearbox = value as ATGearbox; - if (_gearbox == null) { - throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); - } - } - } - - public override GearInfo NextGear - { - get { return new GearInfo(_nextGear.Gear, _nextGear.TorqueConverterLocked); } - } - - public ATShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} - - public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) - { - if (DataBus.VehicleSpeed.IsEqual(0)) { - // AT always starts in first gear and TC active! - _gearbox.TorqueConverterLocked = false; - _gearbox.Disengaged = true; - return 1; - } - var torqueConverterLocked = true; - for (var gear = ModelData.Gears.Keys.Max(); gear > 1; gear--) { - if (_gearbox.ModelData.Gears[gear].HasTorqueConverter) { - torqueConverterLocked = false; - } - var response = _gearbox.Initialize(gear, torqueConverterLocked, torque, outAngularVelocity); - - if (response.EngineSpeed > DataBus.EngineRatedSpeed || response.EngineSpeed < DataBus.EngineIdleSpeed) { - continue; - } - - if (!IsBelowDownShiftCurve(gear, response.EnginePowerRequest / response.EngineSpeed, response.EngineSpeed)) { - _gearbox.TorqueConverterLocked = torqueConverterLocked; - _gearbox.Disengaged = false; - return gear; - } - } - // fallback: start with first gear; - _gearbox.TorqueConverterLocked = false; - _gearbox.Disengaged = false; - return 1; - } - - public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) { - _gearbox.TorqueConverterLocked = _nextGear.TorqueConverterLocked; - _gearbox.Disengaged = _nextGear.Disengaged; - _nextGear.AbsTime = null; - return _nextGear.Gear; - } - _nextGear.AbsTime = null; - return _gearbox.Gear; - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) - { - throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); - } - - public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - // ENGAGE --------------------------------------------------------- - // 0 -> 1C: drive off after disengaged - engage first gear - if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) { - Log.Debug("shift required: drive off after vehicle stopped"); - _nextGear.SetState(absTime, disengaged: false, gear: 1, tcLocked: false); - return true; - } - - // DISENGAGE ------------------------------------------------------ - // 1) _ -> 0: disengage before halting - var braking = DataBus.DriverBehavior == DrivingBehavior.Braking; - var torqueNegative = outTorque.IsSmaller(0); - var slowerThanDisengageSpeed = - DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed); - var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed; - - // 2) L -> 0: disengage if inAngularVelocity == 0 - var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>()); - - // 3) 1C -> 0: disengange when negative T_out and positive T_in - var gear1C = gear == 1 && !_gearbox.TorqueConverterLocked; - var disengageTOutNegativeAndTInPositive = DataBus.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) && - inTorque.IsGreater(0); - - var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C && - inAngularVelocity.IsSmallerOrEqual(DataBus.EngineIdleSpeed); - - if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero || - disengageTOutNegativeAndTInPositive) { - _nextGear.SetState(absTime, disengaged: true, gear: 1, tcLocked: false); - return true; - } - - // EMERGENCY SHIFTS --------------------------------------- - // Emergency Downshift: if lower than engine idle speed - if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - Log.Debug("engine speed would fall below idle speed - shift down"); - Downshift(absTime, gear); - return true; - } - // Emergency Upshift: if higher than engine rated speed - if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) { - // check if upshift is possible - if (!ModelData.Gears.ContainsKey(gear + 1)) { - return false; - } - Log.Debug("engine speed would be above max speed / rated speed - shift up"); - Upshift(absTime, gear); - return true; - } - - // UPSHIFT -------------------------------------------------------- - if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - lastShiftTime)) { - return true; - } - - // DOWNSHIFT ------------------------------------------------------ - if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - lastShiftTime)) { - return true; - } - - return false; - } - - [SuppressMessage("ReSharper", "UnusedParameter.Local")] - private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); - if (!shiftTimeReached) { - return false; - } - - var currentGear = ModelData.Gears[gear]; - - if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) { - // UPSHIFT - General Rule - // L -> L+1 - // C -> L - var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear; - if (!ModelData.Gears.ContainsKey(nextGear)) { - return false; - } - - var nextEngineSpeed = outAngularVelocity * ModelData.Gears[nextGear].Ratio; - if (nextEngineSpeed.IsEqual(0)) { - return false; - } - - var currentEnginePower = inTorque * inAngularVelocity; - var nextEngineTorque = currentEnginePower / nextEngineSpeed; - var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked); - - var minAccelerationReachable = true; - if (!DataBus.VehicleSpeed.IsEqual(0)) { - var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity); - var minAcceleration = _gearbox.TorqueConverterLocked - ? ModelData.UpshiftMinAcceleration - : ModelData.TorqueConverterData.CLUpshiftMinAcceleration; - minAcceleration = VectoMath.Min(minAcceleration, DataBus.DriverAcceleration); - minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); - } - - if (isAboveUpShift && minAccelerationReachable) { - Upshift(absTime, gear); - return true; - } - } - - // UPSHIFT - Special rule for 1C -> 2C - if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && - ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { - // C -> C+1 - var nextGear = ModelData.Gears[gear + 1]; - var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; - var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); - - var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; - var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; - var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed); - - var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); - - var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity); - var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration, - DataBus.DriverAcceleration); - var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); - - if (engineSpeedOverMin && minAccelerationReachable) { - Upshift(absTime, gear); - return true; - } - } - return false; - } - - /// <summary> - /// Tests if the operating point is above (right of) the up-shift curve. - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param> - /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> - private bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed, - bool torqueConverterLocked) - { - var shiftPolygon = torqueConverterLocked - ? ModelData.Gears[gear].ShiftPolygon - : ModelData.Gears[gear].TorqueConverterShiftPolygon; - - return gear < ModelData.Gears.Keys.Max() && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); - } - - private void Upshift(Second absTime, uint gear) - { - // C -> L: switch from torque converter to locked gear - if (!_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasLockedGear) { - _nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: true); - return; - } - - // L -> L+1 - // C -> C+1 - if (ModelData.Gears.ContainsKey(gear + 1)) { - _nextGear.SetState(absTime, disengaged: false, gear: gear + 1, tcLocked: _gearbox.TorqueConverterLocked); - return; - } - - // C -> L+1 -- not allowed!! - throw new VectoSimulationException( - "ShiftStrategy wanted to shift up, but current gear has active torque converter (C) but no locked gear (no L) and shifting directly to (L) is not allowed."); - } - - [SuppressMessage("ReSharper", "UnusedParameter.Local")] - private bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); - - if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) { - Downshift(absTime, gear); - return true; - } - - return false; - } - - /// <summary> - /// Tests if the operating point is below (left of) the down-shift curve. - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> - private bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - return gear > 1 && ModelData.Gears[gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); - } - - private void Downshift(Second absTime, uint gear) - { - // L -> C - if (_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasTorqueConverter) { - _nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: false); - return; - } - - // L -> L-1 - // C -> C-1 - if (ModelData.Gears.ContainsKey(gear - 1)) { - _nextGear.SetState(absTime, disengaged: false, gear: gear - 1, tcLocked: _gearbox.TorqueConverterLocked); - return; - } - - // L -> 0 -- not allowed!! - throw new VectoSimulationException( - "ShiftStrategy wanted to shift down but current gear is locked (L) and has no torque converter (C) and disenganging directly from (L) is not allowed."); - } - - private class NextGearState - { - public Second AbsTime; - public bool Disengaged; - public uint Gear; - public bool TorqueConverterLocked; - - public void SetState(Second absTime, bool disengaged, uint gear, bool tcLocked) - { - AbsTime = absTime; - Disengaged = disengaged; - Gear = gear; - TorqueConverterLocked = tcLocked; - } - } - } +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class ATShiftStrategy : BaseShiftStrategy + { + private ATGearbox _gearbox; + private readonly NextGearState _nextGear = new NextGearState(); + + public override IGearbox Gearbox + { + get { return _gearbox; } + set + { + _gearbox = value as ATGearbox; + if (_gearbox == null) { + throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); + } + } + } + + public override GearInfo NextGear + { + get { return new GearInfo(_nextGear.Gear, _nextGear.TorqueConverterLocked); } + } + + public ATShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} + + public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleSpeed.IsEqual(0)) { + // AT always starts in first gear and TC active! + _gearbox.TorqueConverterLocked = false; + _gearbox.Disengaged = true; + return 1; + } + var torqueConverterLocked = true; + for (var gear = ModelData.Gears.Keys.Max(); gear > 1; gear--) { + if (_gearbox.ModelData.Gears[gear].HasTorqueConverter) { + torqueConverterLocked = false; + } + var response = _gearbox.Initialize(gear, torqueConverterLocked, torque, outAngularVelocity); + + if (response.EngineSpeed > DataBus.EngineRatedSpeed || response.EngineSpeed < DataBus.EngineIdleSpeed) { + continue; + } + + if (!IsBelowDownShiftCurve(gear, response.EnginePowerRequest / response.EngineSpeed, response.EngineSpeed)) { + _gearbox.TorqueConverterLocked = torqueConverterLocked; + _gearbox.Disengaged = false; + return gear; + } + } + // fallback: start with first gear; + _gearbox.TorqueConverterLocked = false; + _gearbox.Disengaged = false; + return 1; + } + + public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) { + _gearbox.TorqueConverterLocked = _nextGear.TorqueConverterLocked; + _gearbox.Disengaged = _nextGear.Disengaged; + _nextGear.AbsTime = null; + return _nextGear.Gear; + } + _nextGear.AbsTime = null; + return _gearbox.Gear; + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) + { + throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); + } + + public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + // ENGAGE --------------------------------------------------------- + // 0 -> 1C: drive off after disengaged - engage first gear + if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) { + Log.Debug("shift required: drive off after vehicle stopped"); + _nextGear.SetState(absTime, disengaged: false, gear: 1, tcLocked: false); + return true; + } + + // DISENGAGE ------------------------------------------------------ + // 1) _ -> 0: disengage before halting + var braking = DataBus.DriverBehavior == DrivingBehavior.Braking; + var torqueNegative = outTorque.IsSmaller(0); + var slowerThanDisengageSpeed = + DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed); + var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed; + + // 2) L -> 0: disengage if inAngularVelocity == 0 + var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>()); + + // 3) 1C -> 0: disengange when negative T_out and positive T_in + var gear1C = gear == 1 && !_gearbox.TorqueConverterLocked; + var disengageTOutNegativeAndTInPositive = DataBus.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) && + inTorque.IsGreater(0); + + var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C && + inAngularVelocity.IsSmallerOrEqual(DataBus.EngineIdleSpeed); + + if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero || + disengageTOutNegativeAndTInPositive) { + _nextGear.SetState(absTime, disengaged: true, gear: 1, tcLocked: false); + return true; + } + + // EMERGENCY SHIFTS --------------------------------------- + if (CheckEmergencyShift(absTime, inAngularVelocity, gear)) { + return true; + } + + // UPSHIFT -------------------------------------------------------- + if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + lastShiftTime)) { + return true; + } + + // DOWNSHIFT ------------------------------------------------------ + if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + lastShiftTime)) { + return true; + } + + return false; + } + + private bool CheckEmergencyShift(Second absTime, PerSecond inAngularVelocity, uint gear) + { +// Emergency Downshift: if lower than engine idle speed + if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + Log.Debug("engine speed would fall below idle speed - shift down"); + Downshift(absTime, gear); + return true; + } + // Emergency Upshift: if higher than engine rated speed + if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) { + // check if upshift is possible + if (!ModelData.Gears.ContainsKey(gear + 1)) { + return false; + } + Log.Debug("engine speed would be above max speed / rated speed - shift up"); + Upshift(absTime, gear); + return true; + } + return false; + } + + [SuppressMessage("ReSharper", "UnusedParameter.Local")] + private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); + if (!shiftTimeReached) { + return false; + } + + var currentGear = ModelData.Gears[gear]; + + if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) { + var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear); + if (result.HasValue) { + return result.Value; + } + } + + // UPSHIFT - Special rule for 1C -> 2C + if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && + ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { + var result = CheckUpshiftTcTc(absTime, outTorque, outAngularVelocity, gear, currentGear); + if (result.HasValue) { + return result.Value; + } + } + return false; + } + + private bool? CheckUpshiftTcTc(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, uint gear, + GearData currentGear) + { +// C -> C+1 + var nextGear = ModelData.Gears[gear + 1]; + var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; + var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); + + var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; + var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; + var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed); + + var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); + + var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity); + var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration, + DataBus.DriverAcceleration); + var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); + + if (engineSpeedOverMin && minAccelerationReachable) { + Upshift(absTime, gear); + return true; + } + return null; + } + + private bool? CheckUpshiftToLocked(Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear) + { +// UPSHIFT - General Rule + // L -> L+1 + // C -> L + var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear; + if (!ModelData.Gears.ContainsKey(nextGear)) { + return false; + } + + var nextEngineSpeed = outAngularVelocity * ModelData.Gears[nextGear].Ratio; + if (nextEngineSpeed.IsEqual(0)) { + return false; + } + + var currentEnginePower = inTorque * inAngularVelocity; + var nextEngineTorque = currentEnginePower / nextEngineSpeed; + var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked); + + var minAccelerationReachable = true; + if (!DataBus.VehicleSpeed.IsEqual(0)) { + var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity); + var minAcceleration = _gearbox.TorqueConverterLocked + ? ModelData.UpshiftMinAcceleration + : ModelData.TorqueConverterData.CLUpshiftMinAcceleration; + minAcceleration = VectoMath.Min(minAcceleration, DataBus.DriverAcceleration); + minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); + } + + if (isAboveUpShift && minAccelerationReachable) { + Upshift(absTime, gear); + return true; + } + return null; + } + + /// <summary> + /// Tests if the operating point is above (right of) the up-shift curve. + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param> + /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> + private bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed, + bool torqueConverterLocked) + { + var shiftPolygon = torqueConverterLocked + ? ModelData.Gears[gear].ShiftPolygon + : ModelData.Gears[gear].TorqueConverterShiftPolygon; + + return gear < ModelData.Gears.Keys.Max() && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); + } + + private void Upshift(Second absTime, uint gear) + { + // C -> L: switch from torque converter to locked gear + if (!_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasLockedGear) { + _nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: true); + return; + } + + // L -> L+1 + // C -> C+1 + if (ModelData.Gears.ContainsKey(gear + 1)) { + _nextGear.SetState(absTime, disengaged: false, gear: gear + 1, tcLocked: _gearbox.TorqueConverterLocked); + return; + } + + // C -> L+1 -- not allowed!! + throw new VectoSimulationException( + "ShiftStrategy wanted to shift up, but current gear has active torque converter (C) but no locked gear (no L) and shifting directly to (L) is not allowed."); + } + + [SuppressMessage("ReSharper", "UnusedParameter.Local")] + private bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); + + if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) { + Downshift(absTime, gear); + return true; + } + + return false; + } + + /// <summary> + /// Tests if the operating point is below (left of) the down-shift curve. + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> + private bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + return gear > 1 && ModelData.Gears[gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); + } + + private void Downshift(Second absTime, uint gear) + { + // L -> C + if (_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasTorqueConverter) { + _nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: false); + return; + } + + // L -> L-1 + // C -> C-1 + if (ModelData.Gears.ContainsKey(gear - 1)) { + _nextGear.SetState(absTime, disengaged: false, gear: gear - 1, tcLocked: _gearbox.TorqueConverterLocked); + return; + } + + // L -> 0 -- not allowed!! + throw new VectoSimulationException( + "ShiftStrategy wanted to shift down but current gear is locked (L) and has no torque converter (C) and disenganging directly from (L) is not allowed."); + } + + private class NextGearState + { + public Second AbsTime; + public bool Disengaged; + public uint Gear; + public bool TorqueConverterLocked; + + public void SetState(Second absTime, bool disengaged, uint gear, bool tcLocked) + { + AbsTime = absTime; + Disengaged = disengaged; + Gear = gear; + TorqueConverterLocked = tcLocked; + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index 5af38c58dcdf83cf3998edb8dc7c978e5a7f423b..ab488ae867df7ec8734cc941d4dfe200d29b01fa 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -29,145 +29,152 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class Clutch : StatefulProviderComponent<Clutch.ClutchState, ITnOutPort, ITnInPort, ITnOutPort>, IClutch, - ITnOutPort, ITnInPort - { - private readonly PerSecond _idleSpeed; - private readonly PerSecond _ratedSpeed; - - public IIdleController IdleController { - get { return _idleController; } - set { - _idleController = value; - _idleController.RequestPort = NextComponent; - } - } - - private readonly SI _clutchSpeedSlippingFactor; - private IIdleController _idleController; - - public Clutch(IVehicleContainer container, CombustionEngineData engineData) : base(container) - { - _idleSpeed = engineData.IdleSpeed; - _ratedSpeed = engineData.FullLoadCurves[0].RatedSpeed; - _clutchSpeedSlippingFactor = Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed) / - (_idleSpeed + Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed)); - } - - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - NewtonMeter torqueIn; - PerSecond engineSpeedIn; - if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) { - engineSpeedIn = _idleSpeed; - torqueIn = 0.SI<NewtonMeter>(); - } else { - AddClutchLoss(outTorque, outAngularVelocity, true, out torqueIn, out engineSpeedIn); - } - PreviousState.SetState(torqueIn, outAngularVelocity, outTorque, outAngularVelocity); - - var retVal = NextComponent.Initialize(torqueIn, engineSpeedIn); - retVal.ClutchPowerRequest = outTorque * outAngularVelocity; - return retVal; - } - - public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); - if (!DataBus.ClutchClosed(absTime) && !dryRun) { - Log.Debug("Invoking IdleController..."); - var retval = IdleController.Request(absTime, dt, outTorque, null, dryRun); - retval.ClutchPowerRequest = 0.SI<Watt>(); - CurrentState.SetState(0.SI<NewtonMeter>(), retval.EngineSpeed, outTorque, outAngularVelocity); - CurrentState.ClutchLoss = 0.SI<Watt>(); - return retval; - } - if (IdleController != null) { - IdleController.Reset(); - } - - Log.Debug("from Wheels: torque: {0}, angularVelocity: {1}, power {2}", outTorque, outAngularVelocity, - Formulas.TorqueToPower(outTorque, outAngularVelocity)); - - NewtonMeter torqueIn; - PerSecond angularVelocityIn; - if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) { - angularVelocityIn = _idleSpeed; - torqueIn = 0.SI<NewtonMeter>(); - } else { - AddClutchLoss(outTorque, outAngularVelocity, (DataBus.Gear == 1 && outTorque > 0) ||startClutch || outAngularVelocity.IsEqual(0), out torqueIn, out angularVelocityIn); - } - Log.Debug("to Engine: torque: {0}, angularVelocity: {1}, power {2}", torqueIn, angularVelocityIn, - Formulas.TorqueToPower(torqueIn, angularVelocityIn)); - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var avgInAngularVelocity = (PreviousState.InAngularVelocity + angularVelocityIn) / 2.0; - var clutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity; - if (!startClutch && !clutchLoss.IsEqual(0)) { - // we don't want to have negative clutch losses, so adapt input torque to match the average output power - torqueIn = outTorque * avgOutAngularVelocity / avgInAngularVelocity; - } - - var retVal = NextComponent.Request(absTime, dt, torqueIn, angularVelocityIn, dryRun); - if (!dryRun) { - CurrentState.SetState(torqueIn, angularVelocityIn, outTorque, outAngularVelocity); - CurrentState.ClutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity; - } - retVal.ClutchPowerRequest = outTorque * - ((PreviousState.OutAngularVelocity ?? 0.SI<PerSecond>()) + CurrentState.OutAngularVelocity) / 2.0; - return retVal; - } - - private void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool startClutch, out NewtonMeter torqueIn, out PerSecond angularVelocityIn) - { - torqueIn = torque; - angularVelocityIn = angularVelocity; - - var engineSpeedNorm = (angularVelocity - _idleSpeed) / (_ratedSpeed - _idleSpeed); - if (startClutch && engineSpeedNorm < Constants.SimulationSettings.ClutchClosingSpeedNorm) { - // MQ: 27.5.2016: when angularVelocity is 0 (at the end of the simulation interval) don't use the - // angularVelocity but average angular velocity - // Reason: if angularVelocity = 0 also the power (torque * angularVelocity) is 0 and then - // the torque demand for the engine is 0. no drag torque although vehicle has to decelerate - // "the clutch" eats up the whole torque - var engineSpeed = VectoMath.Max(_idleSpeed, angularVelocity); - - angularVelocityIn = _clutchSpeedSlippingFactor * engineSpeed + _idleSpeed; - - } - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - if (PreviousState.InAngularVelocity == null || CurrentState.InAngularVelocity == null) { - container[ModalResultField.P_clutch_out] = 0.SI<Watt>(); - container[ModalResultField.P_clutch_loss] = 0.SI<Watt>(); - } else { - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - var avgInAngularVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - container[ModalResultField.P_clutch_out] = CurrentState.OutTorque * avgOutAngularVelocity; - container[ModalResultField.P_clutch_loss] = CurrentState.InTorque * avgInAngularVelocity - - CurrentState.OutTorque * avgOutAngularVelocity; - } - } - - public class ClutchState : SimpleComponentState - { - public Watt ClutchLoss = 0.SI<Watt>(); - } - } +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class Clutch : StatefulProviderComponent<Clutch.ClutchState, ITnOutPort, ITnInPort, ITnOutPort>, IClutch, + ITnOutPort, ITnInPort + { + private readonly PerSecond _idleSpeed; + private readonly PerSecond _ratedSpeed; + + public IIdleController IdleController + { + get { return _idleController; } + set + { + _idleController = value; + _idleController.RequestPort = NextComponent; + } + } + + private readonly SI _clutchSpeedSlippingFactor; + private IIdleController _idleController; + + public Clutch(IVehicleContainer container, CombustionEngineData engineData) : base(container) + { + _idleSpeed = engineData.IdleSpeed; + _ratedSpeed = engineData.FullLoadCurves[0].RatedSpeed; + _clutchSpeedSlippingFactor = Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed) / + (_idleSpeed + Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed)); + } + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + NewtonMeter torqueIn; + PerSecond engineSpeedIn; + if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) { + engineSpeedIn = _idleSpeed; + torqueIn = 0.SI<NewtonMeter>(); + } else { + AddClutchLoss(outTorque, outAngularVelocity, true, out torqueIn, out engineSpeedIn); + } + PreviousState.SetState(torqueIn, outAngularVelocity, outTorque, outAngularVelocity); + + var retVal = NextComponent.Initialize(torqueIn, engineSpeedIn); + retVal.ClutchPowerRequest = outTorque * outAngularVelocity; + return retVal; + } + + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); + if (!DataBus.ClutchClosed(absTime) && !dryRun) { + Log.Debug("Invoking IdleController..."); + var retval = IdleController.Request(absTime, dt, outTorque, null, dryRun); + retval.ClutchPowerRequest = 0.SI<Watt>(); + CurrentState.SetState(0.SI<NewtonMeter>(), retval.EngineSpeed, outTorque, outAngularVelocity); + CurrentState.ClutchLoss = 0.SI<Watt>(); + return retval; + } + if (IdleController != null) { + IdleController.Reset(); + } + + Log.Debug("from Wheels: torque: {0}, angularVelocity: {1}, power {2}", outTorque, outAngularVelocity, + Formulas.TorqueToPower(outTorque, outAngularVelocity)); + + NewtonMeter torqueIn; + PerSecond angularVelocityIn; + + AddClutchLoss(outTorque, outAngularVelocity, + (DataBus.Gear == 1 && outTorque > 0) || startClutch || outAngularVelocity.IsEqual(0), out torqueIn, + out angularVelocityIn); + + Log.Debug("to Engine: torque: {0}, angularVelocity: {1}, power {2}", torqueIn, angularVelocityIn, + Formulas.TorqueToPower(torqueIn, angularVelocityIn)); + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var avgInAngularVelocity = (PreviousState.InAngularVelocity + angularVelocityIn) / 2.0; + var clutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity; + if (!startClutch && !clutchLoss.IsEqual(0)) { + // we don't want to have negative clutch losses, so adapt input torque to match the average output power + torqueIn = outTorque * avgOutAngularVelocity / avgInAngularVelocity; + } + + var retVal = NextComponent.Request(absTime, dt, torqueIn, angularVelocityIn, dryRun); + if (!dryRun) { + CurrentState.SetState(torqueIn, angularVelocityIn, outTorque, outAngularVelocity); + CurrentState.ClutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity; + } + retVal.ClutchPowerRequest = outTorque * + ((PreviousState.OutAngularVelocity ?? 0.SI<PerSecond>()) + CurrentState.OutAngularVelocity) / 2.0; + return retVal; + } + + private void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool startClutch, out NewtonMeter torqueIn, + out PerSecond angularVelocityIn) + { + if (DataBus.DriverBehavior == DrivingBehavior.Halted) { + angularVelocityIn = _idleSpeed; + torqueIn = 0.SI<NewtonMeter>(); + return; + } + + torqueIn = torque; + angularVelocityIn = angularVelocity; + + var engineSpeedNorm = (angularVelocity - _idleSpeed) / (_ratedSpeed - _idleSpeed); + if (startClutch && engineSpeedNorm < Constants.SimulationSettings.ClutchClosingSpeedNorm) { + // MQ: 27.5.2016: when angularVelocity is 0 (at the end of the simulation interval) don't use the + // angularVelocity but average angular velocity + // Reason: if angularVelocity = 0 also the power (torque * angularVelocity) is 0 and then + // the torque demand for the engine is 0. no drag torque although vehicle has to decelerate + // "the clutch" eats up the whole torque + var engineSpeed = VectoMath.Max(_idleSpeed, angularVelocity); + + angularVelocityIn = _clutchSpeedSlippingFactor * engineSpeed + _idleSpeed; + } + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + if (PreviousState.InAngularVelocity == null || CurrentState.InAngularVelocity == null) { + container[ModalResultField.P_clutch_out] = 0.SI<Watt>(); + container[ModalResultField.P_clutch_loss] = 0.SI<Watt>(); + } else { + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + var avgInAngularVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + container[ModalResultField.P_clutch_out] = CurrentState.OutTorque * avgOutAngularVelocity; + container[ModalResultField.P_clutch_loss] = CurrentState.InTorque * avgInAngularVelocity - + CurrentState.OutTorque * avgOutAngularVelocity; + } + } + + public class ClutchState : SimpleComponentState + { + public Watt ClutchLoss = 0.SI<Watt>(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 2e17f9602e86bcbc7916ad2014d5dc44e21f13f1..02152d10f148ffa1f50bd06011d4a593f7cb2c18 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -175,9 +175,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // if the clutch disengages the idle controller should take over! throw new VectoSimulationException("angular velocity is null! Clutch open without IdleController?"); } - if (angularVelocity < ModelData.IdleSpeed.Value() - EngineIdleSpeedStopThreshold) { - CurrentState.OperationMode = EngineOperationMode.Stopped; - } + //if (angularVelocity < ModelData.IdleSpeed.Value() - EngineIdleSpeedStopThreshold) { + // CurrentState.OperationMode = EngineOperationMode.Stopped; + //} var avgEngineSpeed = (PreviousState.EngineSpeed + angularVelocity) / 2.0; @@ -192,9 +192,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fullDragTorque = ModelData.FullLoadCurves[DataBus.Gear].DragLoadStationaryTorque(avgEngineSpeed); var dynamicFullLoadPower = ComputeFullLoadPower(avgEngineSpeed, dt, dryRun); - if (dynamicFullLoadPower < 0) { - dynamicFullLoadPower = 0.SI<Watt>(); - } + var dynamicFullLoadTorque = dynamicFullLoadPower / avgEngineSpeed; var inertiaTorqueLoss = Formulas.InertiaPower(angularVelocity, PreviousState.EngineSpeed, ModelData.Inertia, dt) / @@ -459,6 +457,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl dynFullPowerCalculated = stationaryFullLoadPower; } + if (dynFullPowerCalculated < 0) { + return 0.SI<Watt>(); + } return dynFullPowerCalculated; } @@ -589,7 +590,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl angularSpeed = angularSpeed.LimitTo(_engine.ModelData.IdleSpeed, _engine.EngineRatedSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); + Default(r => { + throw new UnexpectedResponseException("searching Idling point", r); + }); return retVal; } @@ -646,7 +649,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl 0.SI<NewtonMeter>(), angularSpeed); retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed); }). - Default(r => { throw new UnexpectedResponseException("searching Idling point", r); }); + Default(r => { + throw new UnexpectedResponseException("searching Idling point", r); + }); return retVal; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs index 1b384fa2ae89ec89de42f3e24704ebded0ef4945..e3d6c3420179a779cf08ff9a5b570211edf9add7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -29,464 +29,478 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState> - { - /// <summary> - /// True if gearbox is disengaged (no gear is set). - /// </summary> - protected internal Second Disengaged; - - protected bool? TorqueConverterActive; - - protected internal readonly TorqueConverter TorqueConverter; - - public CycleGearbox(IVehicleContainer container, VectoRunData runData) - : base(container, runData) - { - if (!ModelData.Type.AutomaticTransmission()) { - return; - } - var strategy = new CycleShiftStrategy(ModelData, null); - TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData); - if (TorqueConverter == null) { - throw new VectoException("Torque Converter required for AT transmission!"); - } - } - - public override void Connect(ITnOutPort other) - { - base.Connect(other); - if (TorqueConverter != null) { - TorqueConverter.NextComponent = other; - } - } - - public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var dt = Constants.SimulationSettings.TargetTimeInterval; - - Gear = DataBus.CycleData.LeftSample.Gear; - TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive; - - if (TorqueConverter != null && TorqueConverterActive == null) { - throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); - } - - var inAngularVelocity = DataBus.EngineIdleSpeed; - var inTorque = 0.SI<NewtonMeter>(); - IResponse response; - - if (Gear != 0) { - inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); - CurrentState.TorqueLossResult = inTorqueLossResult; - inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value; - - var torqueLossInertia = outAngularVelocity.IsEqual(0) - ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / - inAngularVelocity; - - inTorque += torqueLossInertia; - - response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null - ? TorqueConverter.Initialize(inTorque, inAngularVelocity) - : NextComponent.Initialize(inTorque, inAngularVelocity); - } else { - response = NextComponent.Initialize(inTorque, inAngularVelocity); - } - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - PreviousState.Gear = Gear; - - response.GearboxPowerRequest = inTorque * inAngularVelocity; - return response; - } - - /// <summary> - /// Requests the Gearbox to deliver torque and angularVelocity - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><description>ResponseDryRun</description></item> - /// <item><description>ResponseOverload</description></item> - /// <item><description>ResponseGearshift</description></item> - /// </list> - /// </returns> - public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - var gear = GetGearFromCycle(); - - TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.TorqueConverterActive - : DataBus.CycleData.RightSample.TorqueConverterActive; - - if (TorqueConverter != null && TorqueConverterActive == null) { - throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); - } - if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) { - throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear); - } - - // mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run - // mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_* - var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted - //|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1)) - ? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun) - : RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - - retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; - return retVal; - } - - private uint GetGearFromCycle() - { - return DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.Gear - : DataBus.CycleData.RightSample.Gear; - } - - /// <summary> - /// Handles requests when a gear is engaged - /// </summary> - /// <param name="absTime"></param> - /// <param name="dt"></param> - /// <param name="outTorque"></param> - /// <param name="outAngularVelocity"></param> - /// <param name="dryRun"></param> - /// <returns></returns> - private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - Disengaged = null; - - Gear = GetGearFromCycle(); - - var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value; - - var effectiveRatio = ModelData.Gears[Gear].Ratio; - var effectiveLossMap = ModelData.Gears[Gear].LossMap; - if (!torqueConverterLocked) { - effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; - effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; - } - - if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) { - throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear, - torqueConverterLocked ? "L" : "C"); - } - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); - CurrentState.TorqueLossResult = inTorqueLossResult; - var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value; - CurrentState.TorqueLossResult = inTorqueLossResult; - - if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { - throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!"); - } - - var inAngularVelocity = outAngularVelocity * effectiveRatio; - - if (!inAngularVelocity.IsEqual(0)) { - // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side - CurrentState.InertiaTorqueLossOut = - Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity; - inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio; - } else { - CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - } - if (Gear != PreviousState.Gear && - ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) { - CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity); - } - if (CurrentState.PowershiftLosses != null) { - var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; - inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed; - } - if (dryRun) { - if (TorqueConverter != null && !torqueConverterLocked) { - return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true); - } - - var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); - dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - return dryRunResponse; - } - - CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; - - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.Gear = Gear; - // end critical section - - if (TorqueConverter != null && !torqueConverterLocked) { - CurrentState.TorqueConverterActive = true; - return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity); - } - - if (TorqueConverter != null) { - TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, - CurrentState.InAngularVelocity); - } - var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); - response.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - return response; - } - - /// <summary> - /// Handles Requests when no gear is disengaged - /// </summary> - /// <param name="absTime"></param> - /// <param name="dt"></param> - /// <param name="outTorque"></param> - /// <param name="outAngularVelocity"></param> - /// <param name="dryRun"></param> - /// <returns></returns> - private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - if (Disengaged == null) { - Disengaged = absTime; - } - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - if (dryRun) { - // if gearbox is disengaged the 0-line is the limit for drag and full load - return new ResponseDryRun { - Source = this, - GearboxPowerRequest = outTorque * avgOutAngularVelocity, - DeltaDragLoad = outTorque * avgOutAngularVelocity, - DeltaFullLoad = outTorque * avgOutAngularVelocity, - }; - } - - if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) && - !outAngularVelocity.IsEqual(0)) { - return new ResponseOverload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseUnderload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - IResponse disengagedResponse; - if (GearboxType.AutomaticTransmission()) { - disengagedResponse = EngineIdleRequest(absTime, dt); - } else { - disengagedResponse = NextGear.Gear > 0 - ? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), - outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio) - : EngineIdleRequest(absTime, dt); - } - if (TorqueConverter != null) { - if (DataBus.VehicleStopped) { - TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque, - outAngularVelocity); - } else { - TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque, - disengagedResponse.EngineSpeed); - } - } - disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity); - CurrentState.Gear = Gear; - - return disengagedResponse; - } - - private IResponse EngineIdleRequest(Second absTime, Second dt) - { - var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed); - if (disengagedResponse is ResponseSuccess) { - return disengagedResponse; - } - var motoringSpeed = DataBus.EngineSpeed; - if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) { - var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true); - try { - motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad, - Constants.SimulationSettings.EngineIdlingSearchInterval, - getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true), - criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value()); - } catch (VectoException) { - Log.Warn("CycleGearbox could not find motoring speed for disengaged state."); - } - motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed); - } - disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed); - return disengagedResponse; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear; - container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; - container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; - container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; - container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + - CurrentState.OutAngularVelocity) / 2.0; - container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; - - if (ModelData.Type.AutomaticTransmission()) { - container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive; - container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null - ? 0.SI<Watt>() - : CurrentState.PowershiftLosses * avgInAngularSpeed; - } - // torque converter fields are written by TorqueConverter (if present), called from Vehicle container - } - - protected override void DoCommitSimulationStep() - { - if (Gear != 0) { - if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { - Log.Warn( - "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); - if (DataBus.ExecutionMode == ExecutionMode.Declaration) { - throw new VectoException( - "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); - } - } - } - base.DoCommitSimulationStep(); - } - - #region ICluchInfo - - public override GearInfo NextGear - { - get { - if (Disengaged == null) { - return new GearInfo(Gear, !TorqueConverterActive ?? true); - } - var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); - var nextGear = 0u; - var torqueConverterLocked = false; - foreach (var entry in future) { - if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.Gear == 0) { - continue; - } - nextGear = entry.Gear; - torqueConverterLocked = !entry.TorqueConverterActive ?? false; - break; - } - return new GearInfo(nextGear, torqueConverterLocked); - } - } - - public override Second TractionInterruption - { - get { - if (Disengaged == null) { - return ModelData.TractionInterruption; - } - var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); - foreach (var entry in future) { - if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { - // vehicle is stopped, no next gear, engine should go to idle - break; - } - if (entry.Gear == 0) { - continue; - } - return entry.Time - Disengaged; - } - return ModelData.TractionInterruption; - } - } - - public override bool ClutchClosed(Second absTime) - { - return (DataBus.DriverBehavior == DrivingBehavior.Braking - ? DataBus.CycleData.LeftSample.Gear - : DataBus.CycleData.RightSample.Gear) != 0; - } - - #endregion - - public class CycleGearboxState : GearboxState - { - public bool TorqueConverterActive; - public WattSecond PowershiftLosses { get; set; } - } - - public class CycleShiftStrategy : BaseShiftStrategy - { - public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} - - public override IGearbox Gearbox { get; set; } - - public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, - PerSecond inAngularVelocity, uint gear, Second lastShiftTime) - { - return false; - } - - public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) - { - throw new System.NotImplementedException(); - } - - public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - throw new System.NotImplementedException(); - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) - { - throw new System.NotImplementedException(); - } - - public override GearInfo NextGear - { - get { throw new System.NotImplementedException(); } - } - } - } +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState> + { + /// <summary> + /// True if gearbox is disengaged (no gear is set). + /// </summary> + protected internal Second Disengaged; + + protected bool? TorqueConverterActive; + + protected internal readonly TorqueConverter TorqueConverter; + + public CycleGearbox(IVehicleContainer container, VectoRunData runData) + : base(container, runData) + { + if (!ModelData.Type.AutomaticTransmission()) { + return; + } + var strategy = new CycleShiftStrategy(ModelData, null); + TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData); + if (TorqueConverter == null) { + throw new VectoException("Torque Converter required for AT transmission!"); + } + } + + public override void Connect(ITnOutPort other) + { + base.Connect(other); + if (TorqueConverter != null) { + TorqueConverter.NextComponent = other; + } + } + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var dt = Constants.SimulationSettings.TargetTimeInterval; + + Gear = DataBus.CycleData.LeftSample.Gear; + TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive; + + if (TorqueConverter != null && TorqueConverterActive == null) { + throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); + } + + var inAngularVelocity = DataBus.EngineIdleSpeed; + var inTorque = 0.SI<NewtonMeter>(); + IResponse response; + + if (Gear != 0) { + inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); + CurrentState.TorqueLossResult = inTorqueLossResult; + inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value; + + var torqueLossInertia = outAngularVelocity.IsEqual(0) + ? 0.SI<NewtonMeter>() + : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / + inAngularVelocity; + + inTorque += torqueLossInertia; + + response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null + ? TorqueConverter.Initialize(inTorque, inAngularVelocity) + : NextComponent.Initialize(inTorque, inAngularVelocity); + } else { + response = NextComponent.Initialize(inTorque, inAngularVelocity); + } + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + PreviousState.Gear = Gear; + + response.GearboxPowerRequest = inTorque * inAngularVelocity; + return response; + } + + /// <summary> + /// Requests the Gearbox to deliver torque and angularVelocity + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><description>ResponseDryRun</description></item> + /// <item><description>ResponseOverload</description></item> + /// <item><description>ResponseGearshift</description></item> + /// </list> + /// </returns> + public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); + var gear = GetGearFromCycle(); + + TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.TorqueConverterActive + : DataBus.CycleData.RightSample.TorqueConverterActive; + + if (TorqueConverter != null && TorqueConverterActive == null) { + throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!"); + } + if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) { + throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear); + } + + // mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run + // mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_* + var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted + //|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1)) + ? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun) + : RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + + retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; + return retVal; + } + + private uint GetGearFromCycle() + { + return DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.Gear + : DataBus.CycleData.RightSample.Gear; + } + + /// <summary> + /// Handles requests when a gear is engaged + /// </summary> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="outTorque"></param> + /// <param name="outAngularVelocity"></param> + /// <param name="dryRun"></param> + /// <returns></returns> + private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + Disengaged = null; + + Gear = GetGearFromCycle(); + + var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value; + + var effectiveRatio = ModelData.Gears[Gear].Ratio; + var effectiveLossMap = ModelData.Gears[Gear].LossMap; + if (!torqueConverterLocked) { + effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio; + effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap; + } + + CheckModelData(effectiveLossMap, effectiveRatio, torqueConverterLocked); + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); + CurrentState.TorqueLossResult = inTorqueLossResult; + var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value; + CurrentState.TorqueLossResult = inTorqueLossResult; + var inAngularVelocity = outAngularVelocity * effectiveRatio; + + CurrentState.InertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) + ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity + : 0.SI<NewtonMeter>(); + inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio; + if (Gear != PreviousState.Gear && + ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) { + CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity); + } + if (CurrentState.PowershiftLosses != null) { + var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2; + inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed; + } + if (dryRun) { + var dryRunResponse = HandleDryRunRequest(absTime, dt, torqueConverterLocked, inTorque, inAngularVelocity); + dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return dryRunResponse; + } + + CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque; + + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + // end critical section + + if (TorqueConverter != null && !torqueConverterLocked) { + CurrentState.TorqueConverterActive = true; + return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity); + } + + if (TorqueConverter != null) { + TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque, + CurrentState.InAngularVelocity); + } + var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); + response.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return response; + } + + private void CheckModelData(TransmissionLossMap effectiveLossMap, double effectiveRatio, bool torqueConverterLocked) + { + if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) { + throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear, + torqueConverterLocked ? "L" : "C"); + } + if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) { + throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!"); + } + } + + private IResponse HandleDryRunRequest(Second absTime, Second dt, bool torqueConverterLocked, NewtonMeter inTorque, + PerSecond inAngularVelocity) + { + if (TorqueConverter != null && !torqueConverterLocked) { + return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true); + } + // mk 2016-12-13 + //if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + // //Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear, + // // DataBus.VehicleSpeed); + // Gear = 0; + // return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + //} + return NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); + } + + /// <summary> + /// Handles Requests when no gear is disengaged + /// </summary> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="outTorque"></param> + /// <param name="outAngularVelocity"></param> + /// <param name="dryRun"></param> + /// <returns></returns> + private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + if (Disengaged == null) { + Disengaged = absTime; + } + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + if (dryRun) { + // if gearbox is disengaged the 0-line is the limit for drag and full load + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = outTorque * avgOutAngularVelocity, + DeltaDragLoad = outTorque * avgOutAngularVelocity, + DeltaFullLoad = outTorque * avgOutAngularVelocity, + }; + } + + if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) && + !outAngularVelocity.IsEqual(0)) { + return new ResponseOverload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseUnderload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + IResponse disengagedResponse; + if (GearboxType.AutomaticTransmission()) { + disengagedResponse = EngineIdleRequest(absTime, dt); + } else { + disengagedResponse = NextGear.Gear > 0 + ? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), + outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio) + : EngineIdleRequest(absTime, dt); + } + if (TorqueConverter != null) { + if (DataBus.VehicleStopped) { + TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque, + outAngularVelocity); + } else { + TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque, + disengagedResponse.EngineSpeed); + } + } + disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity); + CurrentState.Gear = Gear; + + return disengagedResponse; + } + + private IResponse EngineIdleRequest(Second absTime, Second dt) + { + var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed); + if (disengagedResponse is ResponseSuccess) { + return disengagedResponse; + } + var motoringSpeed = DataBus.EngineSpeed; + if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) { + var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true); + try { + motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad, + Constants.SimulationSettings.EngineIdlingSearchInterval, + getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, + evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true), + criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value()); + } catch (VectoException) { + Log.Warn("CycleGearbox could not find motoring speed for disengaged state."); + } + motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed); + } + disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed); + return disengagedResponse; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear; + container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; + container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; + container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; + container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + + CurrentState.OutAngularVelocity) / 2.0; + container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; + + if (ModelData.Type.AutomaticTransmission()) { + container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive; + container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null + ? 0.SI<Watt>() + : CurrentState.PowershiftLosses * avgInAngularSpeed; + } + // torque converter fields are written by TorqueConverter (if present), called from Vehicle container + } + + protected override void DoCommitSimulationStep() + { + if (Gear != 0) { + if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { + Log.Warn( + "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); + if (DataBus.ExecutionMode == ExecutionMode.Declaration) { + throw new VectoException( + "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque); + } + } + } + base.DoCommitSimulationStep(); + } + + #region ICluchInfo + + public override GearInfo NextGear + { + get + { + if (Disengaged == null) { + return new GearInfo(Gear, !TorqueConverterActive ?? true); + } + var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); + var nextGear = 0u; + var torqueConverterLocked = false; + foreach (var entry in future) { + if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.Gear == 0) { + continue; + } + nextGear = entry.Gear; + torqueConverterLocked = !entry.TorqueConverterActive ?? false; + break; + } + return new GearInfo(nextGear, torqueConverterLocked); + } + } + + public override Second TractionInterruption + { + get + { + if (Disengaged == null) { + return ModelData.TractionInterruption; + } + var future = DataBus.LookAhead(ModelData.TractionInterruption * 5); + foreach (var entry in future) { + if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) { + // vehicle is stopped, no next gear, engine should go to idle + break; + } + if (entry.Gear == 0) { + continue; + } + return entry.Time - Disengaged; + } + return ModelData.TractionInterruption; + } + } + + public override bool ClutchClosed(Second absTime) + { + return (DataBus.DriverBehavior == DrivingBehavior.Braking + ? DataBus.CycleData.LeftSample.Gear + : DataBus.CycleData.RightSample.Gear) != 0; + } + + #endregion + + public class CycleGearboxState : GearboxState + { + public bool TorqueConverterActive; + public WattSecond PowershiftLosses { get; set; } + } + + public class CycleShiftStrategy : BaseShiftStrategy + { + public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {} + + public override IGearbox Gearbox { get; set; } + + public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime) + { + return false; + } + + public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException(); + } + + public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException(); + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) + { + throw new System.NotImplementedException(); + } + + public override GearInfo NextGear + { + get { throw new System.NotImplementedException(); } + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 1145e04f6ee00cd3978352618cf2db0f19f0d332..ef9a330dd311e476ccfb5f151d7e5331f3416a22 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; @@ -130,42 +131,52 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } else { // update action distance for current 'next action' - if (Driver.DataBus.VehicleSpeed > NextDrivingAction.NextTargetSpeed) { - var brakingDistance = Driver.ComputeDecelerationDistance(NextDrivingAction.NextTargetSpeed) + BrakingSafetyMargin; - switch (NextDrivingAction.Action) { - case DrivingBehavior.Coasting: - //var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.NextTargetSpeed); - var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.CycleEntry); - NextDrivingAction.CoastingStartDistance = NextDrivingAction.TriggerDistance - coastingDistance; - NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance; - break; - case DrivingBehavior.Braking: - NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance; - NextDrivingAction.CoastingStartDistance = double.MaxValue.SI<Meter>(); - break; - default: - throw new ArgumentOutOfRangeException(); - } - } + UpdateDistancesForCurrentNextAction(); - if (nextAction != null) { - if (nextAction.HasEqualTrigger(NextDrivingAction)) { - // if the action changes and the vehicle has not yet exceeded the action distance => update the action - // otherwise do nothing, NextDrivingAction's action distance has already been updated - if (nextAction.Action != NextDrivingAction.Action && nextAction.ActionDistance > currentDistance) { - NextDrivingAction = nextAction; - } - } else { - // hmm, we've got a new action that is closer to what we got before? - if (nextAction.ActionDistance < NextDrivingAction.ActionDistance) { - NextDrivingAction = nextAction; - } + SetNextDrivingAction(currentDistance, nextAction); + } + Log.Debug("Next Driving Action: {0}", NextDrivingAction); + } + + private void SetNextDrivingAction(Meter currentDistance, DrivingBehaviorEntry nextAction) + { + if (nextAction != null) { + if (nextAction.HasEqualTrigger(NextDrivingAction)) { + // if the action changes and the vehicle has not yet exceeded the action distance => update the action + // otherwise do nothing, NextDrivingAction's action distance has already been updated + if (nextAction.Action != NextDrivingAction.Action && nextAction.ActionDistance > currentDistance) { + NextDrivingAction = nextAction; } } else { - NextDrivingAction = null; + // hmm, we've got a new action that is closer to what we got before? + if (nextAction.ActionDistance < NextDrivingAction.ActionDistance) { + NextDrivingAction = nextAction; + } + } + } else { + NextDrivingAction = null; + } + } + + private void UpdateDistancesForCurrentNextAction() + { + if (Driver.DataBus.VehicleSpeed > NextDrivingAction.NextTargetSpeed) { + var brakingDistance = Driver.ComputeDecelerationDistance(NextDrivingAction.NextTargetSpeed) + BrakingSafetyMargin; + switch (NextDrivingAction.Action) { + case DrivingBehavior.Coasting: + //var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.NextTargetSpeed); + var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.CycleEntry); + NextDrivingAction.CoastingStartDistance = NextDrivingAction.TriggerDistance - coastingDistance; + NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance; + break; + case DrivingBehavior.Braking: + NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance; + NextDrivingAction.CoastingStartDistance = double.MaxValue.SI<Meter>(); + break; + default: + throw new ArgumentOutOfRangeException(); } } - Log.Debug("Next Driving Action: {0}", NextDrivingAction); } protected internal DrivingBehaviorEntry GetNextDrivingAction(Meter ds) @@ -184,51 +195,58 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var nextTargetSpeed = OverspeedAllowed(entry.VehicleTargetSpeed) ? entry.VehicleTargetSpeed + Driver.DriverData.OverSpeedEcoRoll.OverSpeed : entry.VehicleTargetSpeed; - if (nextTargetSpeed < currentSpeed) { - var action = DrivingBehavior.Braking; - var coastingDistance = ComputeCoastingDistance(currentSpeed, entry); - var brakingDistance = Driver.ComputeDecelerationDistance(nextTargetSpeed) + BrakingSafetyMargin; - - if (!Driver.DriverData.LookAheadCoasting.Enabled || coastingDistance < 0) { - Log.Debug( - "adding 'Braking' starting at distance {0}. brakingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}", - entry.Distance - brakingDistance, brakingDistance, entry.Distance, nextTargetSpeed); - coastingDistance = brakingDistance; - } else { - //var coastingDistance = ComputeCoastingDistance(currentSpeed, nextTargetSpeed); - if (currentSpeed > Driver.DriverData.LookAheadCoasting.MinSpeed) { - action = DrivingBehavior.Coasting; - - Log.Debug( - "adding 'Coasting' starting at distance {0}. coastingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}", - entry.Distance - coastingDistance, coastingDistance, entry.Distance, nextTargetSpeed); - } else { - coastingDistance = -1.SI<Meter>(); - } - } - nextActions.Add( - new DrivingBehaviorEntry { - Action = action, - CoastingStartDistance = entry.Distance - coastingDistance, - BrakingStartDistance = entry.Distance - brakingDistance, - TriggerDistance = entry.Distance, - NextTargetSpeed = nextTargetSpeed, - CycleEntry = entry, - }); + if (nextTargetSpeed >= currentSpeed) { + // acceleration is not relevant + continue; } + nextActions.Add(GetDrivingBehaviorEntry(nextTargetSpeed, currentSpeed, entry)); } if (!nextActions.Any()) { return null; } var nextBrakingAction = nextActions.OrderBy(x => x.BrakingStartDistance).First(); var nextCoastingAction = nextActions.OrderBy(x => x.CoastingStartDistance).First(); - if (nextBrakingAction.TriggerDistance.IsEqual(nextCoastingAction.TriggerDistance)) { - // its the same trigger, use it - return nextCoastingAction; - } + + return nextBrakingAction.TriggerDistance.IsEqual(nextCoastingAction.TriggerDistance) + ? nextCoastingAction + : nextBrakingAction; // MQ: 27.5.2016 remark: one could set the coasting distance to the closest coasting distance as found above to start coasting a little bit earlier. - return nextBrakingAction; + } + + private DrivingBehaviorEntry GetDrivingBehaviorEntry(MeterPerSecond nextTargetSpeed, MeterPerSecond currentSpeed, + DrivingCycleData.DrivingCycleEntry entry) + { + var action = DrivingBehavior.Braking; + + var brakingDistance = Driver.ComputeDecelerationDistance(nextTargetSpeed) + BrakingSafetyMargin; + var coastingDistance = ComputeCoastingDistance(currentSpeed, entry); + if (!Driver.DriverData.LookAheadCoasting.Enabled || coastingDistance < 0) { + Log.Debug( + "adding 'Braking' starting at distance {0}. brakingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}", + entry.Distance - brakingDistance, brakingDistance, entry.Distance, nextTargetSpeed); + coastingDistance = brakingDistance; + } else { + //var coastingDistance = ComputeCoastingDistance(currentSpeed, nextTargetSpeed); + if (currentSpeed > Driver.DriverData.LookAheadCoasting.MinSpeed) { + action = DrivingBehavior.Coasting; + + Log.Debug( + "adding 'Coasting' starting at distance {0}. coastingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}", + entry.Distance - coastingDistance, coastingDistance, entry.Distance, nextTargetSpeed); + } else { + coastingDistance = -1.SI<Meter>(); + } + } + var nextEntry = new DrivingBehaviorEntry { + Action = action, + CoastingStartDistance = entry.Distance - coastingDistance, + BrakingStartDistance = entry.Distance - brakingDistance, + TriggerDistance = entry.Distance, + NextTargetSpeed = nextTargetSpeed, + CycleEntry = entry, + }; + return nextEntry; } protected internal virtual Meter ComputeCoastingDistance(MeterPerSecond vehicleSpeed, @@ -383,95 +401,122 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl velocity += DriverData.OverSpeedEcoRoll.OverSpeed; } if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - // drive along - IResponse first; - if (DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed) && - DataBus.VehicleSpeed.IsEqual(targetVelocity)) { - first = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); - debug.Add(new { action = "Coast", first }); - if (first is ResponseSuccess && first.Acceleration < 0) { - first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); - debug.Add(new { action = "Coast:(Success & Acc<0) -> Accelerate", first }); - } - } else { - first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); - debug.Add(new { action = "Accelerate", first }); - } + return HandleRequestEngaged(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug); + } else { + return HandleRequestDisengaged(absTime, ds, gradient, velocity, debug); + } + } - var second = first; - first.Switch(). - Case<ResponseUnderload>(r => { - if (DataBus.VehicleSpeed.IsGreater(0) && DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed)) { - second = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); - debug.Add(new { action = "first:(Underload & Overspeed)-> Coast", second }); - if (second is ResponseUnderload || second is ResponseSpeedLimitExceeded) { - second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); - debug.Add(new { - action = "second:(Underload|SpeedLimitExceeded) -> Brake", - second - }); - } - if (second is ResponseEngineSpeedTooHigh) { - second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, second); - debug.Add(new { - action = "second:(EngineSpeedTooHigh|SpeedLimitExceeded) -> Brake with reduced acceleration", - second - }); - } - } else { - second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); - debug.Add(new { action = "first:(Underload & !Overspeed) -> Brake", second }); - } - }); - - var third = second; - - second.Switch(). - Case<ResponseGearShift>(r => { - third = Driver.DrivingActionRoll(absTime, ds, velocity, gradient); - debug.Add(new { action = "second: GearShift -> Roll", third }); - third.Switch(). - Case<ResponseUnderload>(() => { - // overload may happen if driver limits acceleration when rolling downhill - third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); - debug.Add(new { action = "third:Underload -> Brake", third }); - }). - Case<ResponseSpeedLimitExceeded>(() => { - third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); - debug.Add(new { action = "third:SpeedLimitExceeded -> Brake", third }); - }); - }). - Case<ResponseOverload>(r => { - third = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); - debug.Add(new { action = "second:Overload -> Coast", third }); - }); + private IResponse HandleRequestDisengaged(Second absTime, Meter ds, Radian gradient, MeterPerSecond velocity, + DebugData debug) + { + if (DataBus.VehicleSpeed.IsSmallerOrEqual(0.SI<MeterPerSecond>())) { + // the clutch is disengaged, and the vehicle stopped - we can't perform a roll action. wait for the clutch to be engaged + // todo mk 2016-08-23: is this still needed? + var remainingShiftTime = Constants.SimulationSettings.TargetTimeInterval; + while (!DataBus.ClutchClosed(absTime + remainingShiftTime)) { + remainingShiftTime += Constants.SimulationSettings.TargetTimeInterval; + } + return new ResponseFailTimeInterval { + Source = this, + DeltaT = remainingShiftTime, + }; + } + var response = Driver.DrivingActionRoll(absTime, ds, velocity, gradient); + debug.Add(new { action = "ClutchOpen -> Roll", response }); + response.Switch(). + Case<ResponseUnderload>(r => { + response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, r); + debug.Add(new { action = "Roll:Underload -> Brake", response }); + }) + .Case<ResponseSpeedLimitExceeded>(() => { + response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); + debug.Add(new { action = "Roll:SpeedLimitExceeded -> Brake", response }); + }); + return response; + } - return third; - } else { - if (DataBus.VehicleSpeed.IsSmallerOrEqual(0.SI<MeterPerSecond>())) { - // the clutch is disengaged, and the vehicle stopped - we can't perform a roll action. wait for the clutch to be engaged - var remainingShiftTime = Constants.SimulationSettings.TargetTimeInterval; - while (!DataBus.ClutchClosed(absTime + remainingShiftTime)) { - remainingShiftTime += Constants.SimulationSettings.TargetTimeInterval; + private IResponse HandleRequestEngaged(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, + bool prohibitOverspeed, MeterPerSecond velocity, DebugData debug) + { + // drive along + var first = FirstAccelerateOrCoast(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug); + + var second = first; + first.Switch(). + Case<ResponseUnderload>(r => { + if (DataBus.VehicleSpeed.IsGreater(0) && DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed)) { + second = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); + debug.Add(new { action = "first:(Underload & Overspeed)-> Coast", second }); + second = HandleCoastAfterUnderloadWithOverspeed(absTime, ds, gradient, velocity, debug, second); + } else { + second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); + debug.Add(new { action = "first:(Underload & !Overspeed) -> Brake", second }); } - return new ResponseFailTimeInterval { - Source = this, - DeltaT = remainingShiftTime, - }; + }); + + var third = second; + + second.Switch(). + Case<ResponseGearShift>(r => { + third = Driver.DrivingActionRoll(absTime, ds, velocity, gradient); + debug.Add(new { action = "second: GearShift -> Roll", third }); + third.Switch(). + Case<ResponseUnderload>(() => { + // overload may happen if driver limits acceleration when rolling downhill + third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); + debug.Add(new { action = "third:Underload -> Brake", third }); + }). + Case<ResponseSpeedLimitExceeded>(() => { + third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); + debug.Add(new { action = "third:SpeedLimitExceeded -> Brake", third }); + }); + }). + Case<ResponseOverload>(r => { + third = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); + debug.Add(new { action = "second:Overload -> Coast", third }); + }); + + return third; + } + + private IResponse HandleCoastAfterUnderloadWithOverspeed(Second absTime, Meter ds, Radian gradient, + MeterPerSecond velocity, DebugData debug, IResponse second) + { + if (second is ResponseUnderload || second is ResponseSpeedLimitExceeded) { + second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); + debug.Add(new { + action = "second:(Underload|SpeedLimitExceeded) -> Brake", + second + }); + } + if (second is ResponseEngineSpeedTooHigh) { + second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, second); + debug.Add(new { + action = "second:(EngineSpeedTooHigh|SpeedLimitExceeded) -> Brake with reduced acceleration", + second + }); + } + return second; + } + + private IResponse FirstAccelerateOrCoast(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, + bool prohibitOverspeed, MeterPerSecond velocity, DebugData debug) + { + IResponse first; + if (DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed) && + DataBus.VehicleSpeed.IsEqual(targetVelocity)) { + first = Driver.DrivingActionCoast(absTime, ds, velocity, gradient); + debug.Add(new { action = "Coast", first }); + if (first is ResponseSuccess && first.Acceleration < 0) { + first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + debug.Add(new { action = "Coast:(Success & Acc<0) -> Accelerate", first }); } - var response = Driver.DrivingActionRoll(absTime, ds, velocity, gradient); - debug.Add(new { action = "ClutchOpen -> Roll", response }); - response.Switch(). - Case<ResponseUnderload>(r => { - response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, r); - debug.Add(new { action = "Roll:Underload -> Brake", response }); - }) - .Case<ResponseSpeedLimitExceeded>(() => { - response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient); - debug.Add(new { action = "Roll:SpeedLimitExceeded -> Brake", response }); - }); - return response; + } else { + first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + debug.Add(new { action = "Accelerate", first }); } + return first; } protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds, @@ -535,7 +580,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected override IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, bool prohibitOverspeed = false) { - IResponse response = null; if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) { return HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); } @@ -545,136 +589,218 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DefaultDriverStrategy.BrakingSafetyMargin; DriverStrategy.BrakeTrigger.BrakingStartDistance = DriverStrategy.BrakeTrigger.TriggerDistance - brakingDistance; if (Phase == BrakingPhase.Coast) { - var nextBrakeAction = DriverStrategy.GetNextDrivingAction(ds); - if (nextBrakeAction != null && !DriverStrategy.BrakeTrigger.TriggerDistance.IsEqual(nextBrakeAction.TriggerDistance) && - nextBrakeAction.BrakingStartDistance.IsSmaller(DriverStrategy.BrakeTrigger.BrakingStartDistance)) { - DriverStrategy.BrakeTrigger = nextBrakeAction; - Log.Debug("setting brake trigger to new trigger: trigger distance: {0}, start braking @ {1}", - nextBrakeAction.TriggerDistance, nextBrakeAction.BrakingStartDistance); - } - - Log.Debug("start braking @ {0}", DriverStrategy.BrakeTrigger.BrakingStartDistance); - var remainingDistanceToBrake = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance; - var estimatedTimeInterval = remainingDistanceToBrake / DataBus.VehicleSpeed; - if (estimatedTimeInterval.IsSmaller(Constants.SimulationSettings.LowerBoundTimeInterval) || - currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance > - DriverStrategy.BrakeTrigger.BrakingStartDistance) { - Phase = BrakingPhase.Brake; - Log.Debug("Switching to BRAKE Phase. currentDistance: {0}", currentDistance); - } else { - if ((currentDistance + ds).IsGreater(DriverStrategy.BrakeTrigger.BrakingStartDistance)) { - return new ResponseDrivingCycleDistanceExceeded() { - //Source = this, - MaxDistance = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance - }; - } - } - if (DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast) { - Phase = BrakingPhase.Brake; - Log.Debug("Switching to BRAKE Phase. currentDistance: {0} v: {1}", currentDistance, - DataBus.VehicleSpeed); + var resp = CheckSwitchingToBraking(ds, currentDistance); + if (resp != null) { + return resp; } } switch (Phase) { case BrakingPhase.Coast: - Driver.DriverBehavior = DrivingBehavior.Coasting; + return DoCoast(absTime, ds, targetVelocity, gradient, currentDistance); + case BrakingPhase.Brake: + return DoBrake(absTime, ds, targetVelocity, gradient, brakingDistance, currentDistance); + default: + throw new VectoException("Invalid Phase in DriverModeBrake"); + } + } + + private IResponse DoBrake(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, + Meter brakingDistance, Meter currentDistance) + { + IResponse response; + Log.Debug("Phase: BRAKE. breaking distance: {0} start braking @ {1}", brakingDistance, + DriverStrategy.BrakeTrigger.BrakingStartDistance); + if (DriverStrategy.BrakeTrigger.BrakingStartDistance.IsSmaller(currentDistance, + Constants.SimulationSettings.DriverActionDistanceTolerance / 2)) { + Log.Info("Expected Braking Deceleration could not be reached! {0}", + DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance); + } + var targetDistance = DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast + ? DriverStrategy.BrakeTrigger.TriggerDistance + : null; + if (targetDistance == null && DriverStrategy.BrakeTrigger.NextTargetSpeed.IsEqual(0.SI<MeterPerSecond>())) { + targetDistance = DriverStrategy.BrakeTrigger.TriggerDistance - DefaultDriverStrategy.BrakingSafetyMargin; + } + Driver.DriverBehavior = DrivingBehavior.Braking; + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, targetDistance: targetDistance); + response.Switch(). + Case<ResponseOverload>(r => { + Log.Info( + "Brake -> Got OverloadResponse during brake action - desired deceleration could not be reached! response: {0}", + r); + if (!DataBus.ClutchClosed(absTime)) { + Log.Info("Brake -> Overload -> Clutch is open - Trying roll action"); + response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); + } else { + Log.Info("Brake -> Overload -> Clutch is closed - Trying brake action again"); + DataBus.BrakePower = 0.SI<Watt>(); + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient, + targetDistance: targetDistance); + response.Switch(). + Case<ResponseOverload>(r1 => { + Log.Info("Brake -> Overload -> 2nd Brake -> Overload -> Trying accelerate action"); + response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + response.Switch().Case<ResponseGearShift>( + rs => { + Log.Info("Brake -> Overload -> 2nd Brake -> Accelerate -> Got GearShift response, performing roll action"); + response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + }); + }); + } + }). + Case<ResponseGearShift>(r => { + Log.Info("Brake -> Got GearShift response, performing roll action + brakes"); + //response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + DataBus.BrakePower = 0.SI<Watt>(); + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, targetDistance: targetDistance); + }); + return response; + } + + private IResponse DoCoast(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, + Meter currentDistance) + { + IResponse response; + Driver.DriverBehavior = DrivingBehavior.Coasting; + response = DataBus.ClutchClosed(absTime) + ? Driver.DrivingActionCoast(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient) + : Driver.DrivingActionRoll(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient); + response.Switch(). + Case<ResponseUnderload>(r => { + // coast would decelerate more than driver's max deceleration => issue brakes to decelerate with driver's max deceleration + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, r); + if ((DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance).IsSmallerOrEqual( + Constants.SimulationSettings.DriverActionDistanceTolerance)) { + Phase = BrakingPhase.Brake; + } + }). + Case<ResponseOverload>(r => { + // limiting deceleration while coast may result in an overload => issue brakes to decelerate with driver's max deceleration response = DataBus.ClutchClosed(absTime) - ? Driver.DrivingActionCoast(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient) - : Driver.DrivingActionRoll(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient); + ? Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient) + : Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); + //Phase = BrakingPhase.Brake; + }). + Case<ResponseDrivingCycleDistanceExceeded>(r => { + if (!ds.IsEqual(r.MaxDistance)) { + // distance has been reduced due to vehicle stop in coast/roll action => use brake action to get exactly to the stop-distance + // TODO what if no gear is enaged (and we need driveline power to get to the stop-distance? + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } + }). + Case<ResponseGearShift>(r => { + response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); + }). + Case<ResponseEngineSpeedTooHigh>(r => { + response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r); + }); + // handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try + response.Switch(). + Case<ResponseSpeedLimitExceeded>(() => { + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, + gradient); + if (response is ResponseOverload && !DataBus.ClutchClosed(absTime)) { + response = Driver.DrivingActionRoll(absTime, ds, DataBus.VehicleSpeed, gradient); + } + }); + return response; + } + + private IResponse CheckSwitchingToBraking(Meter ds, Meter currentDistance) + { + var nextBrakeAction = DriverStrategy.GetNextDrivingAction(ds); + if (nextBrakeAction != null && !DriverStrategy.BrakeTrigger.TriggerDistance.IsEqual(nextBrakeAction.TriggerDistance) && + nextBrakeAction.BrakingStartDistance.IsSmaller(DriverStrategy.BrakeTrigger.BrakingStartDistance)) { + DriverStrategy.BrakeTrigger = nextBrakeAction; + Log.Debug("setting brake trigger to new trigger: trigger distance: {0}, start braking @ {1}", + nextBrakeAction.TriggerDistance, nextBrakeAction.BrakingStartDistance); + } + + Log.Debug("start braking @ {0}", DriverStrategy.BrakeTrigger.BrakingStartDistance); + var remainingDistanceToBrake = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance; + var estimatedTimeInterval = remainingDistanceToBrake / DataBus.VehicleSpeed; + if (estimatedTimeInterval.IsSmaller(Constants.SimulationSettings.LowerBoundTimeInterval) || + currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance > + DriverStrategy.BrakeTrigger.BrakingStartDistance) { + Phase = BrakingPhase.Brake; + Log.Debug("Switching to BRAKE Phase. currentDistance: {0}", currentDistance); + } else { + if ((currentDistance + ds).IsGreater(DriverStrategy.BrakeTrigger.BrakingStartDistance)) { + return new ResponseDrivingCycleDistanceExceeded() { + //Source = this, + MaxDistance = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance + }; + } + } + if (DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast) { + Phase = BrakingPhase.Brake; + Log.Debug("Switching to BRAKE Phase. currentDistance: {0} v: {1}", currentDistance, + DataBus.VehicleSpeed); + } + return null; + } + + private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + var response = TargetSpeedReachedDriveAlong(absTime, ds, targetVelocity, gradient); + //var i = 0; + //do { + response.Switch(). + Case<ResponseGearShift>(() => { + response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); response.Switch(). Case<ResponseUnderload>(r => { - // coast would decelerate more than driver's max deceleration => issue brakes to decelerate with driver's max deceleration + // under-load may happen if driver limits acceleration when rolling downhill response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient, r); - if ((DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance).IsSmallerOrEqual( - Constants.SimulationSettings.DriverActionDistanceTolerance)) { - Phase = BrakingPhase.Brake; - } - }). - Case<ResponseOverload>(r => { - // limiting deceleration while coast may result in an overload => issue brakes to decelerate with driver's max deceleration - response = DataBus.ClutchClosed(absTime) - ? Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient) - : Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); - //Phase = BrakingPhase.Brake; }). - Case<ResponseDrivingCycleDistanceExceeded>(r => { - if (!ds.IsEqual(r.MaxDistance)) { - // distance has been reduced due to vehicle stop in coast/roll action => use brake action to get exactly to the stop-distance - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } - }). - Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }). - Case<ResponseEngineSpeedTooHigh>(r => { - response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r); - }); - // handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try - response.Switch(). Case<ResponseSpeedLimitExceeded>(() => { response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, gradient); - if (response is ResponseOverload && !DataBus.ClutchClosed(absTime)) { - response = Driver.DrivingActionRoll(absTime, ds, DataBus.VehicleSpeed, gradient); - } }); - break; - case BrakingPhase.Brake: - - Log.Debug("Phase: BRAKE. breaking distance: {0} start braking @ {1}", brakingDistance, - DriverStrategy.BrakeTrigger.BrakingStartDistance); - if (DriverStrategy.BrakeTrigger.BrakingStartDistance.IsSmaller(currentDistance, - Constants.SimulationSettings.DriverActionDistanceTolerance / 2)) { - Log.Info("Expected Braking Deceleration could not be reached! {0}", - DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance); - } - var targetDistance = DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast - ? DriverStrategy.BrakeTrigger.TriggerDistance - : null; - if (targetDistance == null && DriverStrategy.BrakeTrigger.NextTargetSpeed.IsEqual(0.SI<MeterPerSecond>())) { - targetDistance = DriverStrategy.BrakeTrigger.TriggerDistance - DefaultDriverStrategy.BrakingSafetyMargin; - } - Driver.DriverBehavior = DrivingBehavior.Braking; - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, targetDistance: targetDistance); + }). + Case<ResponseSpeedLimitExceeded>(() => { + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, + gradient); + }). + Case<ResponseUnderload>(r => { + //response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + // gradient, r); + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval, + gradient, r); response.Switch(). - Case<ResponseOverload>(r => { - Log.Info( - "Brake -> Got OverloadResponse during brake action - desired deceleration could not be reached! response: {0}", - r); - if (!DataBus.ClutchClosed(absTime)) { - Log.Info("Brake -> Overload -> Clutch is open - Trying roll action"); - response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); - } else { - Log.Info("Brake -> Overload -> Clutch is closed - Trying brake action again"); - DataBus.BrakePower = 0.SI<Watt>(); - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient, - targetDistance: targetDistance); - response.Switch(). - Case<ResponseOverload>(r1 => { - Log.Info("Brake -> Overload -> 2nd Brake -> Overload -> Trying accelerate action"); - response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - response.Switch().Case<ResponseGearShift>( - rs => { - Log.Info("Brake -> Overload -> 2nd Brake -> Accelerate -> Got GearShift response, performing roll action"); - response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - }); - }); - } - }). - Case<ResponseGearShift>(r => { - Log.Info("Brake -> Got GearShift response, performing roll action + brakes"); - //response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + Case<ResponseGearShift>(() => { DataBus.BrakePower = 0.SI<Watt>(); response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, targetDistance: targetDistance); + gradient, r); + }). + Case<ResponseOverload>(() => { + DataBus.BrakePower = 0.SI<Watt>(); + if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { + if (DataBus.VehicleSpeed.IsGreater(0)) { + response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } else { + if (RetryDistanceExceeded) { + response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + } else { + RetryDistanceExceeded = true; + response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + } + } + } else { + response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } }); - break; - } - + }); + //} while (!(response is ResponseSuccess) && i++ < 3); return response; } - private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + private IResponse TargetSpeedReachedDriveAlong(Second absTime, Meter ds, MeterPerSecond targetVelocity, + Radian gradient) { IResponse response; if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { @@ -685,62 +811,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); } else { RetryDistanceExceeded = true; - return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; } } } else { response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); } - var i = 0; - do { - response.Switch(). - Case<ResponseGearShift>(() => { - response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); - response.Switch(). - Case<ResponseUnderload>(r => { - // under-load may happen if driver limits acceleration when rolling downhill - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - }). - Case<ResponseSpeedLimitExceeded>(() => { - response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, - gradient); - }); - }). - Case<ResponseSpeedLimitExceeded>(() => { - response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, - gradient); - }). - Case<ResponseUnderload>(r => { - //response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - // gradient, r); - response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval, - gradient, r); - response.Switch(). - Case<ResponseGearShift>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - }). - Case<ResponseOverload>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - if (DataBus.VehicleSpeed.IsGreater(0)) { - response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } else { - if (RetryDistanceExceeded) { - response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); - } else { - RetryDistanceExceeded = true; - response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; - } - } - } else { - response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } - }); - }); - } while (!(response is ResponseSuccess) && i++ < 3); return response; } @@ -788,7 +864,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Meter ActionDistance { - get { + get + { return VectoMath.Min(CoastingStartDistance ?? double.MaxValue.SI<Meter>(), BrakingStartDistance ?? double.MaxValue.SI<Meter>()); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs index 5ef7c018e3e3a1d472b5b76b296da1fe215ec3f5..f077fefc392a8c938032d8c729544493c8417a43 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs @@ -107,27 +107,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Request(Second absTime, Meter ds) { if (Left.Distance.IsEqual(PreviousState.Distance.Value())) { - // we are exactly on an entry in the cycle. - var stopTime = Left.PTOActive && IdleController != null - ? Left.StoppingTime + IdleController.Duration - : Left.StoppingTime; - - if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) { - // stop for certain time unless we've already waited long enough ... - - // we are stopping: ensure that velocity is 0. - if (!Left.VehicleTargetSpeed.IsEqual(0)) { - Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}", - Left.StoppingTime, Left.VehicleTargetSpeed); - throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!"); - } - var dt = GetStopTimeInterval(); - if (dt == null) { - CurrentState.WaitPhase++; - dt = GetStopTimeInterval(); - } - CurrentState.Response = DriveTimeInterval(absTime, dt); - return CurrentState.Response; + var response = DoFirstSimulationInterval(absTime); + if (response != null) { + return response; } } if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(Right.Distance)) { @@ -167,6 +149,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return CurrentState.Response; } + private IResponse DoFirstSimulationInterval(Second absTime) + { +// we are exactly on an entry in the cycle. + var stopTime = Left.PTOActive && IdleController != null + ? Left.StoppingTime + IdleController.Duration + : Left.StoppingTime; + + if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) { + // stop for certain time unless we've already waited long enough ... + + // we are stopping: ensure that velocity is 0. + if (!Left.VehicleTargetSpeed.IsEqual(0)) { + Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}", + Left.StoppingTime, Left.VehicleTargetSpeed); + throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!"); + } + var dt = GetStopTimeInterval(); + if (dt == null) { + CurrentState.WaitPhase++; + dt = GetStopTimeInterval(); + } + CurrentState.Response = DriveTimeInterval(absTime, dt); + return CurrentState.Response; + } + return null; + } + private Second GetStopTimeInterval() { if (!Left.PTOActive || IdleController == null) { @@ -309,17 +318,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl CurrentState = CurrentState.Clone(); _intervalProlonged = false; - //var stopTime = Left.PTOActive && IdleController != null - // ? Left.StoppingTime + IdleController.Duration - // : Left.StoppingTime; - - //if (!stopTime.IsEqual(0) && stopTime.IsEqual(PreviousState.WaitTime)) { - // // we needed to stop at the current interval in the cycle and have already waited enough time, move on.. - // if (IdleController != null) { - // IdleController.ActivateIdle(); - // } - // CycleIntervalIterator.MoveNext(); - //} var stopTime = Left.PTOActive && IdleController != null ? Left.StoppingTime + IdleController.Duration @@ -392,7 +390,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// </summary> public double Progress { - get { + get + { return Data.Entries.Count > 0 ? (CurrentState.Distance.Value() - Data.Entries.First().Distance.Value()) / (Data.Entries.Last().Distance.Value() - Data.Entries.First().Distance.Value()) @@ -449,7 +448,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public CycleData CycleData { - get { + get + { return new CycleData { AbsTime = CurrentState.AbsTime, AbsDistance = CurrentState.Distance, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index d6427262a92f48cca756403e27ea624d13a4fe1f..894dd1b7096ba7193d40314f607a597d65863c86 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -29,907 +29,943 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; -using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class Driver : - StatefulProviderComponent<Driver.DriverState, IDrivingCycleOutPort, IDriverDemandInPort, IDriverDemandOutPort>, - IDriver, IDrivingCycleOutPort, IDriverDemandInPort, IDriverActions, IDriverInfo - { - public DriverData DriverData { get; protected set; } - - protected readonly IDriverStrategy DriverStrategy; - public string CurrentAction = ""; - - public Driver(IVehicleContainer container, DriverData driverData, IDriverStrategy strategy) : base(container) - { - DriverData = driverData; - DriverStrategy = strategy; - strategy.Driver = this; - DriverAcceleration = 0.SI<MeterPerSquareSecond>(); - } - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) - { - DriverBehavior = vehicleSpeed.IsEqual(0) ? DrivingBehavior.Halted : DrivingBehavior.Driving; - return NextComponent.Initialize(vehicleSpeed, roadGradient); - } - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, - MeterPerSquareSecond startAcceleration) - { - DriverBehavior = vehicleSpeed.IsEqual(0) ? DrivingBehavior.Halted : DrivingBehavior.Driving; - var retVal = NextComponent.Initialize(vehicleSpeed, roadGradient, startAcceleration); - - return retVal; - } - - public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) - { - IterationStatistics.Increment(this, "Requests"); - - Log.Debug("==== DRIVER Request (distance) ===="); - Log.Debug( - "Request: absTime: {0}, ds: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5}, vehicle stopped: {6}", - absTime, ds, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.VehicleStopped); - - var retVal = DriverStrategy.Request(absTime, ds, targetVelocity, gradient); - - CurrentState.Response = retVal; - retVal.SimulationInterval = CurrentState.dt; - retVal.Acceleration = CurrentState.Acceleration; - - return retVal; - } - - public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) - { - IterationStatistics.Increment(this, "Requests"); - - Log.Debug("==== DRIVER Request (time) ===="); - Log.Debug( - "Request: absTime: {0}, dt: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}: vehicle stopped: {7}", - absTime, dt, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear, - DataBus.VehicleStopped); - - var retVal = DriverStrategy.Request(absTime, dt, targetVelocity, gradient); - - CurrentState.Response = retVal; - retVal.SimulationInterval = CurrentState.dt; - retVal.Acceleration = CurrentState.Acceleration; - - return retVal; - } - - public new IDataBus DataBus - { - get { return base.DataBus; } - } - - /// <summary> - /// see documentation of IDriverActions - /// </summary> - /// <param name="absTime"></param> - /// <param name="ds"></param> - /// <param name="targetVelocity"></param> - /// <param name="gradient"></param> - /// <param name="previousResponse"></param> - /// <returns></returns> - public IResponse DrivingActionAccelerate(Second absTime, Meter ds, MeterPerSecond targetVelocity, - Radian gradient, - IResponse previousResponse = null) - { - CurrentAction = "ACCELERATE"; - IterationStatistics.Increment(this, "Accelerate"); - Log.Debug("DrivingAction Accelerate"); - var operatingPoint = ComputeAcceleration(ds, targetVelocity); - - IResponse retVal = null; - DriverAcceleration = operatingPoint.Acceleration; - var response = previousResponse ?? - NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, - gradient); - response.Acceleration = operatingPoint.Acceleration; - - response.Switch(). - Case<ResponseSuccess>(r => { retVal = r; // => return - }). - Case<ResponseOverload>(). // do nothing, searchOperatingPoint is called later on - Case<ResponseEngineSpeedTooHigh>(). // do nothing, searchOperatingPoint is called later on - Case<ResponseUnderload>(r => { - // Delta is negative we are already below the Drag-load curve. activate brakes - retVal = r; // => return, strategy should brake - }). - Case<ResponseFailTimeInterval>(r => { - // occurs only with AT gearboxes - extend time interval after gearshift! - retVal = new ResponseDrivingCycleDistanceExceeded { - Source = this, - MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT - }; - }). - Case<ResponseGearShift>(r => { retVal = r; }). - Default(r => { throw new UnexpectedResponseException("DrivingAction Accelerate.", r); }); - - if (retVal == null) { - // unhandled response (overload, delta > 0) - we need to search for a valid operating point.. - - OperatingPoint nextOperatingPoint; - try { - nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, - response); - } catch (VectoEngineSpeedTooLowException) { - // in case of an exception during search the engine-speed got too low - gear disengaged, try roll action. - nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, - response); - } - - var limitedOperatingPoint = nextOperatingPoint; - if (!(retVal is ResponseEngineSpeedTooHigh || DataBus.ClutchClosed(absTime))) { - limitedOperatingPoint = LimitAccelerationByDriverModel(nextOperatingPoint, - LimitationMode.LimitDecelerationDriver); - Log.Debug("Found operating point for Drive/Accelerate. dt: {0}, acceleration: {1}", - limitedOperatingPoint.SimulationInterval, limitedOperatingPoint.Acceleration); - } - DriverAcceleration = limitedOperatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, limitedOperatingPoint.SimulationInterval, - limitedOperatingPoint.Acceleration, - gradient); - if (retVal != null) { - retVal.Acceleration = limitedOperatingPoint.Acceleration; - } - retVal.Switch(). - Case<ResponseUnderload>(() => operatingPoint = limitedOperatingPoint) - . // acceleration is limited by driver model, operating point moves below drag curve - Case<ResponseOverload>(() => { - // deceleration is limited by driver model, operating point moves above full load (e.g., steep uphill) - // the vehicle/driver can't achieve an acceleration higher than deceleration curve, try again with higher deceleration - if (DataBus.GearboxType.AutomaticTransmission()) { - Log.Info("AT Gearbox - Operating point resulted in an overload, searching again..."); - // search again for operating point, transmission may have shifted inbetween - nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, - response); - DriverAcceleration = nextOperatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, - nextOperatingPoint.Acceleration, gradient); - } else { - if (absTime > 0 && DataBus.VehicleStopped) { - Log.Info( - "Operating point with limited acceleration resulted in an overload! Vehicle stopped! trying HALT action {0}", - nextOperatingPoint.Acceleration); - DataBus.BrakePower = 1.SI<Watt>(); - retVal = DrivingActionHalt(absTime, nextOperatingPoint.SimulationInterval, 0.SI<MeterPerSecond>(), gradient); - ds = 0.SI<Meter>(); - //retVal.Acceleration = 0.SI<MeterPerSquareSecond>(); - } else { - if (response is ResponseEngineSpeedTooHigh) { - Log.Info( - "Operating point with limited acceleration due to high engine speed resulted in an overload, searching again..."); - nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, - retVal); - DriverAcceleration = nextOperatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, - nextOperatingPoint.Acceleration, gradient); - } else { - Log.Info( - "Operating point with limited acceleration resulted in an overload! trying again with original acceleration {0}", - nextOperatingPoint.Acceleration); - DriverAcceleration = nextOperatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, - nextOperatingPoint.Acceleration, - gradient); - } - } - } - retVal.Switch(). - Case<ResponseSuccess>(() => operatingPoint = nextOperatingPoint). - Case<ResponseGearShift>(() => operatingPoint = nextOperatingPoint). - Default( - r => { throw new UnexpectedResponseException("DrivingAction Accelerate after Overload", r); }); - }). - Case<ResponseGearShift>(() => operatingPoint = limitedOperatingPoint). - Case<ResponseFailTimeInterval>(r => { - // occurs only with AT gearboxes - extend time interval after gearshift! - retVal = new ResponseDrivingCycleDistanceExceeded { - Source = this, - MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT - }; - }). - Case<ResponseSuccess>(() => operatingPoint = limitedOperatingPoint). - Default( - r => { - throw new UnexpectedResponseException( - "DrivingAction Accelerate after SearchOperatingPoint.", r); - }); - } - CurrentState.Acceleration = operatingPoint.Acceleration; - CurrentState.dt = operatingPoint.SimulationInterval; - CurrentState.Response = retVal; - - retVal.Acceleration = operatingPoint.Acceleration; - retVal.SimulationInterval = operatingPoint.SimulationInterval; - retVal.SimulationDistance = ds; - retVal.OperatingPoint = operatingPoint; - - return retVal; - } - - /// <summary> - /// see documentation of IDriverActions - /// </summary> - /// <param name="absTime"></param> - /// <param name="ds"></param> - /// <param name="maxVelocity"></param> - /// <param name="gradient"></param> - /// <returns></returns> - public IResponse DrivingActionCoast(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient) - { - CurrentAction = "COAST"; - IterationStatistics.Increment(this, "Coast"); - Log.Debug("DrivingAction Coast"); - - return CoastOrRollAction(absTime, ds, maxVelocity, gradient, false); - } - - /// <summary> - /// see documentation of IDriverActions - /// </summary> - /// <param name="absTime"></param> - /// <param name="ds"></param> - /// <param name="maxVelocity"></param> - /// <param name="gradient"></param> - /// <returns></returns> - public IResponse DrivingActionRoll(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient) - { - CurrentAction = "ROLL"; - IterationStatistics.Increment(this, "Roll"); - - Log.Debug("DrivingAction Roll"); - - var retVal = CoastOrRollAction(absTime, ds, maxVelocity, gradient, true); - retVal.Switch(). - Case<ResponseGearShift>( - () => { - throw new UnexpectedResponseException("DrivingAction Roll: Gearshift during Roll action.", - retVal); - }); - - return retVal; - } - - /// <summary> - /// - /// </summary> - /// <param name="absTime"></param> - /// <param name="ds"></param> - /// <param name="maxVelocity"></param> - /// <param name="gradient"></param> - /// <param name="rollAction"></param> - /// <returns> - /// * ResponseSuccess - /// * ResponseDrivingCycleDistanceExceeded: vehicle is at low speed, coasting would lead to stop before ds is reached. - /// * ResponseSpeedLimitExceeded: vehicle accelerates during coasting which would lead to exceeding the given maxVelocity (e.g., driving downhill, engine's drag load is not sufficient) - /// * ResponseUnderload: engine's operating point is below drag curve (vehicle accelerates more than driver model allows; engine's drag load is not sufficient for limited acceleration - /// * ResponseGearShift: gearbox needs to shift gears, vehicle can not accelerate (traction interruption) - /// * ResponseFailTimeInterval: - /// </returns> - protected IResponse CoastOrRollAction(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient, - bool rollAction) - { - var requestedOperatingPoint = ComputeAcceleration(ds, DataBus.VehicleSpeed); - DriverAcceleration = requestedOperatingPoint.Acceleration; - var initialResponse = NextComponent.Request(absTime, requestedOperatingPoint.SimulationInterval, - requestedOperatingPoint.Acceleration, gradient, dryRun: true); - - OperatingPoint searchedOperatingPoint; - try { - searchedOperatingPoint = SearchOperatingPoint(absTime, requestedOperatingPoint.SimulationDistance, - gradient, - requestedOperatingPoint.Acceleration, initialResponse, coastingOrRoll: true); - } catch (VectoEngineSpeedTooLowException) { - // in case of an exception during search the engine-speed got too low - gear disengaged --> try again with disengaged gear. - searchedOperatingPoint = SearchOperatingPoint(absTime, requestedOperatingPoint.SimulationDistance, - gradient, - requestedOperatingPoint.Acceleration, initialResponse, coastingOrRoll: true); - } - - if (!ds.IsEqual(searchedOperatingPoint.SimulationDistance)) { - // vehicle is at low speed, coasting would lead to stop before ds is reached: reduce simulated distance to stop distance. - Log.Debug( - "SearchOperatingPoint reduced the max. distance: {0} -> {1}. Issue new request from driving cycle!", - searchedOperatingPoint.SimulationDistance, ds); - CurrentState.Response = new ResponseDrivingCycleDistanceExceeded { - Source = this, - MaxDistance = searchedOperatingPoint.SimulationDistance, - Acceleration = searchedOperatingPoint.Acceleration, - SimulationInterval = searchedOperatingPoint.SimulationInterval, - OperatingPoint = searchedOperatingPoint - }; - return CurrentState.Response; - } - - Log.Debug("Found operating point for {2}. dt: {0}, acceleration: {1}", - searchedOperatingPoint.SimulationInterval, - searchedOperatingPoint.Acceleration, rollAction ? "ROLL" : "COAST"); - - var limitedOperatingPoint = LimitAccelerationByDriverModel(searchedOperatingPoint, - rollAction ? LimitationMode.NoLimitation : LimitationMode.LimitDecelerationDriver); - - // compute speed at the end of the simulation interval. if it exceeds the limit -> return - var v2 = DataBus.VehicleSpeed + - limitedOperatingPoint.Acceleration * limitedOperatingPoint.SimulationInterval; - if (v2 > maxVelocity && limitedOperatingPoint.Acceleration.IsGreaterOrEqual(0)) { - Log.Debug("vehicle's velocity would exceed given max speed. v2: {0}, max speed: {1}", v2, maxVelocity); - return new ResponseSpeedLimitExceeded() { Source = this }; - } - - DriverAcceleration = limitedOperatingPoint.Acceleration; - var response = NextComponent.Request(absTime, limitedOperatingPoint.SimulationInterval, - limitedOperatingPoint.Acceleration, gradient); - - response.SimulationInterval = limitedOperatingPoint.SimulationInterval; - response.SimulationDistance = ds; - response.Acceleration = limitedOperatingPoint.Acceleration; - response.OperatingPoint = limitedOperatingPoint; - - response.Switch(). - Case<ResponseSuccess>(). - Case<ResponseUnderload>(). // driver limits acceleration, operating point may be below engine's - //drag load resp. below 0 - Case<ResponseOverload>(). // driver limits acceleration, operating point may be above 0 (GBX), use brakes - Case<ResponseEngineSpeedTooHigh>(). // reduce acceleration/vehicle speed - Case<ResponseGearShift>(). - Case<ResponseFailTimeInterval>(r => { - response = new ResponseDrivingCycleDistanceExceeded { - Source = this, - MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT - }; - }). - Default( - () => { - throw new UnexpectedResponseException( - "CoastOrRoll Action: unhandled response from powertrain.", response); - }); - - CurrentState.Response = response; - CurrentState.Acceleration = response.Acceleration; - CurrentState.dt = response.SimulationInterval; - return response; - } - - public IResponse DrivingActionBrake(Second absTime, Meter ds, MeterPerSecond nextTargetSpeed, Radian gradient, - IResponse previousResponse = null, Meter targetDistance = null) - { - CurrentAction = "BRAKE"; - IterationStatistics.Increment(this, "Brake"); - Log.Debug("DrivingAction Brake"); - - IResponse retVal = null; - - var operatingPoint = ComputeAcceleration(ds, nextTargetSpeed); - - //if (operatingPoint.Acceleration.IsSmaller(0)) { - // if we should brake with the max. deceleration and the deceleration changes within the current interval, take the larger deceleration... - if ( - operatingPoint.Acceleration.IsEqual( - DriverData.AccelerationCurve.Lookup(DataBus.VehicleSpeed).Deceleration)) { - var v2 = DataBus.VehicleSpeed + operatingPoint.Acceleration * operatingPoint.SimulationInterval; - var nextAcceleration = DriverData.AccelerationCurve.Lookup(v2).Deceleration; - var tmp = ComputeTimeInterval(VectoMath.Min(operatingPoint.Acceleration, nextAcceleration), - operatingPoint.SimulationDistance); - if (!operatingPoint.Acceleration.IsEqual(nextAcceleration) && - operatingPoint.SimulationDistance.IsEqual(tmp.SimulationDistance)) { - // only adjust operating point if the acceleration is different but the simulation distance is not modified - // i.e., braking to the next sample point (but a little bit slower) - Log.Debug("adjusting acceleration from {0} to {1}", operatingPoint.Acceleration, tmp.Acceleration); - operatingPoint = tmp; - // ComputeTimeInterval((operatingPoint.Acceleration + tmp.Acceleration) / 2, operatingPoint.SimulationDistance); - } - } - if (targetDistance != null && targetDistance > DataBus.Distance) { - var tmp = ComputeAcceleration(targetDistance - DataBus.Distance, nextTargetSpeed, false); - if (tmp.Acceleration.IsGreater(operatingPoint.Acceleration)) { - operatingPoint = ComputeTimeInterval(tmp.Acceleration, ds); - if (!ds.IsEqual(operatingPoint.SimulationDistance)) { - Log.Error( - "Unexpected Condition: Distance has been adjusted from {0} to {1}, currentVelocity: {2} acceleration: {3}, targetVelocity: {4}", - operatingPoint.SimulationDistance, ds, DataBus.VehicleSpeed, operatingPoint.Acceleration, - nextTargetSpeed); - throw new VectoSimulationException("Simulation distance unexpectedly adjusted! {0} -> {1}", ds, - operatingPoint.SimulationDistance); - } - } - } - - DriverAcceleration = operatingPoint.Acceleration; - var response = previousResponse ?? - NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, - gradient); - - var point = operatingPoint; - response.Switch(). - Case<ResponseSuccess>(r => retVal = r). - Case<ResponseOverload>(r => retVal = r) - . // i.e., driving uphill, clutch open, deceleration higher than desired deceleration - Case<ResponseUnderload>(). // will be handled in SearchBrakingPower - Case<ResponseEngineSpeedTooHigh>(r => { - Log.Debug("Engine speeed was too high, search for appropriate acceleration first."); - operatingPoint = SearchOperatingPoint(absTime, ds, gradient, point.Acceleration, - response); - }). // will be handled in SearchBrakingPower - Case<ResponseGearShift>(). // will be handled in SearchBrakingPower - Case<ResponseFailTimeInterval>(r => - retVal = new ResponseDrivingCycleDistanceExceeded() { - Source = this, - MaxDistance = DataBus.VehicleSpeed * r.DeltaT + point.Acceleration / 2 * r.DeltaT * r.DeltaT - }). - Default(r => { throw new UnexpectedResponseException("DrivingAction Brake: first request.", r); }); - - if (retVal != null) { - CurrentState.Acceleration = operatingPoint.Acceleration; - CurrentState.dt = operatingPoint.SimulationInterval; - CurrentState.Response = retVal; - retVal.Acceleration = operatingPoint.Acceleration; - retVal.SimulationInterval = operatingPoint.SimulationInterval; - retVal.SimulationDistance = ds; - retVal.OperatingPoint = operatingPoint; - return retVal; - } - - operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, - operatingPoint.Acceleration, response); - - if (!ds.IsEqual(operatingPoint.SimulationDistance, 1E-15.SI<Meter>())) { - Log.Info( - "SearchOperatingPoint Braking reduced the max. distance: {0} -> {1}. Issue new request from driving cycle!", - operatingPoint.SimulationDistance, ds); - return new ResponseDrivingCycleDistanceExceeded { - Source = this, - MaxDistance = operatingPoint.SimulationDistance - }; - } - - Log.Debug("Found operating point for braking. dt: {0}, acceleration: {1} brakingPower: {2}", - operatingPoint.SimulationInterval, - operatingPoint.Acceleration, DataBus.BrakePower); - if (DataBus.BrakePower < 0) { - var overload = new ResponseOverload { - Source = this, - BrakePower = DataBus.BrakePower, - Acceleration = operatingPoint.Acceleration - }; - DataBus.BrakePower = 0.SI<Watt>(); - return overload; - } - - DriverAcceleration = operatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, - gradient); - - retVal.Switch(). - Case<ResponseSuccess>(). - Case<ResponseGearShift>(). - Case<ResponseFailTimeInterval>(r => - retVal = new ResponseDrivingCycleDistanceExceeded() { - Source = this, - MaxDistance = - DataBus.VehicleSpeed * r.DeltaT + operatingPoint.Acceleration / 2 * r.DeltaT * r.DeltaT - }). - Case<ResponseUnderload>(r => { - if (DataBus.GearboxType.AutomaticTransmission()) { - operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, - operatingPoint.Acceleration, response); - DriverAcceleration = operatingPoint.Acceleration; - retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, - operatingPoint.Acceleration, gradient); - } - }). - Case<ResponseOverload>(r => { - if (DataBus.GearboxType.AutomaticTransmission()) { - // overload may happen because of gearshift between search and actual request, search again - var i = 5; - while (i-- > 0 && !(retVal is ResponseSuccess)) { - DataBus.BrakePower = 0.SI<Watt>(); - operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, - operatingPoint.Acceleration, response); - DriverAcceleration = operatingPoint.Acceleration; - if (DataBus.BrakePower.IsSmaller(0)) { - DataBus.BrakePower = 0.SI<Watt>(); - - operatingPoint = SearchOperatingPoint(absTime, ds, gradient, 0.SI<MeterPerSquareSecond>(), r); - } - retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, - operatingPoint.Acceleration, gradient); - } - } else { - throw new UnexpectedResponseException( - "DrivingAction Brake: request failed after braking power was found.", r); - } - }). - Default( - r => { - throw new UnexpectedResponseException( - "DrivingAction Brake: request failed after braking power was found.", r); - }); - CurrentState.Acceleration = operatingPoint.Acceleration; - CurrentState.dt = operatingPoint.SimulationInterval; - CurrentState.Response = retVal; - retVal.Acceleration = operatingPoint.Acceleration; - retVal.SimulationInterval = operatingPoint.SimulationInterval; - retVal.SimulationDistance = ds; - retVal.OperatingPoint = operatingPoint; - - return retVal; - } - - // ================================================ - - /// <summary> - /// - /// </summary> - /// <param name="operatingPoint"></param> - /// <param name="limits"></param> - /// <returns></returns> - private OperatingPoint LimitAccelerationByDriverModel(OperatingPoint operatingPoint, - LimitationMode limits) - { - var limitApplied = false; - var originalAcceleration = operatingPoint.Acceleration; - //if (((limits & LimitationMode.LimitDecelerationLookahead) != 0) && - // operatingPoint.Acceleration < DriverData.LookAheadCoasting.Deceleration) { - // operatingPoint.Acceleration = DriverData.LookAheadCoasting.Deceleration; - // limitApplied = true; - //} - var accelerationLimits = DriverData.AccelerationCurve.Lookup(DataBus.VehicleSpeed); - if (operatingPoint.Acceleration > accelerationLimits.Acceleration) { - operatingPoint.Acceleration = accelerationLimits.Acceleration; - limitApplied = true; - } - if (((limits & LimitationMode.LimitDecelerationDriver) != 0) && - operatingPoint.Acceleration < accelerationLimits.Deceleration) { - operatingPoint.Acceleration = accelerationLimits.Deceleration; - limitApplied = true; - } - if (limitApplied) { - operatingPoint.SimulationInterval = - ComputeTimeInterval(operatingPoint.Acceleration, operatingPoint.SimulationDistance) - .SimulationInterval; - Log.Debug("Limiting acceleration from {0} to {1}, dt: {2}", originalAcceleration, - operatingPoint.Acceleration, operatingPoint.SimulationInterval); - } - return operatingPoint; - } - - /// <summary> - /// Performs a search for the required braking power such that the vehicle accelerates with the given acceleration. - /// Returns a new operating point (a, ds, dt) where ds may be shorter due to vehicle stopping - /// </summary> - /// <returns>operating point (a, ds, dt) such that the vehicle accelerates with the given acceleration.</returns> - private OperatingPoint SearchBrakingPower(Second absTime, Meter ds, Radian gradient, - MeterPerSquareSecond acceleration, IResponse initialResponse) - { - IterationStatistics.Increment(this, "SearchBrakingPower", 0); - - var operatingPoint = new OperatingPoint { SimulationDistance = ds, Acceleration = acceleration }; - operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds); - Watt deltaPower = null; - initialResponse.Switch(). - Case<ResponseGearShift>(r => { - IterationStatistics.Increment(this, "SearchBrakingPower"); - DriverAcceleration = operatingPoint.Acceleration; - var nextResp = NextComponent.Request(absTime, operatingPoint.SimulationInterval, - operatingPoint.Acceleration, - gradient, true); - deltaPower = nextResp.GearboxPowerRequest; - }). - Case<ResponseEngineSpeedTooHigh>(r => { - IterationStatistics.Increment(this, "SearchBrakingPower"); - DriverAcceleration = operatingPoint.Acceleration; - var nextResp = NextComponent.Request(absTime, operatingPoint.SimulationInterval, - operatingPoint.Acceleration, - gradient, true); - deltaPower = nextResp.GearboxPowerRequest; - }). - Case<ResponseUnderload>(r => - deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest). - Default( - r => { throw new UnexpectedResponseException("cannot use response for searching braking power!", r); }); - - try { - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, deltaPower, - deltaPower.Abs() * (DataBus.GearboxType.AutomaticTransmission() ? 0.5 : 1), - getYValue: result => { - var response = (ResponseDryRun)result; - return DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest; - }, - evaluateFunction: x => { - DataBus.BrakePower = x; - operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds); - - IterationStatistics.Increment(this, "SearchBrakingPower"); - DriverAcceleration = operatingPoint.Acceleration; - return NextComponent.Request(absTime, operatingPoint.SimulationInterval, - operatingPoint.Acceleration, gradient, - true); - }, - criterion: result => { - var response = (ResponseDryRun)result; - var delta = DataBus.ClutchClosed(absTime) - ? response.DeltaDragLoad - : response.GearboxPowerRequest; - return delta.Value(); - }); - - return operatingPoint; - } catch (Exception) { - Log.Error("Failed to find operating point for braking power! absTime: {0}", absTime); - throw; - } - } - - protected OperatingPoint SearchOperatingPoint(Second absTime, Meter ds, Radian gradient, - MeterPerSquareSecond acceleration, IResponse initialResponse, bool coastingOrRoll = false) - { - IterationStatistics.Increment(this, "SearchOperatingPoint", 0); - - var retVal = new OperatingPoint { Acceleration = acceleration, SimulationDistance = ds }; - - var actionRoll = !DataBus.ClutchClosed(absTime); - var searchEngineSpeed = false; - - Watt origDelta = null; - if (actionRoll) { - initialResponse.Switch(). - Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). - Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). - Default(r => { throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); }); - } else { - initialResponse.Switch(). - Case<ResponseOverload>(r => origDelta = r.Delta). - Case<ResponseEngineSpeedTooHigh>(r => { - searchEngineSpeed = true; - origDelta = r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); - }). // search operating point in drive action after overload - Case<ResponseDryRun>(r => origDelta = coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad). - Default(r => { throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); }); - } - var delta = origDelta; - try { - retVal.Acceleration = SearchAlgorithm.Search(acceleration, delta, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: response => { - var r = (ResponseDryRun)response; - if (searchEngineSpeed) { - return r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); - } - return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); - }, - evaluateFunction: - acc => { - // calculate new time interval only when vehiclespeed and acceleration are != 0 - // else: use same timeinterval as before. - if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) { - var tmp = ComputeTimeInterval(acc, ds); - if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { - throw new VectoSearchAbortedException( - "next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc, - DataBus.VehicleSpeed, tmp.SimulationInterval); - } - retVal.Acceleration = tmp.Acceleration; - retVal.SimulationInterval = tmp.SimulationInterval; - retVal.SimulationDistance = tmp.SimulationDistance; - } - IterationStatistics.Increment(this, "SearchOperatingPoint"); - DriverAcceleration = acc; - var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true); - response.OperatingPoint = retVal; - return response; - }, - criterion: response => { - var r = (ResponseDryRun)response; - if (searchEngineSpeed) { - return r.DeltaEngineSpeed.Value(); - } - delta = actionRoll - ? r.GearboxPowerRequest - : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); - return delta.Value(); - }, - abortCriterion: - (response, cnt) => { - var r = (ResponseDryRun)response; - if (r == null) { - return false; - } - - return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); - }); - } catch (VectoSearchAbortedException) { - // search aborted, try to go ahead with the last acceleration - } catch (Exception) { - Log.Error("Failed to find operating point! absTime: {0}", absTime); - throw; - } - - if (!retVal.Acceleration.IsBetween(DriverData.AccelerationCurve.MaxDeceleration(), - DriverData.AccelerationCurve.MaxAcceleration())) { - Log.Info("Operating Point outside driver acceleration limits: a: {0}", retVal.Acceleration); - } - return ComputeTimeInterval(retVal.Acceleration, retVal.SimulationDistance); - } - - /// <summary> - /// compute the acceleration and time-interval such that the vehicle's velocity approaches the given target velocity - /// - first compute the acceleration to reach the targetVelocity within the given distance - /// - limit the acceleration/deceleration by the driver's acceleration curve - /// - compute the time interval required to drive the given distance with the computed acceleration - /// computed acceleration and time interval are stored in CurrentState! - /// </summary> - /// <param name="ds">distance to reach the next target speed</param> - /// <param name="targetVelocity">next vehicle speed to decelerate to</param> - /// <param name="limitByDriverModel">if set to false the required acceleration will be computed, regardless of the driver's acceleration curve</param> - public OperatingPoint ComputeAcceleration(Meter ds, MeterPerSecond targetVelocity, - bool limitByDriverModel = true) - { - var currentSpeed = DataBus.VehicleSpeed; - var retVal = new OperatingPoint() { SimulationDistance = ds }; - - // Δx = (v0+v1)/2 * Δt - // => Δt = 2*Δx/(v0+v1) - var dt = 2 * ds / (currentSpeed + targetVelocity); - - // a = Δv / Δt - var requiredAcceleration = (targetVelocity - currentSpeed) / dt; - - if (!limitByDriverModel) { - return ComputeTimeInterval(requiredAcceleration, ds); - } - - var maxAcceleration = DriverData.AccelerationCurve.Lookup(currentSpeed); - - if (requiredAcceleration > maxAcceleration.Acceleration) { - requiredAcceleration = maxAcceleration.Acceleration; - } - if (requiredAcceleration < maxAcceleration.Deceleration) { - requiredAcceleration = maxAcceleration.Deceleration; - } - - retVal.Acceleration = requiredAcceleration; - retVal = ComputeTimeInterval(retVal.Acceleration, ds); - - if (ds.IsEqual(retVal.SimulationDistance)) { - return retVal; - } - - // this case should not happen, acceleration has been computed such that the target speed - // can be reached within ds. - Log.Error( - "Unexpected Condition: Distance has been adjusted from {0} to {1}, currentVelocity: {2} acceleration: {3}, targetVelocity: {4}", - retVal.SimulationDistance, ds, currentSpeed, CurrentState.Acceleration, targetVelocity); - throw new VectoSimulationException("Simulation distance unexpectedly adjusted! {0} -> {1}", ds, - retVal.SimulationDistance); - } - - /// <summary> - /// computes the distance required to decelerate from the current velocity to the given target velocity considering - /// the drivers acceleration/deceleration curve. - /// </summary> - /// <param name="targetSpeed"></param> - /// <returns></returns> - public Meter ComputeDecelerationDistance(MeterPerSecond targetSpeed) - { - return DriverData.AccelerationCurve.ComputeAccelerationDistance(DataBus.VehicleSpeed, targetSpeed); - } - - /// <summary> - /// Computes the time interval for driving the given distance ds with the vehicle's current speed and the given acceleration. - /// If the distance ds can not be reached (i.e., the vehicle would halt before ds is reached) then the distance parameter is adjusted. - /// Returns a new operating point (a, ds, dt) - /// </summary> - /// <param name="acceleration"></param> - /// <param name="ds"></param> - /// <returns>Operating point (a, ds, dt)</returns> - private OperatingPoint ComputeTimeInterval(MeterPerSquareSecond acceleration, Meter ds) - { - return VectoMath.ComputeTimeInterval(DataBus.VehicleSpeed, acceleration, DataBus.Distance, ds); - } - - /// <summary> - /// simulate a certain time interval where the vehicle is stopped. - /// </summary> - /// <param name="absTime"></param> - /// <param name="dt"></param> - /// <param name="targetVelocity"></param> - /// <param name="gradient"></param> - /// <returns></returns> - public IResponse DrivingActionHalt(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) - { - CurrentAction = "HALT"; - if (!targetVelocity.IsEqual(0) || !DataBus.VehicleStopped) { - Log.Error("TargetVelocity ({0}) and VehicleVelocity ({1}) must be zero when vehicle is halting!", - targetVelocity, - DataBus.VehicleSpeed); - throw new VectoSimulationException( - "TargetVelocity ({0}) and VehicleVelocity ({1}) must be zero when vehicle is halting!", - targetVelocity, - DataBus.VehicleSpeed); - } - - DriverAcceleration = 0.SI<MeterPerSquareSecond>(); - var retVal = NextComponent.Request(absTime, dt, 0.SI<MeterPerSquareSecond>(), gradient); - - retVal.Switch(). - Case<ResponseGearShift>(r => { - DriverAcceleration = 0.SI<MeterPerSquareSecond>(); - retVal = NextComponent.Request(absTime, dt, 0.SI<MeterPerSquareSecond>(), gradient); - }); - CurrentState.dt = dt; - CurrentState.Acceleration = 0.SI<MeterPerSquareSecond>(); - return retVal; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.acc] = CurrentState.Acceleration; - container.SetDataValue("DriverAction", ActionToNumber(CurrentAction)); - } - - private int ActionToNumber(string currentAction) - { - switch (currentAction.ToUpper()) { - case "HALT": - return 0; - case "ROLL": - return 2; - case "COAST": - return 4; - case "ACCELERATE": - return 6; - case "BRAKE": - return -5; - default: - return -10; - } - } - - protected override void DoCommitSimulationStep() - { - if (!(CurrentState.Response is ResponseSuccess)) { - throw new VectoSimulationException("Previous request did not succeed!"); - } - CurrentState.Response = null; - } - - public class DriverState - { - // ReSharper disable once InconsistentNaming - public Second dt; - public MeterPerSquareSecond Acceleration; - public IResponse Response; - } - - [Flags] - protected enum LimitationMode - { - NoLimitation = 0x0, - LimitDecelerationDriver = 0x2, - //LimitDecelerationLookahead = 0x4 - } - - public DrivingBehavior DriverBehavior { get; set; } - - public MeterPerSquareSecond DriverAcceleration { get; protected set; } - } +using System; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; +using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class Driver : + StatefulProviderComponent<Driver.DriverState, IDrivingCycleOutPort, IDriverDemandInPort, IDriverDemandOutPort>, + IDriver, IDrivingCycleOutPort, IDriverDemandInPort, IDriverActions, IDriverInfo + { + public DriverData DriverData { get; protected set; } + + protected readonly IDriverStrategy DriverStrategy; + public string CurrentAction = ""; + + public Driver(IVehicleContainer container, DriverData driverData, IDriverStrategy strategy) : base(container) + { + DriverData = driverData; + DriverStrategy = strategy; + strategy.Driver = this; + DriverAcceleration = 0.SI<MeterPerSquareSecond>(); + } + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) + { + DriverBehavior = vehicleSpeed.IsEqual(0) ? DrivingBehavior.Halted : DrivingBehavior.Driving; + return NextComponent.Initialize(vehicleSpeed, roadGradient); + } + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, + MeterPerSquareSecond startAcceleration) + { + DriverBehavior = vehicleSpeed.IsEqual(0) ? DrivingBehavior.Halted : DrivingBehavior.Driving; + var retVal = NextComponent.Initialize(vehicleSpeed, roadGradient, startAcceleration); + + return retVal; + } + + public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + IterationStatistics.Increment(this, "Requests"); + + Log.Debug("==== DRIVER Request (distance) ===="); + Log.Debug( + "Request: absTime: {0}, ds: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5}, vehicle stopped: {6}", + absTime, ds, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.VehicleStopped); + + var retVal = DriverStrategy.Request(absTime, ds, targetVelocity, gradient); + + CurrentState.Response = retVal; + retVal.SimulationInterval = CurrentState.dt; + retVal.Acceleration = CurrentState.Acceleration; + + return retVal; + } + + public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) + { + IterationStatistics.Increment(this, "Requests"); + + Log.Debug("==== DRIVER Request (time) ===="); + Log.Debug( + "Request: absTime: {0}, dt: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}: vehicle stopped: {7}", + absTime, dt, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear, + DataBus.VehicleStopped); + + var retVal = DriverStrategy.Request(absTime, dt, targetVelocity, gradient); + + CurrentState.Response = retVal; + retVal.SimulationInterval = CurrentState.dt; + retVal.Acceleration = CurrentState.Acceleration; + + return retVal; + } + + public new IDataBus DataBus + { + get { return base.DataBus; } + } + + /// <summary> + /// see documentation of IDriverActions + /// </summary> + /// <param name="absTime"></param> + /// <param name="ds"></param> + /// <param name="targetVelocity"></param> + /// <param name="gradient"></param> + /// <param name="previousResponse"></param> + /// <returns></returns> + public IResponse DrivingActionAccelerate(Second absTime, Meter ds, MeterPerSecond targetVelocity, + Radian gradient, + IResponse previousResponse = null) + { + CurrentAction = "ACCELERATE"; + IterationStatistics.Increment(this, "Accelerate"); + Log.Debug("DrivingAction Accelerate"); + var operatingPoint = ComputeAcceleration(ds, targetVelocity); + + IResponse retVal = null; + DriverAcceleration = operatingPoint.Acceleration; + var response = previousResponse ?? + NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, + gradient); + response.Acceleration = operatingPoint.Acceleration; + + response.Switch(). + Case<ResponseSuccess>(r => { + retVal = r; // => return + }). + Case<ResponseOverload>(). // do nothing, searchOperatingPoint is called later on + Case<ResponseEngineSpeedTooHigh>(). // do nothing, searchOperatingPoint is called later on + Case<ResponseUnderload>(r => { + // Delta is negative we are already below the Drag-load curve. activate brakes + retVal = r; // => return, strategy should brake + }). + Case<ResponseFailTimeInterval>(r => { + // occurs only with AT gearboxes - extend time interval after gearshift! + retVal = new ResponseDrivingCycleDistanceExceeded { + Source = this, + MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT + }; + }). + Case<ResponseGearShift>(r => { + retVal = r; + }). + Default(r => { + throw new UnexpectedResponseException("DrivingAction Accelerate.", r); + }); + + if (retVal == null) { + // unhandled response (overload, delta > 0) - we need to search for a valid operating point.. + + OperatingPoint nextOperatingPoint; + try { + nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, + response); + } catch (VectoEngineSpeedTooLowException) { + // in case of an exception during search the engine-speed got too low - gear disengaged, try roll action. + nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, + response); + } + + var limitedOperatingPoint = nextOperatingPoint; + if (!(retVal is ResponseEngineSpeedTooHigh || DataBus.ClutchClosed(absTime))) { + limitedOperatingPoint = LimitAccelerationByDriverModel(nextOperatingPoint, + LimitationMode.LimitDecelerationDriver); + Log.Debug("Found operating point for Drive/Accelerate. dt: {0}, acceleration: {1}", + limitedOperatingPoint.SimulationInterval, limitedOperatingPoint.Acceleration); + } + DriverAcceleration = limitedOperatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, limitedOperatingPoint.SimulationInterval, + limitedOperatingPoint.Acceleration, + gradient); + if (retVal != null) { + retVal.Acceleration = limitedOperatingPoint.Acceleration; + } + retVal.Switch(). + Case<ResponseUnderload>(() => operatingPoint = limitedOperatingPoint) + . // acceleration is limited by driver model, operating point moves below drag curve + Case<ResponseOverload>(() => { + // deceleration is limited by driver model, operating point moves above full load (e.g., steep uphill) + // the vehicle/driver can't achieve an acceleration higher than deceleration curve, try again with higher deceleration + if (DataBus.GearboxType.AutomaticTransmission()) { + Log.Info("AT Gearbox - Operating point resulted in an overload, searching again..."); + // search again for operating point, transmission may have shifted inbetween + nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, + response); + DriverAcceleration = nextOperatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, + nextOperatingPoint.Acceleration, gradient); + } else { + if (absTime > 0 && DataBus.VehicleStopped) { + Log.Info( + "Operating point with limited acceleration resulted in an overload! Vehicle stopped! trying HALT action {0}", + nextOperatingPoint.Acceleration); + DataBus.BrakePower = 1.SI<Watt>(); + retVal = DrivingActionHalt(absTime, nextOperatingPoint.SimulationInterval, 0.SI<MeterPerSecond>(), gradient); + ds = 0.SI<Meter>(); + //retVal.Acceleration = 0.SI<MeterPerSquareSecond>(); + } else { + if (response is ResponseEngineSpeedTooHigh) { + Log.Info( + "Operating point with limited acceleration due to high engine speed resulted in an overload, searching again..."); + nextOperatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, + retVal); + DriverAcceleration = nextOperatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, + nextOperatingPoint.Acceleration, gradient); + } else { + Log.Info( + "Operating point with limited acceleration resulted in an overload! trying again with original acceleration {0}", + nextOperatingPoint.Acceleration); + DriverAcceleration = nextOperatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, nextOperatingPoint.SimulationInterval, + nextOperatingPoint.Acceleration, + gradient); + } + } + } + retVal.Switch(). + Case<ResponseSuccess>(() => operatingPoint = nextOperatingPoint). + Case<ResponseGearShift>(() => operatingPoint = nextOperatingPoint). + Default( + r => { + throw new UnexpectedResponseException("DrivingAction Accelerate after Overload", r); + }); + }). + Case<ResponseGearShift>(() => operatingPoint = limitedOperatingPoint). + Case<ResponseFailTimeInterval>(r => { + // occurs only with AT gearboxes - extend time interval after gearshift! + retVal = new ResponseDrivingCycleDistanceExceeded { + Source = this, + MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT + }; + }). + Case<ResponseSuccess>(() => operatingPoint = limitedOperatingPoint). + Default( + r => { + throw new UnexpectedResponseException( + "DrivingAction Accelerate after SearchOperatingPoint.", r); + }); + } + CurrentState.Acceleration = operatingPoint.Acceleration; + CurrentState.dt = operatingPoint.SimulationInterval; + CurrentState.Response = retVal; + + retVal.Acceleration = operatingPoint.Acceleration; + retVal.SimulationInterval = operatingPoint.SimulationInterval; + retVal.SimulationDistance = ds; + retVal.OperatingPoint = operatingPoint; + + return retVal; + } + + /// <summary> + /// see documentation of IDriverActions + /// </summary> + /// <param name="absTime"></param> + /// <param name="ds"></param> + /// <param name="maxVelocity"></param> + /// <param name="gradient"></param> + /// <returns></returns> + public IResponse DrivingActionCoast(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient) + { + CurrentAction = "COAST"; + IterationStatistics.Increment(this, "Coast"); + Log.Debug("DrivingAction Coast"); + + return CoastOrRollAction(absTime, ds, maxVelocity, gradient, false); + } + + /// <summary> + /// see documentation of IDriverActions + /// </summary> + /// <param name="absTime"></param> + /// <param name="ds"></param> + /// <param name="maxVelocity"></param> + /// <param name="gradient"></param> + /// <returns></returns> + public IResponse DrivingActionRoll(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient) + { + CurrentAction = "ROLL"; + IterationStatistics.Increment(this, "Roll"); + + Log.Debug("DrivingAction Roll"); + + var retVal = CoastOrRollAction(absTime, ds, maxVelocity, gradient, true); + retVal.Switch(). + Case<ResponseGearShift>( + () => { + throw new UnexpectedResponseException("DrivingAction Roll: Gearshift during Roll action.", + retVal); + }); + + return retVal; + } + + /// <summary> + /// + /// </summary> + /// <param name="absTime"></param> + /// <param name="ds"></param> + /// <param name="maxVelocity"></param> + /// <param name="gradient"></param> + /// <param name="rollAction"></param> + /// <returns> + /// * ResponseSuccess + /// * ResponseDrivingCycleDistanceExceeded: vehicle is at low speed, coasting would lead to stop before ds is reached. + /// * ResponseSpeedLimitExceeded: vehicle accelerates during coasting which would lead to exceeding the given maxVelocity (e.g., driving downhill, engine's drag load is not sufficient) + /// * ResponseUnderload: engine's operating point is below drag curve (vehicle accelerates more than driver model allows; engine's drag load is not sufficient for limited acceleration + /// * ResponseGearShift: gearbox needs to shift gears, vehicle can not accelerate (traction interruption) + /// * ResponseFailTimeInterval: + /// </returns> + protected IResponse CoastOrRollAction(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient, + bool rollAction) + { + var requestedOperatingPoint = ComputeAcceleration(ds, DataBus.VehicleSpeed); + DriverAcceleration = requestedOperatingPoint.Acceleration; + var initialResponse = NextComponent.Request(absTime, requestedOperatingPoint.SimulationInterval, + requestedOperatingPoint.Acceleration, gradient, dryRun: true); + + OperatingPoint searchedOperatingPoint; + try { + searchedOperatingPoint = SearchOperatingPoint(absTime, requestedOperatingPoint.SimulationDistance, + gradient, + requestedOperatingPoint.Acceleration, initialResponse, coastingOrRoll: true); + } catch (VectoEngineSpeedTooLowException) { + // in case of an exception during search the engine-speed got too low - gear disengaged --> try again with disengaged gear. + searchedOperatingPoint = SearchOperatingPoint(absTime, requestedOperatingPoint.SimulationDistance, + gradient, + requestedOperatingPoint.Acceleration, initialResponse, coastingOrRoll: true); + } + + if (!ds.IsEqual(searchedOperatingPoint.SimulationDistance)) { + // vehicle is at low speed, coasting would lead to stop before ds is reached: reduce simulated distance to stop distance. + Log.Debug( + "SearchOperatingPoint reduced the max. distance: {0} -> {1}. Issue new request from driving cycle!", + searchedOperatingPoint.SimulationDistance, ds); + CurrentState.Response = new ResponseDrivingCycleDistanceExceeded { + Source = this, + MaxDistance = searchedOperatingPoint.SimulationDistance, + Acceleration = searchedOperatingPoint.Acceleration, + SimulationInterval = searchedOperatingPoint.SimulationInterval, + OperatingPoint = searchedOperatingPoint + }; + return CurrentState.Response; + } + + Log.Debug("Found operating point for {2}. dt: {0}, acceleration: {1}", + searchedOperatingPoint.SimulationInterval, + searchedOperatingPoint.Acceleration, rollAction ? "ROLL" : "COAST"); + + var limitedOperatingPoint = LimitAccelerationByDriverModel(searchedOperatingPoint, + rollAction ? LimitationMode.NoLimitation : LimitationMode.LimitDecelerationDriver); + + // compute speed at the end of the simulation interval. if it exceeds the limit -> return + var v2 = DataBus.VehicleSpeed + + limitedOperatingPoint.Acceleration * limitedOperatingPoint.SimulationInterval; + if (v2 > maxVelocity && limitedOperatingPoint.Acceleration.IsGreaterOrEqual(0)) { + Log.Debug("vehicle's velocity would exceed given max speed. v2: {0}, max speed: {1}", v2, maxVelocity); + return new ResponseSpeedLimitExceeded() { Source = this }; + } + + DriverAcceleration = limitedOperatingPoint.Acceleration; + var response = NextComponent.Request(absTime, limitedOperatingPoint.SimulationInterval, + limitedOperatingPoint.Acceleration, gradient); + + response.SimulationInterval = limitedOperatingPoint.SimulationInterval; + response.SimulationDistance = ds; + response.Acceleration = limitedOperatingPoint.Acceleration; + response.OperatingPoint = limitedOperatingPoint; + + response.Switch(). + Case<ResponseSuccess>(). + Case<ResponseUnderload>(). // driver limits acceleration, operating point may be below engine's + //drag load resp. below 0 + Case<ResponseOverload>(). // driver limits acceleration, operating point may be above 0 (GBX), use brakes + Case<ResponseEngineSpeedTooHigh>(). // reduce acceleration/vehicle speed + Case<ResponseGearShift>(). + Case<ResponseFailTimeInterval>(r => { + response = new ResponseDrivingCycleDistanceExceeded { + Source = this, + MaxDistance = r.Acceleration / 2 * r.DeltaT * r.DeltaT + DataBus.VehicleSpeed * r.DeltaT + }; + }). + Default( + () => { + throw new UnexpectedResponseException( + "CoastOrRoll Action: unhandled response from powertrain.", response); + }); + + CurrentState.Response = response; + CurrentState.Acceleration = response.Acceleration; + CurrentState.dt = response.SimulationInterval; + return response; + } + + public IResponse DrivingActionBrake(Second absTime, Meter ds, MeterPerSecond nextTargetSpeed, Radian gradient, + IResponse previousResponse = null, Meter targetDistance = null) + { + CurrentAction = "BRAKE"; + IterationStatistics.Increment(this, "Brake"); + Log.Debug("DrivingAction Brake"); + + IResponse retVal = null; + + var operatingPoint = ComputeAcceleration(ds, nextTargetSpeed); + + //if (operatingPoint.Acceleration.IsSmaller(0)) { + operatingPoint = IncreaseDecelerationToMaxWithinSpeedRange(operatingPoint); + + operatingPoint = + AdaptDecelerationToTargetDistance(ds, nextTargetSpeed, targetDistance, operatingPoint.Acceleration) ?? + operatingPoint; + + DriverAcceleration = operatingPoint.Acceleration; + var response = previousResponse ?? + NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, + gradient); + + var point = operatingPoint; + response.Switch(). + Case<ResponseSuccess>(r => retVal = r). + Case<ResponseOverload>(r => retVal = r) + . // i.e., driving uphill, clutch open, deceleration higher than desired deceleration + Case<ResponseUnderload>(). // will be handled in SearchBrakingPower + Case<ResponseEngineSpeedTooHigh>(r => { + Log.Debug("Engine speeed was too high, search for appropriate acceleration first."); + operatingPoint = SearchOperatingPoint(absTime, ds, gradient, point.Acceleration, + response); + }). // will be handled in SearchBrakingPower + Case<ResponseGearShift>(). // will be handled in SearchBrakingPower + Case<ResponseFailTimeInterval>(r => + retVal = new ResponseDrivingCycleDistanceExceeded() { + Source = this, + MaxDistance = DataBus.VehicleSpeed * r.DeltaT + point.Acceleration / 2 * r.DeltaT * r.DeltaT + }). + Default(r => { + throw new UnexpectedResponseException("DrivingAction Brake: first request.", r); + }); + + if (retVal != null) { + CurrentState.Acceleration = operatingPoint.Acceleration; + CurrentState.dt = operatingPoint.SimulationInterval; + CurrentState.Response = retVal; + retVal.Acceleration = operatingPoint.Acceleration; + retVal.SimulationInterval = operatingPoint.SimulationInterval; + retVal.SimulationDistance = ds; + retVal.OperatingPoint = operatingPoint; + return retVal; + } + + operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, + operatingPoint.Acceleration, response); + + if (!ds.IsEqual(operatingPoint.SimulationDistance, 1E-15.SI<Meter>())) { + Log.Info( + "SearchOperatingPoint Braking reduced the max. distance: {0} -> {1}. Issue new request from driving cycle!", + operatingPoint.SimulationDistance, ds); + return new ResponseDrivingCycleDistanceExceeded { + Source = this, + MaxDistance = operatingPoint.SimulationDistance + }; + } + + Log.Debug("Found operating point for braking. dt: {0}, acceleration: {1} brakingPower: {2}", + operatingPoint.SimulationInterval, + operatingPoint.Acceleration, DataBus.BrakePower); + if (DataBus.BrakePower < 0) { + var overload = new ResponseOverload { + Source = this, + BrakePower = DataBus.BrakePower, + Acceleration = operatingPoint.Acceleration + }; + DataBus.BrakePower = 0.SI<Watt>(); + return overload; + } + + DriverAcceleration = operatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, + gradient); + + retVal.Switch(). + Case<ResponseSuccess>(). + Case<ResponseGearShift>(). + Case<ResponseFailTimeInterval>(r => + retVal = new ResponseDrivingCycleDistanceExceeded() { + Source = this, + MaxDistance = + DataBus.VehicleSpeed * r.DeltaT + operatingPoint.Acceleration / 2 * r.DeltaT * r.DeltaT + }). + Case<ResponseUnderload>(r => { + if (DataBus.GearboxType.AutomaticTransmission()) { + operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, + operatingPoint.Acceleration, response); + DriverAcceleration = operatingPoint.Acceleration; + retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, + operatingPoint.Acceleration, gradient); + } + }). + Case<ResponseOverload>(r => { + if (DataBus.GearboxType.AutomaticTransmission()) { + // overload may happen because of gearshift between search and actual request, search again + var i = 5; + while (i-- > 0 && !(retVal is ResponseSuccess)) { + DataBus.BrakePower = 0.SI<Watt>(); + operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, + operatingPoint.Acceleration, response); + DriverAcceleration = operatingPoint.Acceleration; + if (DataBus.BrakePower.IsSmaller(0)) { + DataBus.BrakePower = 0.SI<Watt>(); + + operatingPoint = SearchOperatingPoint(absTime, ds, gradient, 0.SI<MeterPerSquareSecond>(), r); + } + retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, + operatingPoint.Acceleration, gradient); + } + } else { + throw new UnexpectedResponseException( + "DrivingAction Brake: request failed after braking power was found.", r); + } + }). + Default( + r => { + throw new UnexpectedResponseException( + "DrivingAction Brake: request failed after braking power was found.", r); + }); + CurrentState.Acceleration = operatingPoint.Acceleration; + CurrentState.dt = operatingPoint.SimulationInterval; + CurrentState.Response = retVal; + retVal.Acceleration = operatingPoint.Acceleration; + retVal.SimulationInterval = operatingPoint.SimulationInterval; + retVal.SimulationDistance = ds; + retVal.OperatingPoint = operatingPoint; + + return retVal; + } + + private OperatingPoint AdaptDecelerationToTargetDistance(Meter ds, MeterPerSecond nextTargetSpeed, + Meter targetDistance, MeterPerSquareSecond acceleration) + { + if (targetDistance != null && targetDistance > DataBus.Distance) { + var tmp = ComputeAcceleration(targetDistance - DataBus.Distance, nextTargetSpeed, false); + if (tmp.Acceleration.IsGreater(acceleration)) { + var operatingPoint = ComputeTimeInterval(tmp.Acceleration, ds); + if (!ds.IsEqual(operatingPoint.SimulationDistance)) { + Log.Error( + "Unexpected Condition: Distance has been adjusted from {0} to {1}, currentVelocity: {2} acceleration: {3}, targetVelocity: {4}", + operatingPoint.SimulationDistance, ds, DataBus.VehicleSpeed, operatingPoint.Acceleration, + nextTargetSpeed); + throw new VectoSimulationException("Simulation distance unexpectedly adjusted! {0} -> {1}", ds, + operatingPoint.SimulationDistance); + } + return operatingPoint; + } + } + return null; + } + + private OperatingPoint IncreaseDecelerationToMaxWithinSpeedRange(OperatingPoint operatingPoint) + { + // if we should brake with the max. deceleration and the deceleration changes within the current interval, take the larger deceleration... + if ( + operatingPoint.Acceleration.IsEqual( + DriverData.AccelerationCurve.Lookup(DataBus.VehicleSpeed).Deceleration)) { + var v2 = DataBus.VehicleSpeed + operatingPoint.Acceleration * operatingPoint.SimulationInterval; + var nextAcceleration = DriverData.AccelerationCurve.Lookup(v2).Deceleration; + var tmp = ComputeTimeInterval(VectoMath.Min(operatingPoint.Acceleration, nextAcceleration), + operatingPoint.SimulationDistance); + if (!operatingPoint.Acceleration.IsEqual(nextAcceleration) && + operatingPoint.SimulationDistance.IsEqual(tmp.SimulationDistance)) { + // only adjust operating point if the acceleration is different but the simulation distance is not modified + // i.e., braking to the next sample point (but a little bit slower) + Log.Debug("adjusting acceleration from {0} to {1}", operatingPoint.Acceleration, tmp.Acceleration); + operatingPoint = tmp; + // ComputeTimeInterval((operatingPoint.Acceleration + tmp.Acceleration) / 2, operatingPoint.SimulationDistance); + } + } + return operatingPoint; + } + + // ================================================ + + /// <summary> + /// + /// </summary> + /// <param name="operatingPoint"></param> + /// <param name="limits"></param> + /// <returns></returns> + private OperatingPoint LimitAccelerationByDriverModel(OperatingPoint operatingPoint, + LimitationMode limits) + { + var limitApplied = false; + var originalAcceleration = operatingPoint.Acceleration; + //if (((limits & LimitationMode.LimitDecelerationLookahead) != 0) && + // operatingPoint.Acceleration < DriverData.LookAheadCoasting.Deceleration) { + // operatingPoint.Acceleration = DriverData.LookAheadCoasting.Deceleration; + // limitApplied = true; + //} + var accelerationLimits = DriverData.AccelerationCurve.Lookup(DataBus.VehicleSpeed); + if (operatingPoint.Acceleration > accelerationLimits.Acceleration) { + operatingPoint.Acceleration = accelerationLimits.Acceleration; + limitApplied = true; + } + if (((limits & LimitationMode.LimitDecelerationDriver) != 0) && + operatingPoint.Acceleration < accelerationLimits.Deceleration) { + operatingPoint.Acceleration = accelerationLimits.Deceleration; + limitApplied = true; + } + if (limitApplied) { + operatingPoint.SimulationInterval = + ComputeTimeInterval(operatingPoint.Acceleration, operatingPoint.SimulationDistance) + .SimulationInterval; + Log.Debug("Limiting acceleration from {0} to {1}, dt: {2}", originalAcceleration, + operatingPoint.Acceleration, operatingPoint.SimulationInterval); + } + return operatingPoint; + } + + /// <summary> + /// Performs a search for the required braking power such that the vehicle accelerates with the given acceleration. + /// Returns a new operating point (a, ds, dt) where ds may be shorter due to vehicle stopping + /// </summary> + /// <returns>operating point (a, ds, dt) such that the vehicle accelerates with the given acceleration.</returns> + private OperatingPoint SearchBrakingPower(Second absTime, Meter ds, Radian gradient, + MeterPerSquareSecond acceleration, IResponse initialResponse) + { + IterationStatistics.Increment(this, "SearchBrakingPower", 0); + + var operatingPoint = new OperatingPoint { SimulationDistance = ds, Acceleration = acceleration }; + operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds); + Watt deltaPower = null; + initialResponse.Switch(). + Case<ResponseGearShift>(r => { + IterationStatistics.Increment(this, "SearchBrakingPower"); + DriverAcceleration = operatingPoint.Acceleration; + var nextResp = NextComponent.Request(absTime, operatingPoint.SimulationInterval, + operatingPoint.Acceleration, + gradient, true); + deltaPower = nextResp.GearboxPowerRequest; + }). + Case<ResponseEngineSpeedTooHigh>(r => { + IterationStatistics.Increment(this, "SearchBrakingPower"); + DriverAcceleration = operatingPoint.Acceleration; + var nextResp = NextComponent.Request(absTime, operatingPoint.SimulationInterval, + operatingPoint.Acceleration, + gradient, true); + deltaPower = nextResp.GearboxPowerRequest; + }). + Case<ResponseUnderload>(r => + deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest). + Default( + r => { + throw new UnexpectedResponseException("cannot use response for searching braking power!", r); + }); + + try { + DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, deltaPower, + deltaPower.Abs() * (DataBus.GearboxType.AutomaticTransmission() ? 0.5 : 1), + getYValue: result => { + var response = (ResponseDryRun)result; + return DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest; + }, + evaluateFunction: x => { + DataBus.BrakePower = x; + operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds); + + IterationStatistics.Increment(this, "SearchBrakingPower"); + DriverAcceleration = operatingPoint.Acceleration; + return NextComponent.Request(absTime, operatingPoint.SimulationInterval, + operatingPoint.Acceleration, gradient, + true); + }, + criterion: result => { + var response = (ResponseDryRun)result; + var delta = DataBus.ClutchClosed(absTime) + ? response.DeltaDragLoad + : response.GearboxPowerRequest; + return delta.Value(); + }); + + return operatingPoint; + } catch (Exception) { + Log.Error("Failed to find operating point for braking power! absTime: {0}", absTime); + throw; + } + } + + protected OperatingPoint SearchOperatingPoint(Second absTime, Meter ds, Radian gradient, + MeterPerSquareSecond acceleration, IResponse initialResponse, bool coastingOrRoll = false) + { + IterationStatistics.Increment(this, "SearchOperatingPoint", 0); + + var retVal = new OperatingPoint { Acceleration = acceleration, SimulationDistance = ds }; + + var actionRoll = !DataBus.ClutchClosed(absTime); + + var origDelta = GetOrigDelta(initialResponse, coastingOrRoll, actionRoll); + + var searchEngineSpeed = initialResponse is ResponseEngineSpeedTooHigh; + + var delta = origDelta; + try { + retVal.Acceleration = SearchAlgorithm.Search(acceleration, delta, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: response => { + var r = (ResponseDryRun)response; + if (searchEngineSpeed) { + return r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); + } + return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); + }, + evaluateFunction: + acc => { + // calculate new time interval only when vehiclespeed and acceleration are != 0 + // else: use same timeinterval as before. + var vehicleDrivesAndAccelerates = !(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0)); + if (vehicleDrivesAndAccelerates) { + var tmp = ComputeTimeInterval(acc, ds); + if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { + throw new VectoSearchAbortedException( + "next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc, + DataBus.VehicleSpeed, tmp.SimulationInterval); + } + retVal.Acceleration = tmp.Acceleration; + retVal.SimulationInterval = tmp.SimulationInterval; + retVal.SimulationDistance = tmp.SimulationDistance; + } + IterationStatistics.Increment(this, "SearchOperatingPoint"); + DriverAcceleration = acc; + var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true); + response.OperatingPoint = retVal; + return response; + }, + criterion: response => { + var r = (ResponseDryRun)response; + if (searchEngineSpeed) { + return r.DeltaEngineSpeed.Value(); + } + delta = actionRoll + ? r.GearboxPowerRequest + : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); + return delta.Value(); + }, + abortCriterion: + (response, cnt) => { + var r = (ResponseDryRun)response; + return r != null && !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); + }); + } catch (VectoSearchAbortedException) { + // search aborted, try to go ahead with the last acceleration + } catch (Exception) { + Log.Error("Failed to find operating point! absTime: {0}", absTime); + throw; + } + + if (!retVal.Acceleration.IsBetween(DriverData.AccelerationCurve.MaxDeceleration(), + DriverData.AccelerationCurve.MaxAcceleration())) { + Log.Info("Operating Point outside driver acceleration limits: a: {0}", retVal.Acceleration); + } + return ComputeTimeInterval(retVal.Acceleration, retVal.SimulationDistance); + } + + private static Watt GetOrigDelta(IResponse initialResponse, bool coastingOrRoll, bool actionRoll) + { + Watt origDelta = null; + if (actionRoll) { + initialResponse.Switch(). + Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). + Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). + Default(r => { + throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); + }); + } else { + initialResponse.Switch(). + Case<ResponseOverload>(r => origDelta = r.Delta). + Case<ResponseEngineSpeedTooHigh>(r => { + origDelta = r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); + }). // search operating point in drive action after overload + Case<ResponseDryRun>(r => origDelta = coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad). + Default(r => { + throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); + }); + } + return origDelta; + } + + /// <summary> + /// compute the acceleration and time-interval such that the vehicle's velocity approaches the given target velocity + /// - first compute the acceleration to reach the targetVelocity within the given distance + /// - limit the acceleration/deceleration by the driver's acceleration curve + /// - compute the time interval required to drive the given distance with the computed acceleration + /// computed acceleration and time interval are stored in CurrentState! + /// </summary> + /// <param name="ds">distance to reach the next target speed</param> + /// <param name="targetVelocity">next vehicle speed to decelerate to</param> + /// <param name="limitByDriverModel">if set to false the required acceleration will be computed, regardless of the driver's acceleration curve</param> + public OperatingPoint ComputeAcceleration(Meter ds, MeterPerSecond targetVelocity, + bool limitByDriverModel = true) + { + var currentSpeed = DataBus.VehicleSpeed; + var retVal = new OperatingPoint() { SimulationDistance = ds }; + + // Δx = (v0+v1)/2 * Δt + // => Δt = 2*Δx/(v0+v1) + var dt = 2 * ds / (currentSpeed + targetVelocity); + + // a = Δv / Δt + var requiredAcceleration = (targetVelocity - currentSpeed) / dt; + + if (!limitByDriverModel) { + return ComputeTimeInterval(requiredAcceleration, ds); + } + + var maxAcceleration = DriverData.AccelerationCurve.Lookup(currentSpeed); + + if (requiredAcceleration > maxAcceleration.Acceleration) { + requiredAcceleration = maxAcceleration.Acceleration; + } + if (requiredAcceleration < maxAcceleration.Deceleration) { + requiredAcceleration = maxAcceleration.Deceleration; + } + + retVal.Acceleration = requiredAcceleration; + retVal = ComputeTimeInterval(retVal.Acceleration, ds); + + if (ds.IsEqual(retVal.SimulationDistance)) { + return retVal; + } + + // this case should not happen, acceleration has been computed such that the target speed + // can be reached within ds. + Log.Error( + "Unexpected Condition: Distance has been adjusted from {0} to {1}, currentVelocity: {2} acceleration: {3}, targetVelocity: {4}", + retVal.SimulationDistance, ds, currentSpeed, CurrentState.Acceleration, targetVelocity); + throw new VectoSimulationException("Simulation distance unexpectedly adjusted! {0} -> {1}", ds, + retVal.SimulationDistance); + } + + /// <summary> + /// computes the distance required to decelerate from the current velocity to the given target velocity considering + /// the drivers acceleration/deceleration curve. + /// </summary> + /// <param name="targetSpeed"></param> + /// <returns></returns> + public Meter ComputeDecelerationDistance(MeterPerSecond targetSpeed) + { + return DriverData.AccelerationCurve.ComputeAccelerationDistance(DataBus.VehicleSpeed, targetSpeed); + } + + /// <summary> + /// Computes the time interval for driving the given distance ds with the vehicle's current speed and the given acceleration. + /// If the distance ds can not be reached (i.e., the vehicle would halt before ds is reached) then the distance parameter is adjusted. + /// Returns a new operating point (a, ds, dt) + /// </summary> + /// <param name="acceleration"></param> + /// <param name="ds"></param> + /// <returns>Operating point (a, ds, dt)</returns> + private OperatingPoint ComputeTimeInterval(MeterPerSquareSecond acceleration, Meter ds) + { + return VectoMath.ComputeTimeInterval(DataBus.VehicleSpeed, acceleration, DataBus.Distance, ds); + } + + /// <summary> + /// simulate a certain time interval where the vehicle is stopped. + /// </summary> + /// <param name="absTime"></param> + /// <param name="dt"></param> + /// <param name="targetVelocity"></param> + /// <param name="gradient"></param> + /// <returns></returns> + public IResponse DrivingActionHalt(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient) + { + CurrentAction = "HALT"; + if (!targetVelocity.IsEqual(0) || !DataBus.VehicleStopped) { + Log.Error("TargetVelocity ({0}) and VehicleVelocity ({1}) must be zero when vehicle is halting!", + targetVelocity, + DataBus.VehicleSpeed); + throw new VectoSimulationException( + "TargetVelocity ({0}) and VehicleVelocity ({1}) must be zero when vehicle is halting!", + targetVelocity, + DataBus.VehicleSpeed); + } + + DriverAcceleration = 0.SI<MeterPerSquareSecond>(); + var retVal = NextComponent.Request(absTime, dt, 0.SI<MeterPerSquareSecond>(), gradient); + + retVal.Switch(). + Case<ResponseGearShift>(r => { + DriverAcceleration = 0.SI<MeterPerSquareSecond>(); + retVal = NextComponent.Request(absTime, dt, 0.SI<MeterPerSquareSecond>(), gradient); + }); + CurrentState.dt = dt; + CurrentState.Acceleration = 0.SI<MeterPerSquareSecond>(); + return retVal; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.acc] = CurrentState.Acceleration; + container.SetDataValue("DriverAction", ActionToNumber(CurrentAction)); + } + + private int ActionToNumber(string currentAction) + { + switch (currentAction.ToUpper()) { + case "HALT": + return 0; + case "ROLL": + return 2; + case "COAST": + return 4; + case "ACCELERATE": + return 6; + case "BRAKE": + return -5; + default: + return -10; + } + } + + protected override void DoCommitSimulationStep() + { + if (!(CurrentState.Response is ResponseSuccess)) { + throw new VectoSimulationException("Previous request did not succeed!"); + } + CurrentState.Response = null; + } + + public class DriverState + { + // ReSharper disable once InconsistentNaming + public Second dt; + public MeterPerSquareSecond Acceleration; + public IResponse Response; + } + + [Flags] + protected enum LimitationMode + { + NoLimitation = 0x0, + LimitDecelerationDriver = 0x2, + //LimitDecelerationLookahead = 0x4 + } + + public DrivingBehavior DriverBehavior { get; set; } + + public MeterPerSquareSecond DriverAcceleration { get; protected set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 8ea0d270916aada48966c3ae5065d1389cab16e3..6682c9725aa171e603600d371a8581beb71bbca1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -29,401 +29,406 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class Gearbox : AbstractGearbox<GearboxState> - { - /// <summary> - /// The shift strategy. - /// </summary> - private readonly IShiftStrategy _strategy; - - /// <summary> - /// Time when a gearbox shift engages a new gear (shift is finished). Is set when shifting is needed. - /// </summary> - private Second _engageTime = 0.SI<Second>(); - - /// <summary> - /// True if gearbox is disengaged (no gear is set). - /// </summary> - protected internal bool Disengaged = true; - - public Second LastUpshift { get; protected internal set; } - - public Second LastDownshift { get; protected internal set; } - - public override GearInfo NextGear - { - get { return _strategy.NextGear; } - } - - public override bool ClutchClosed(Second absTime) - { - return _engageTime.IsSmallerOrEqual(absTime); - } - - public Gearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) : base(container, runData) - { - _strategy = strategy; - _strategy.Gearbox = this; - - LastDownshift = -double.MaxValue.SI<Second>(); - LastUpshift = -double.MaxValue.SI<Second>(); - } - - public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var absTime = 0.SI<Second>(); - var dt = Constants.SimulationSettings.TargetTimeInterval; - - _engageTime = -double.MaxValue.SI<Second>(); - - if (Disengaged) { - Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); - } - - var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - var gearboxTorqueLoss = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); - CurrentState.TorqueLossResult = gearboxTorqueLoss; - - var inTorque = outTorque / ModelData.Gears[Gear].Ratio - + gearboxTorqueLoss.Value; - - PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - PreviousState.Gear = Gear; - Disengaged = false; - - var response = NextComponent.Initialize(inTorque, inAngularVelocity); - - return response; - } - - internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var oldGear = Gear; - Gear = gear; - var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; - var torqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); - CurrentState.TorqueLossResult = torqueLossResult; - var inTorque = outTorque / ModelData.Gears[gear].Ratio + torqueLossResult.Value; - - if (!inAngularVelocity.IsEqual(0)) { - var alpha = ModelData.Inertia.IsEqual(0) - ? 0.SI<PerSquareSecond>() - : outTorque / ModelData.Inertia; - - var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia, - Constants.SimulationSettings.TargetTimeInterval); - inTorque += inertiaPowerLoss / inAngularVelocity; - } - - var response = - (ResponseDryRun) - NextComponent.Request(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, inTorque, - inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity); - //response.Switch(). - // Case<ResponseSuccess>(). - // Case<ResponseOverload>(). - // Case<ResponseUnderload>(). - // Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); }); - - var fullLoad = DataBus.EngineStationaryFullPower(inAngularVelocity); - - Gear = oldGear; - return new ResponseDryRun { - Source = this, - EnginePowerRequest = response.EnginePowerRequest, - EngineSpeed = response.EngineSpeed, - DynamicFullLoadPower = response.DynamicFullLoadPower, - ClutchPowerRequest = response.ClutchPowerRequest, - GearboxPowerRequest = outTorque * outAngularVelocity, - DeltaFullLoad = response.EnginePowerRequest - fullLoad - }; - } - - /// <summary> - /// Requests the Gearbox to deliver torque and angularVelocity - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><description>ResponseDryRun</description></item> - /// <item><description>ResponseOverload</description></item> - /// <item><description>ResponseGearshift</description></item> - /// </list> - /// </returns> - public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - IterationStatistics.Increment(this, "Requests"); - - Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - if (DataBus.VehicleStopped) { - _engageTime = absTime; - LastDownshift = -double.MaxValue.SI<Second>(); - LastUpshift = -double.MaxValue.SI<Second>(); - } - if (DataBus.DriverBehavior == DrivingBehavior.Halted) { - _engageTime = absTime + dt; - } - - if (DataBus.DriverBehavior == DrivingBehavior.Braking && (DataBus.BrakePower.IsGreater(0) || outTorque < 0) && - DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed)) { - _engageTime = VectoMath.Max(_engageTime, absTime + dt); - - return RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - } - - return ClutchClosed(absTime) - ? RequestGearEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun) - : RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); - } - - /// <summary> - /// Requests the Gearbox in Disengaged mode - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><term>ResponseDryRun</term><description>if dryRun, immediate return!</description></item> - /// <item><term>ResponseFailTimeInterval</term><description>if shiftTime would be exceeded by current step</description></item> - /// <item><term>ResponseOverload</term><description>if torque > 0</description></item> - /// <item><term>ResponseUnderload</term><description>if torque < 0</description></item> - /// <item><term>else</term><description>Response from NextComponent</description></item> - /// </list> - /// </returns> - private IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - Disengaged = true; - Log.Debug("Current Gear: Neutral"); - - var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - - var gear = NextGear.Gear; - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var inTorqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); - var inTorque = outTorque / ModelData.Gears[gear].Ratio + inTorqueLossResult.Value; - - var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; - var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) - ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity - : 0.SI<NewtonMeter>(); - inTorque += inertiaTorqueLossOut / ModelData.Gears[gear].Ratio; - var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; - - if (dryRun) { - // if gearbox is disengaged the 0[W]-line is the limit for drag and full load. - var delta = inTorque * avgInAngularVelocity; - return new ResponseDryRun { - Source = this, - GearboxPowerRequest = delta, - DeltaDragLoad = delta, - DeltaFullLoad = delta, - }; - } - - var shiftTimeExceeded = absTime.IsSmaller(_engageTime) && - _engageTime.IsSmaller(absTime + dt, Constants.SimulationSettings.LowerBoundTimeInterval); - // allow 5% tolerance of shift time - if (shiftTimeExceeded && _engageTime - absTime > Constants.SimulationSettings.LowerBoundTimeInterval / 2) { - return new ResponseFailTimeInterval { - Source = this, - DeltaT = _engageTime - absTime, - GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 - }; - } - - if ((inTorque * avgInAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseOverload { - Source = this, - Delta = inTorque * avgInAngularVelocity, - GearboxPowerRequest = inTorque * avgInAngularVelocity - }; - } - - if ((inTorque * avgInAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseUnderload { - Source = this, - Delta = inTorque * avgInAngularVelocity, - GearboxPowerRequest = inTorque * avgInAngularVelocity - }; - } - - //var inTorque = 0.SI<NewtonMeter>(); - if (avgInAngularVelocity.Equals(0.SI<PerSecond>())) { - inTorque = 0.SI<NewtonMeter>(); - } - - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, - outAngularVelocity); - CurrentState.Gear = gear; - CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[gear].Ratio - outTorque; - - var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), inAngularVelocity); - - //CurrentState.InAngularVelocity = response.EngineSpeed; - - response.GearboxPowerRequest = outTorque * avgAngularVelocity; - - return response; - } - - /// <summary> - /// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously. - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item> - /// <item><term>else</term><description>Response from NextComponent.</description></item> - /// </list> - /// </returns> - private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun) - { - // Set a Gear if no gear was set and engineSpeed is not zero - //if (!Disengaged && DataBus.VehicleStopped && !outAngularVelocity.IsEqual(0)) - //{ - // Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); - //} - if (Disengaged && !outAngularVelocity.IsEqual(0)) { - Disengaged = false; - var lastGear = Gear; - Gear = DataBus.VehicleStopped - ? _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity) - : _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); - if (!DataBus.VehicleStopped) { - if (Gear > lastGear) { - LastUpshift = absTime; - } - if (Gear < lastGear) { - LastDownshift = absTime; - } - } - Log.Debug("Gearbox engaged gear {0}", Gear); - } - - var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); - var inTorque = !avgInAngularVelocity.IsEqual(0) - ? outTorque * (avgOutAngularVelocity / avgInAngularVelocity) - : outTorque / ModelData.Gears[Gear].Ratio; - inTorque += inTorqueLossResult.Value; - - var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) - ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity - : 0.SI<NewtonMeter>(); - inTorque += inertiaTorqueLossOut / ModelData.Gears[Gear].Ratio; - - if (dryRun) { - var inertiaTorqueLossIn = avgOutAngularVelocity.IsEqual(0, 1e-9) - ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity / ModelData.Gears[Gear].Ratio; - var dryRunResponse = NextComponent.Request(absTime, dt, inTorque + inertiaTorqueLossIn, inAngularVelocity, true); - dryRunResponse.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - return dryRunResponse; - } - - var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); - var shiftAllowed = !inAngularVelocity.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0); - - if (response is ResponseSuccess && shiftAllowed) { - var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, - response.EngineSpeed, Gear, _engageTime); - - if (shiftRequired) { - _engageTime = absTime + ModelData.TractionInterruption; - - Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, interuptionTime: {2}, out: ({3}, {4}), in: ({5}, {6})", - absTime, - dt, _engageTime, outTorque, outAngularVelocity, inTorque, inAngularVelocity); - - Disengaged = true; - _strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); - Log.Info("Gearbox disengaged"); - - return new ResponseGearShift { - Source = this, - SimulationInterval = ModelData.TractionInterruption, - GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 - }; - } - } - - // this code has to be _after_ the check for a potential gear-shift! - // (the above block issues dry-run requests and thus may update the CurrentState!) - // begin critical section - CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[Gear].Ratio - outTorque; - // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side - CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut; - - - CurrentState.TorqueLossResult = inTorqueLossResult; - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.Gear = Gear; - // end critical section - - - response.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - - return response; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - // (PreviousState.OutAngularVelocity + - //CurrentState.OutAngularVelocity) / 2.0 * ModelData.Gears[Gear].Ratio; - var inPower = CurrentState.InTorque * avgInAngularSpeed; - var outPower = CurrentState.OutTorque * avgOutAngularSpeed; - container[ModalResultField.Gear] = Disengaged || DataBus.VehicleStopped ? 0 : Gear; - container[ModalResultField.P_gbx_loss] = inPower - outPower; - //CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; - container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; - container[ModalResultField.P_gbx_in] = inPower; - container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + - CurrentState.OutAngularVelocity) / 2.0; - container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; - } - - protected override void DoCommitSimulationStep() - { - if (!Disengaged) { - if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { - Log.Warn( - "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", - Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque, - ModelData.Gears[Gear].Ratio); - if (DataBus.ExecutionMode == ExecutionMode.Declaration) { - throw new VectoException( - "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", - Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque, - ModelData.Gears[Gear].Ratio); - } - } - } - if (DataBus.VehicleStopped) { - Disengaged = true; - _engageTime = -double.MaxValue.SI<Second>(); - } - base.DoCommitSimulationStep(); - } - } +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class Gearbox : AbstractGearbox<GearboxState> + { + /// <summary> + /// The shift strategy. + /// </summary> + private readonly IShiftStrategy _strategy; + + /// <summary> + /// Time when a gearbox shift engages a new gear (shift is finished). Is set when shifting is needed. + /// </summary> + private Second _engageTime = 0.SI<Second>(); + + /// <summary> + /// True if gearbox is disengaged (no gear is set). + /// </summary> + protected internal bool Disengaged = true; + + public Second LastUpshift { get; protected internal set; } + + public Second LastDownshift { get; protected internal set; } + + public override GearInfo NextGear + { + get { return _strategy.NextGear; } + } + + public override bool ClutchClosed(Second absTime) + { + return _engageTime.IsSmallerOrEqual(absTime); + } + + public Gearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) : base(container, runData) + { + _strategy = strategy; + _strategy.Gearbox = this; + + LastDownshift = -double.MaxValue.SI<Second>(); + LastUpshift = -double.MaxValue.SI<Second>(); + } + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var absTime = 0.SI<Second>(); + var dt = Constants.SimulationSettings.TargetTimeInterval; + + _engageTime = -double.MaxValue.SI<Second>(); + + if (Disengaged) { + Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + } + + var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + var gearboxTorqueLoss = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); + CurrentState.TorqueLossResult = gearboxTorqueLoss; + + var inTorque = outTorque / ModelData.Gears[Gear].Ratio + + gearboxTorqueLoss.Value; + + PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + PreviousState.Gear = Gear; + Disengaged = false; + + var response = NextComponent.Initialize(inTorque, inAngularVelocity); + + return response; + } + + internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var oldGear = Gear; + Gear = gear; + var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; + var torqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque); + CurrentState.TorqueLossResult = torqueLossResult; + var inTorque = outTorque / ModelData.Gears[gear].Ratio + torqueLossResult.Value; + + if (!inAngularVelocity.IsEqual(0)) { + var alpha = ModelData.Inertia.IsEqual(0) + ? 0.SI<PerSquareSecond>() + : outTorque / ModelData.Inertia; + + var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia, + Constants.SimulationSettings.TargetTimeInterval); + inTorque += inertiaPowerLoss / inAngularVelocity; + } + + var response = + (ResponseDryRun) + NextComponent.Request(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, inTorque, + inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity); + //response.Switch(). + // Case<ResponseSuccess>(). + // Case<ResponseOverload>(). + // Case<ResponseUnderload>(). + // Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); }); + + var fullLoad = DataBus.EngineStationaryFullPower(inAngularVelocity); + + Gear = oldGear; + return new ResponseDryRun { + Source = this, + EnginePowerRequest = response.EnginePowerRequest, + EngineSpeed = response.EngineSpeed, + DynamicFullLoadPower = response.DynamicFullLoadPower, + ClutchPowerRequest = response.ClutchPowerRequest, + GearboxPowerRequest = outTorque * outAngularVelocity, + DeltaFullLoad = response.EnginePowerRequest - fullLoad + }; + } + + /// <summary> + /// Requests the Gearbox to deliver torque and angularVelocity + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><description>ResponseDryRun</description></item> + /// <item><description>ResponseOverload</description></item> + /// <item><description>ResponseGearshift</description></item> + /// </list> + /// </returns> + public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + IterationStatistics.Increment(this, "Requests"); + + Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); + if (DataBus.VehicleStopped) { + _engageTime = absTime; + LastDownshift = -double.MaxValue.SI<Second>(); + LastUpshift = -double.MaxValue.SI<Second>(); + } + if (DataBus.DriverBehavior == DrivingBehavior.Halted) { + _engageTime = absTime + dt; + } + + if (DataBus.DriverBehavior == DrivingBehavior.Braking && (DataBus.BrakePower.IsGreater(0) || outTorque < 0) && + DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed)) { + _engageTime = VectoMath.Max(_engageTime, absTime + dt); + + return RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + + return ClutchClosed(absTime) + ? RequestGearEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun) + : RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + + /// <summary> + /// Requests the Gearbox in Disengaged mode + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><term>ResponseDryRun</term><description>if dryRun, immediate return!</description></item> + /// <item><term>ResponseFailTimeInterval</term><description>if shiftTime would be exceeded by current step</description></item> + /// <item><term>ResponseOverload</term><description>if torque > 0</description></item> + /// <item><term>ResponseUnderload</term><description>if torque < 0</description></item> + /// <item><term>else</term><description>Response from NextComponent</description></item> + /// </list> + /// </returns> + private IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + Disengaged = true; + Log.Debug("Current Gear: Neutral"); + + var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + + var gear = NextGear.Gear; + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var inTorqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); + var inTorque = outTorque / ModelData.Gears[gear].Ratio + inTorqueLossResult.Value; + + var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; + var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) + ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity + : 0.SI<NewtonMeter>(); + inTorque += inertiaTorqueLossOut / ModelData.Gears[gear].Ratio; + var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; + + if (dryRun) { + // if gearbox is disengaged the 0[W]-line is the limit for drag and full load. + var delta = inTorque * avgInAngularVelocity; + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = delta, + DeltaDragLoad = delta, + DeltaFullLoad = delta, + }; + } + + var shiftTimeExceeded = absTime.IsSmaller(_engageTime) && + _engageTime.IsSmaller(absTime + dt, Constants.SimulationSettings.LowerBoundTimeInterval); + // allow 5% tolerance of shift time + if (shiftTimeExceeded && _engageTime - absTime > Constants.SimulationSettings.LowerBoundTimeInterval / 2) { + return new ResponseFailTimeInterval { + Source = this, + DeltaT = _engageTime - absTime, + GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 + }; + } + + if ((inTorque * avgInAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseOverload { + Source = this, + Delta = inTorque * avgInAngularVelocity, + GearboxPowerRequest = inTorque * avgInAngularVelocity + }; + } + + if ((inTorque * avgInAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) { + return new ResponseUnderload { + Source = this, + Delta = inTorque * avgInAngularVelocity, + GearboxPowerRequest = inTorque * avgInAngularVelocity + }; + } + + //var inTorque = 0.SI<NewtonMeter>(); + if (avgInAngularVelocity.Equals(0.SI<PerSecond>())) { + inTorque = 0.SI<NewtonMeter>(); + } + + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, + outAngularVelocity); + CurrentState.Gear = gear; + CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[gear].Ratio - outTorque; + + var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), inAngularVelocity); + + //CurrentState.InAngularVelocity = response.EngineSpeed; + + response.GearboxPowerRequest = outTorque * avgAngularVelocity; + + return response; + } + + /// <summary> + /// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously. + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item> + /// <item><term>else</term><description>Response from NextComponent.</description></item> + /// </list> + /// </returns> + private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun) + { + // Set a Gear if no gear was set and engineSpeed is not zero + //if (!Disengaged && DataBus.VehicleStopped && !outAngularVelocity.IsEqual(0)) + //{ + // Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + //} + if (Disengaged && !outAngularVelocity.IsEqual(0)) { + ReEngageGear(absTime, dt, outTorque, outAngularVelocity); + Log.Debug("Gearbox engaged gear {0}", Gear); + } + + var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0; + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque); + var inTorque = !avgInAngularVelocity.IsEqual(0) + ? outTorque * (avgOutAngularVelocity / avgInAngularVelocity) + : outTorque / ModelData.Gears[Gear].Ratio; + inTorque += inTorqueLossResult.Value; + + var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0) + ? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity + : 0.SI<NewtonMeter>(); + inTorque += inertiaTorqueLossOut / ModelData.Gears[Gear].Ratio; + + if (dryRun) { + var inertiaTorqueLossIn = avgOutAngularVelocity.IsEqual(0, 1e-9) + ? 0.SI<NewtonMeter>() + : Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity / ModelData.Gears[Gear].Ratio; + var dryRunResponse = NextComponent.Request(absTime, dt, inTorque + inertiaTorqueLossIn, inAngularVelocity, true); + dryRunResponse.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + return dryRunResponse; + } + + var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); + var shiftAllowed = !inAngularVelocity.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0); + + if (response is ResponseSuccess && shiftAllowed) { + var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, + response.EngineSpeed, Gear, _engageTime); + + if (shiftRequired) { + _engageTime = absTime + ModelData.TractionInterruption; + + Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, interuptionTime: {2}, out: ({3}, {4}), in: ({5}, {6})", + absTime, + dt, _engageTime, outTorque, outAngularVelocity, inTorque, inAngularVelocity); + + Disengaged = true; + _strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); + Log.Info("Gearbox disengaged"); + + return new ResponseGearShift { + Source = this, + SimulationInterval = ModelData.TractionInterruption, + GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0 + }; + } + } + + // this code has to be _after_ the check for a potential gear-shift! + // (the above block issues dry-run requests and thus may update the CurrentState!) + // begin critical section + CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[Gear].Ratio - outTorque; + // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side + CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut; + + + CurrentState.TorqueLossResult = inTorqueLossResult; + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + // end critical section + + + response.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + + return response; + } + + private void ReEngageGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + Disengaged = false; + var lastGear = Gear; + Gear = DataBus.VehicleStopped + ? _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity) + : _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); + if (!DataBus.VehicleStopped) { + if (Gear > lastGear) { + LastUpshift = absTime; + } + if (Gear < lastGear) { + LastDownshift = absTime; + } + } + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + // (PreviousState.OutAngularVelocity + + //CurrentState.OutAngularVelocity) / 2.0 * ModelData.Gears[Gear].Ratio; + var inPower = CurrentState.InTorque * avgInAngularSpeed; + var outPower = CurrentState.OutTorque * avgOutAngularSpeed; + container[ModalResultField.Gear] = Disengaged || DataBus.VehicleStopped ? 0 : Gear; + container[ModalResultField.P_gbx_loss] = inPower - outPower; + //CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed; + container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed; + container[ModalResultField.P_gbx_in] = inPower; + container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + + CurrentState.OutAngularVelocity) / 2.0; + container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; + } + + protected override void DoCommitSimulationStep() + { + if (!Disengaged) { + if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) { + Log.Warn( + "Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", + Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque, + ModelData.Gears[Gear].Ratio); + if (DataBus.ExecutionMode == ExecutionMode.Declaration) { + throw new VectoException( + "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}", + Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque, + ModelData.Gears[Gear].Ratio); + } + } + } + if (DataBus.VehicleStopped) { + Disengaged = true; + _engageTime = -double.MaxValue.SI<Second>(); + } + base.DoCommitSimulationStep(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs index cecf32836f9773c7399efb08d54627d8efbc3888..424e42675af0b118fa62556b85e7a1cc3d86777b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs @@ -29,337 +29,358 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Driving Cycle for the Measured Speed Gear driving cycle. - /// </summary> - public class MeasuredSpeedDrivingCycle : - StatefulProviderComponent - <MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>, - IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider, - ISimulationOutPort - { - public class DrivingCycleState - { - public DrivingCycleState Clone() - { - return new DrivingCycleState { - Distance = Distance, - }; - } - - public Meter Distance; - public Meter SimulationDistance; - public MeterPerSquareSecond Acceleration; - } - - protected readonly IDrivingCycleData Data; - - protected internal readonly DrivingCycleEnumerator CycleIterator; - - protected Second AbsTime { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - public MeasuredSpeedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) - : base(container) - { - Data = cycle; - CycleIterator = new DrivingCycleEnumerator(cycle); - - PreviousState = new DrivingCycleState { - Distance = 0.SI<Meter>(), - }; - CurrentState = PreviousState.Clone(); - } - - public IResponse Initialize() - { - var first = Data.Entries.First(); - - AbsTime = first.Time; - - var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); - if (!(response is ResponseSuccess)) { - throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle: Couldn't find start gear.", response); - } - - response.AbsTime = AbsTime; - return response; - } - - public IResponse Request(Second absTime, Meter ds) - { - Log.Fatal("MeasuredSpeed Cycle can not handle distance request."); - throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request."); - } - - public virtual IResponse Request(Second absTime, Second dt) - { - var debug = new DebugData(); - - // cycle finished - if (CycleIterator.LastEntry && absTime >= CycleIterator.RightSample.Time) { - return new ResponseCycleFinished { AbsTime = absTime, Source = this }; - } - - if (CycleIterator.RightSample == null) { - throw new VectoException("Exceeding cycle!"); - } - // interval exceeded - if ((absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = CycleIterator.RightSample.Time - absTime - }; - } - - // calc acceleration from speed diff vehicle to cycle - var targetSpeed = CycleIterator.RightSample.VehicleTargetSpeed; - if (targetSpeed.IsEqual(0.KMPHtoMeterPerSecond(), 0.5.KMPHtoMeterPerSecond())) { - targetSpeed = 0.KMPHtoMeterPerSecond(); - } - var deltaV = targetSpeed - DataBus.VehicleSpeed; - var deltaT = CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time; - - if (DataBus.VehicleSpeed.IsSmaller(0)) { - throw new VectoSimulationException("vehicle velocity is smaller than zero"); - } - - if (deltaT.IsSmaller(0)) { - throw new VectoSimulationException("deltaT is smaller than zero"); - } - - var acceleration = deltaV / deltaT; - var gradient = CycleIterator.LeftSample.RoadGradient; - DriverAcceleration = acceleration; - DriverBehavior = acceleration < 0 - ? DriverBehavior = DrivingBehavior.Braking - : DriverBehavior = DrivingBehavior.Driving; - if (DataBus.VehicleStopped && acceleration.IsEqual(0)) { - DriverBehavior = DrivingBehavior.Halted; - } - - IResponse response; - var responseCount = 0; - do { - response = NextComponent.Request(absTime, dt, acceleration, gradient); - debug.Add(response); - response.Switch() - .Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient)) - .Case<ResponseUnderload>(r => { - var acceleration1 = acceleration; - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, - getYValue: result => DataBus.ClutchClosed(absTime) - ? ((ResponseDryRun)result).DeltaDragLoad - : ((ResponseDryRun)result).GearboxPowerRequest, - evaluateFunction: x => { - DataBus.BrakePower = x; - return NextComponent.Request(absTime, dt, acceleration1, gradient, true); - }, - criterion: y => DataBus.ClutchClosed(absTime) - ? ((ResponseDryRun)y).DeltaDragLoad.Value() - : ((ResponseDryRun)y).GearboxPowerRequest.Value()); - Log.Info( - "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", - absTime, dt, acceleration, gradient, DataBus.BrakePower); - - if (DataBus.BrakePower.IsSmaller(0)) { - Log.Info( - "BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", - absTime, dt, acceleration, gradient, DataBus.BrakePower); - DataBus.BrakePower = 0.SI<Watt>(); - acceleration = SearchAlgorithm.Search(acceleration, r.Delta, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - } - - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseOverload>(r => { - if (DataBus.ClutchClosed(absTime)) { - acceleration = SearchAlgorithm.Search(acceleration, r.Delta, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: - y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - Log.Info( - "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", - absTime, dt, acceleration, gradient); - } else { - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, - getYValue: result => DataBus.ClutchClosed(absTime) - ? ((ResponseDryRun)result).DeltaDragLoad - : ((ResponseDryRun)result).GearboxPowerRequest, - evaluateFunction: x => { - DataBus.BrakePower = x; - return NextComponent.Request(absTime, dt, acceleration, gradient, true); - }, - criterion: y => DataBus.ClutchClosed(absTime) - ? ((ResponseDryRun)y).DeltaDragLoad.Value() - : ((ResponseDryRun)y).GearboxPowerRequest.Value()); - Log.Info( - "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", - absTime, dt, acceleration, gradient, DataBus.BrakePower); - - if (DataBus.BrakePower.IsSmaller(0)) { - Log.Info( - "BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", - absTime, dt, acceleration, gradient, DataBus.BrakePower); - DataBus.BrakePower = 0.SI<Watt>(); - acceleration = SearchAlgorithm.Search(acceleration, r.Delta, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - } - } - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseEngineSpeedTooHigh>(r => { - acceleration = SearchAlgorithm.Search(acceleration, r.DeltaEngineSpeed, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: - y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); - Log.Info( - "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", - absTime, dt, acceleration, gradient); - }) - .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) - .Case<ResponseSuccess>() - .Default( - r => { throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r); }); - } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); - - AbsTime = absTime + dt; - - response.SimulationInterval = dt; - response.Acceleration = acceleration; - debug.Add(response); - - CurrentState.SimulationDistance = acceleration / 2 * dt * dt + DataBus.VehicleSpeed * dt; - if (CurrentState.SimulationDistance.IsSmaller(0)) { - throw new VectoSimulationException( - "MeasuredSpeed: Simulation Distance must not be negative. Driving Backward is not allowed."); - } - - CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance; - CurrentState.Acceleration = acceleration; - - return response; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.dist] = CurrentState.Distance; - container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance; - container[ModalResultField.v_targ] = CycleIterator.LeftSample.VehicleTargetSpeed; - container[ModalResultField.grad] = CycleIterator.LeftSample.RoadGradientPercent; - container[ModalResultField.altitude] = CycleIterator.LeftSample.Altitude; - container[ModalResultField.acc] = CurrentState.Acceleration; - } - - protected override void DoCommitSimulationStep() - { - if ((CycleIterator.RightSample == null) || AbsTime.IsGreaterOrEqual(CycleIterator.RightSample.Time)) { - CycleIterator.MoveNext(); - } - AdvanceState(); - } - - public double Progress - { - get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); } - } - - public CycleData CycleData - { - get { - return new CycleData { - AbsTime = CycleIterator.LeftSample.Time, - AbsDistance = null, - LeftSample = CycleIterator.LeftSample, - RightSample = CycleIterator.RightSample, - }; - } - } - - public bool PTOActive - { - get { return false; } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return new DrivingCycleData.DrivingCycleEntry(CycleIterator.RightSample); - //throw new System.NotImplementedException(); - } - - public Meter Altitude - { - get { return CycleIterator.LeftSample.Altitude; } - } - - public Meter CycleStartDistance - { - get { return 0.SI<Meter>(); } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - throw new NotImplementedException(); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); - - var iterator = CycleIterator.Clone(); - do { - retVal.Add(iterator.RightSample); - } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); - - return retVal; - } - - public void FinishSimulation() - { - Data.Finish(); - } - - public DrivingBehavior DriverBehavior { get; internal set; } - - public MeterPerSquareSecond DriverAcceleration { get; protected set; } - - public Meter Distance - { - get { return CurrentState.Distance; } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Driving Cycle for the Measured Speed Gear driving cycle. + /// </summary> + public class MeasuredSpeedDrivingCycle : + StatefulProviderComponent + <MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>, + IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider, + ISimulationOutPort + { + public class DrivingCycleState + { + public DrivingCycleState Clone() + { + return new DrivingCycleState { + Distance = Distance, + }; + } + + public Meter Distance; + public Meter SimulationDistance; + public MeterPerSquareSecond Acceleration; + } + + protected readonly IDrivingCycleData Data; + + protected internal readonly DrivingCycleEnumerator CycleIterator; + + protected Second AbsTime { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + public MeasuredSpeedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) + : base(container) + { + Data = cycle; + CycleIterator = new DrivingCycleEnumerator(cycle); + + PreviousState = new DrivingCycleState { + Distance = 0.SI<Meter>(), + }; + CurrentState = PreviousState.Clone(); + } + + public IResponse Initialize() + { + var first = Data.Entries.First(); + + AbsTime = first.Time; + + var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); + if (!(response is ResponseSuccess)) { + throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle: Couldn't find start gear.", response); + } + + response.AbsTime = AbsTime; + return response; + } + + public IResponse Request(Second absTime, Meter ds) + { + Log.Fatal("MeasuredSpeed Cycle can not handle distance request."); + throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request."); + } + + public virtual IResponse Request(Second absTime, Second dt) + { + var debug = new DebugData(); + + // cycle finished + if (CycleIterator.LastEntry && absTime >= CycleIterator.RightSample.Time) { + return new ResponseCycleFinished { AbsTime = absTime, Source = this }; + } + + if (CycleIterator.RightSample == null) { + throw new VectoException("Exceeding cycle!"); + } + // interval exceeded + if ((absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = CycleIterator.RightSample.Time - absTime + }; + } + + // calc acceleration from speed diff vehicle to cycle + var targetSpeed = CycleIterator.RightSample.VehicleTargetSpeed; + if (targetSpeed.IsEqual(0.KMPHtoMeterPerSecond(), 0.5.KMPHtoMeterPerSecond())) { + targetSpeed = 0.KMPHtoMeterPerSecond(); + } + var deltaV = targetSpeed - DataBus.VehicleSpeed; + var deltaT = CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time; + + if (DataBus.VehicleSpeed.IsSmaller(0)) { + throw new VectoSimulationException("vehicle velocity is smaller than zero"); + } + + if (deltaT.IsSmaller(0)) { + throw new VectoSimulationException("deltaT is smaller than zero"); + } + + var acceleration = deltaV / deltaT; + var gradient = CycleIterator.LeftSample.RoadGradient; + DriverAcceleration = acceleration; + DriverBehavior = acceleration < 0 + ? DriverBehavior = DrivingBehavior.Braking + : DriverBehavior = DrivingBehavior.Driving; + if (DataBus.VehicleStopped && acceleration.IsEqual(0)) { + DriverBehavior = DrivingBehavior.Halted; + } + + IResponse response; + var responseCount = 0; + do { + response = NextComponent.Request(absTime, dt, acceleration, gradient); + debug.Add(response); + response.Switch() + .Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient)) + .Case<ResponseUnderload>(r => { + response = HandleUnderload(absTime, dt, r, gradient, ref acceleration); + }) + .Case<ResponseOverload>(r => { + response = HandleOverload(absTime, dt, r, gradient, ref acceleration); + }) + .Case<ResponseEngineSpeedTooHigh>(r => { + acceleration = SearchAlgorithm.Search(acceleration, r.DeltaEngineSpeed, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, + evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), + criterion: + y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); + Log.Info( + "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", + absTime, dt, acceleration, gradient); + }) + .Case<ResponseFailTimeInterval>(r => { + dt = r.DeltaT; + }) + .Case<ResponseSuccess>() + .Default( + r => { + throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r); + }); + } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); + + AbsTime = absTime + dt; + + response.SimulationInterval = dt; + response.Acceleration = acceleration; + debug.Add(response); + + CurrentState.SimulationDistance = acceleration / 2 * dt * dt + DataBus.VehicleSpeed * dt; + if (CurrentState.SimulationDistance.IsSmaller(0)) { + throw new VectoSimulationException( + "MeasuredSpeed: Simulation Distance must not be negative. Driving Backward is not allowed."); + } + + CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance; + CurrentState.Acceleration = acceleration; + + return response; + } + + private IResponse HandleUnderload(Second absTime, Second dt, ResponseUnderload r, + Radian gradient, ref MeterPerSquareSecond acceleration) + { + MeterPerSquareSecond acc = acceleration; + DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, + getYValue: result => DataBus.ClutchClosed(absTime) + ? ((ResponseDryRun)result).DeltaDragLoad + : ((ResponseDryRun)result).GearboxPowerRequest, + evaluateFunction: x => { + DataBus.BrakePower = x; + return NextComponent.Request(absTime, dt, acc, gradient, true); + }, + criterion: y => DataBus.ClutchClosed(absTime) + ? ((ResponseDryRun)y).DeltaDragLoad.Value() + : ((ResponseDryRun)y).GearboxPowerRequest.Value()); + Log.Info( + "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", + absTime, dt, acceleration, gradient, DataBus.BrakePower); + + if (DataBus.BrakePower.IsSmaller(0)) { + Log.Info( + "BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", + absTime, dt, acceleration, gradient, DataBus.BrakePower); + DataBus.BrakePower = 0.SI<Watt>(); + acceleration = SearchAlgorithm.Search(acceleration, r.Delta, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), + criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + } + + var response = NextComponent.Request(absTime, dt, acceleration, gradient); + return response; + } + + private IResponse HandleOverload(Second absTime, Second dt, ResponseOverload r, Radian gradient, + ref MeterPerSquareSecond acceleration) + { + IResponse response; + if (DataBus.ClutchClosed(absTime)) { + acceleration = SearchAlgorithm.Search(acceleration, r.Delta, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), + criterion: + y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + Log.Info( + "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", + absTime, dt, acceleration, gradient); + } else { + var acc = acceleration; + DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, + getYValue: result => DataBus.ClutchClosed(absTime) + ? ((ResponseDryRun)result).DeltaDragLoad + : ((ResponseDryRun)result).GearboxPowerRequest, + evaluateFunction: x => { + DataBus.BrakePower = x; + return NextComponent.Request(absTime, dt, acc, gradient, true); + }, + criterion: y => DataBus.ClutchClosed(absTime) + ? ((ResponseDryRun)y).DeltaDragLoad.Value() + : ((ResponseDryRun)y).GearboxPowerRequest.Value()); + Log.Info( + "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", + absTime, dt, acceleration, gradient, DataBus.BrakePower); + + if (DataBus.BrakePower.IsSmaller(0)) { + Log.Info( + "BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", + absTime, dt, acceleration, gradient, DataBus.BrakePower); + DataBus.BrakePower = 0.SI<Watt>(); + acceleration = SearchAlgorithm.Search(acceleration, r.Delta, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), + criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + } + } + response = NextComponent.Request(absTime, dt, acceleration, gradient); + return response; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.dist] = CurrentState.Distance; + container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance; + container[ModalResultField.v_targ] = CycleIterator.LeftSample.VehicleTargetSpeed; + container[ModalResultField.grad] = CycleIterator.LeftSample.RoadGradientPercent; + container[ModalResultField.altitude] = CycleIterator.LeftSample.Altitude; + container[ModalResultField.acc] = CurrentState.Acceleration; + } + + protected override void DoCommitSimulationStep() + { + if ((CycleIterator.RightSample == null) || AbsTime.IsGreaterOrEqual(CycleIterator.RightSample.Time)) { + CycleIterator.MoveNext(); + } + AdvanceState(); + } + + public double Progress + { + get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); } + } + + public CycleData CycleData + { + get + { + return new CycleData { + AbsTime = CycleIterator.LeftSample.Time, + AbsDistance = null, + LeftSample = CycleIterator.LeftSample, + RightSample = CycleIterator.RightSample, + }; + } + } + + public bool PTOActive + { + get { return false; } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return new DrivingCycleData.DrivingCycleEntry(CycleIterator.RightSample); + //throw new System.NotImplementedException(); + } + + public Meter Altitude + { + get { return CycleIterator.LeftSample.Altitude; } + } + + public Meter CycleStartDistance + { + get { return 0.SI<Meter>(); } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + throw new NotImplementedException(); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); + + var iterator = CycleIterator.Clone(); + do { + retVal.Add(iterator.RightSample); + } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); + + return retVal; + } + + public void FinishSimulation() + { + Data.Finish(); + } + + public DrivingBehavior DriverBehavior { get; internal set; } + + public MeterPerSquareSecond DriverAcceleration { get; protected set; } + + public Meter Distance + { + get { return CurrentState.Distance; } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs index de4431d73f2da57d2d87a4a19a94e6c34cee0c9d..098c05e6f802d251de62ffd15ceccc4ca99ffa43 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs @@ -29,138 +29,138 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Driving Cycle for the PWheel driving cycle. - /// </summary> - public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo - { - private readonly VehicleData _vehicleData; - - /// <summary> - /// Initializes a new instance of the <see cref="PWheelCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - /// <param name="axleRatio">The axle ratio.</param> - /// <param name="vehicleData"></param> - /// <param name="gearRatios"></param> - public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData, - IDictionary<uint, double> gearRatios) : base(container, cycle) - { - // just to ensure that null-gear has ratio 1 - gearRatios[0] = 1; - _vehicleData = vehicleData; - foreach (var entry in Data.Entries) { - entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); - entry.Torque = entry.PWheel / entry.WheelAngularVelocity; - } - } - - public override IResponse Initialize() - { - var first = Data.Entries[0]; - AbsTime = first.Time; - var response = NextComponent.Initialize(first.Torque, first.WheelAngularVelocity); - response.AbsTime = AbsTime; - return response; - } - - public override IResponse Request(Second absTime, Second dt) - { - if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { - return new ResponseCycleFinished { Source = this }; - } - - // interval exceeded - if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = CycleIterator.RightSample.Time - absTime - }; - } - - return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity); - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel; - base.DoWriteModalResults(container); - } - - #region IDriverInfo - - public MeterPerSecond VehicleSpeed { get; private set; } - - /// <summary> - /// True if the angularVelocity at the wheels is 0. - /// </summary> - public bool VehicleStopped - { - get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); } - } - - public Kilogram VehicleMass - { - get { return _vehicleData.TotalCurbWeight; } - } - - public Kilogram VehicleLoading - { - get { return _vehicleData.Loading; } - } - - public Kilogram TotalMass - { - get { return _vehicleData.TotalVehicleWeight; } - } - - public CubicMeter CargoVolume - { - get { return _vehicleData.CargoVolume; } - } - - public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) - { - throw new System.NotImplementedException(); - } - - public Newton RollingResistance(Radian gradient) - { - throw new System.NotImplementedException(); - } - - public Newton SlopeResistance(Radian gradient) - { - throw new System.NotImplementedException(); - } - - /// <summary> - /// Always Driving. - /// </summary> - public DrivingBehavior DriverBehavior - { - get { return DrivingBehavior.Driving; } - } - - public MeterPerSquareSecond DriverAcceleration - { - get { return 0.SI<MeterPerSquareSecond>(); } - } - - #endregion - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Driving Cycle for the PWheel driving cycle. + /// </summary> + public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo + { + private readonly VehicleData _vehicleData; + + /// <summary> + /// Initializes a new instance of the <see cref="PWheelCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + /// <param name="axleRatio">The axle ratio.</param> + /// <param name="vehicleData"></param> + /// <param name="gearRatios"></param> + public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData, + IDictionary<uint, double> gearRatios) : base(container, cycle) + { + // just to ensure that null-gear has ratio 1 + gearRatios[0] = 1; + _vehicleData = vehicleData; + foreach (var entry in Data.Entries) { + entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); + entry.Torque = entry.PWheel / entry.WheelAngularVelocity; + } + } + + public override IResponse Initialize() + { + var first = Data.Entries[0]; + AbsTime = first.Time; + var response = NextComponent.Initialize(first.Torque, first.WheelAngularVelocity); + response.AbsTime = AbsTime; + return response; + } + + public override IResponse Request(Second absTime, Second dt) + { + if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { + return new ResponseCycleFinished { Source = this }; + } + + // interval exceeded + if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = CycleIterator.RightSample.Time - absTime + }; + } + + return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity); + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel; + base.DoWriteModalResults(container); + } + + #region IDriverInfo + + public MeterPerSecond VehicleSpeed { get; private set; } + + /// <summary> + /// True if the angularVelocity at the wheels is 0. + /// </summary> + public bool VehicleStopped + { + get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); } + } + + public Kilogram VehicleMass + { + get { return _vehicleData.TotalCurbWeight; } + } + + public Kilogram VehicleLoading + { + get { return _vehicleData.Loading; } + } + + public Kilogram TotalMass + { + get { return _vehicleData.TotalVehicleWeight; } + } + + public CubicMeter CargoVolume + { + get { return _vehicleData.CargoVolume; } + } + + public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) + { + throw new System.NotImplementedException(); + } + + public Newton RollingResistance(Radian gradient) + { + throw new System.NotImplementedException(); + } + + public Newton SlopeResistance(Radian gradient) + { + throw new System.NotImplementedException(); + } + + /// <summary> + /// Always Driving. + /// </summary> + public DrivingBehavior DriverBehavior + { + get { return DrivingBehavior.Driving; } + } + + public MeterPerSquareSecond DriverAcceleration + { + get { return 0.SI<MeterPerSquareSecond>(); } + } + + #endregion + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs index 67e0e9125535e42d7c03529c2a56ed003090f7ba..17fd58fa9018e5ff64a3141adff58c6234ecf1bd 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs @@ -29,204 +29,204 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Represents a driving cycle which directly is connected to the powertrain (e.g. engine, or axle gear). - /// </summary> - public class PowertrainDrivingCycle : - StatefulProviderComponent<SimpleComponentState, ISimulationOutPort, ITnInPort, ITnOutPort>, - IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort - { - protected readonly IDrivingCycleData Data; - protected internal readonly DrivingCycleEnumerator CycleIterator; - - protected Second AbsTime { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container) - { - Data = cycle; - CycleIterator = new DrivingCycleEnumerator(Data); - - AbsTime = 0.SI<Second>(); - } - - public virtual IResponse Initialize() - { - var first = Data.Entries[0]; - AbsTime = first.Time; - var response = NextComponent.Initialize(first.Torque, first.AngularVelocity); - response.AbsTime = AbsTime; - return response; - } - - #region ISimulationOutPort - - public IResponse Request(Second absTime, Meter ds) - { - throw new VectoSimulationException("Powertrain Only Simulation can not handle distance request."); - } - - public virtual IResponse Request(Second absTime, Second dt) - { - // cycle finished (no more entries in cycle) - if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { - return new ResponseCycleFinished { Source = this }; - } - - // interval exceeded - if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = CycleIterator.RightSample.Time - absTime - }; - } - - return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity); - } - - protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity) - { - var debug = new DebugData(); - - IResponse response; - var responseCount = 0; - do { - response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity); - CurrentState.InAngularVelocity = angularVelocity; - CurrentState.InTorque = CycleIterator.LeftSample.Torque; - debug.Add(response); - response.Switch() - .Case<ResponseGearShift>( - () => response = NextComponent.Request(absTime, dt, CurrentState.InTorque, angularVelocity)) - .Case<ResponseUnderload>(r => { - var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity); - var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval, - getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), - criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value()); - response = NextComponent.Request(absTime, dt, torque, angularVelocity); - CurrentState.InTorque = torque; - }) - .Case<ResponseOverload>(r => { - var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, 50.SI<NewtonMeter>(), - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), - criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - response = NextComponent.Request(absTime, dt, torque, angularVelocity); - CurrentState.InAngularVelocity = angularVelocity; - }) - .Case<ResponseEngineSpeedTooHigh>(r => { - angularVelocity = SearchAlgorithm.Search(angularVelocity, r.DeltaEngineSpeed, - 1.RPMtoRad(), - getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, - evaluateFunction: x => NextComponent.Request(absTime, dt, CurrentState.InTorque, x, true), - criterion: y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); - }) - .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) - .Case<ResponseSuccess>(() => { }) - .Default( - r => { throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", r); }); - } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); - - AbsTime = absTime + dt; - response.SimulationInterval = dt; - debug.Add(response); - return response; - } - - public double Progress - { - get { return AbsTime.Value() / Data.Entries.Last().Time.Value(); } - } - - #endregion - - #region VectoSimulationComponent - - protected override void DoWriteModalResults(IModalDataContainer container) {} - - protected override void DoCommitSimulationStep() - { - CycleIterator.MoveNext(); - AdvanceState(); - } - - #endregion - - public CycleData CycleData - { - get { - return new CycleData { - AbsTime = CycleIterator.LeftSample.Time, - AbsDistance = null, - LeftSample = CycleIterator.LeftSample, - RightSample = CycleIterator.RightSample, - }; - } - } - - public bool PTOActive - { - get { return true; } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return new DrivingCycleData.DrivingCycleEntry() { - Altitude = 0.SI<Meter>() - }; - } - - public Meter Altitude - { - get { return 0.SI<Meter>(); } - } - - public Meter CycleStartDistance - { - get { return 0.SI<Meter>(); } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - throw new NotImplementedException(); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); - - var iterator = CycleIterator.Clone(); - do { - retVal.Add(iterator.RightSample); - } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); - - return retVal; - } - - public void FinishSimulation() - { - Data.Finish(); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Represents a driving cycle which directly is connected to the powertrain (e.g. engine, or axle gear). + /// </summary> + public class PowertrainDrivingCycle : + StatefulProviderComponent<SimpleComponentState, ISimulationOutPort, ITnInPort, ITnOutPort>, + IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort + { + protected readonly IDrivingCycleData Data; + protected internal readonly DrivingCycleEnumerator CycleIterator; + + protected Second AbsTime { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container) + { + Data = cycle; + CycleIterator = new DrivingCycleEnumerator(Data); + + AbsTime = 0.SI<Second>(); + } + + public virtual IResponse Initialize() + { + var first = Data.Entries[0]; + AbsTime = first.Time; + var response = NextComponent.Initialize(first.Torque, first.AngularVelocity); + response.AbsTime = AbsTime; + return response; + } + + #region ISimulationOutPort + + public IResponse Request(Second absTime, Meter ds) + { + throw new VectoSimulationException("Powertrain Only Simulation can not handle distance request."); + } + + public virtual IResponse Request(Second absTime, Second dt) + { + // cycle finished (no more entries in cycle) + if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) { + return new ResponseCycleFinished { Source = this }; + } + + // interval exceeded + if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = CycleIterator.RightSample.Time - absTime + }; + } + + return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity); + } + + protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity) + { + var debug = new DebugData(); + + IResponse response; + var responseCount = 0; + do { + response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity); + CurrentState.InAngularVelocity = angularVelocity; + CurrentState.InTorque = CycleIterator.LeftSample.Torque; + debug.Add(response); + response.Switch() + .Case<ResponseGearShift>( + () => response = NextComponent.Request(absTime, dt, CurrentState.InTorque, angularVelocity)) + .Case<ResponseUnderload>(r => { + var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity); + var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval, + getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, + evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), + criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value()); + response = NextComponent.Request(absTime, dt, torque, angularVelocity); + CurrentState.InTorque = torque; + }) + .Case<ResponseOverload>(r => { + var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, 50.SI<NewtonMeter>(), + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true), + criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + response = NextComponent.Request(absTime, dt, torque, angularVelocity); + CurrentState.InAngularVelocity = angularVelocity; + }) + .Case<ResponseEngineSpeedTooHigh>(r => { + angularVelocity = SearchAlgorithm.Search(angularVelocity, r.DeltaEngineSpeed, + 1.RPMtoRad(), + getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed, + evaluateFunction: x => NextComponent.Request(absTime, dt, CurrentState.InTorque, x, true), + criterion: y => ((ResponseDryRun)y).DeltaEngineSpeed.Value()); + }) + .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) + .Case<ResponseSuccess>(() => { }) + .Default( + r => { throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", r); }); + } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); + + AbsTime = absTime + dt; + response.SimulationInterval = dt; + debug.Add(response); + return response; + } + + public double Progress + { + get { return AbsTime.Value() / Data.Entries.Last().Time.Value(); } + } + + #endregion + + #region VectoSimulationComponent + + protected override void DoWriteModalResults(IModalDataContainer container) {} + + protected override void DoCommitSimulationStep() + { + CycleIterator.MoveNext(); + AdvanceState(); + } + + #endregion + + public CycleData CycleData + { + get { + return new CycleData { + AbsTime = CycleIterator.LeftSample.Time, + AbsDistance = null, + LeftSample = CycleIterator.LeftSample, + RightSample = CycleIterator.RightSample, + }; + } + } + + public bool PTOActive + { + get { return true; } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return new DrivingCycleData.DrivingCycleEntry() { + Altitude = 0.SI<Meter>() + }; + } + + public Meter Altitude + { + get { return 0.SI<Meter>(); } + } + + public Meter CycleStartDistance + { + get { return 0.SI<Meter>(); } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + throw new NotImplementedException(); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + var retVal = new List<DrivingCycleData.DrivingCycleEntry>(); + + var iterator = CycleIterator.Clone(); + do { + retVal.Add(iterator.RightSample); + } while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time); + + return retVal; + } + + public void FinishSimulation() + { + Data.Finish(); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs index 8a5db4a93a9e679c06d9acde320d7c7e6c109328..0e5eb487fad515148cd93b1824c8e383d72179ac 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs @@ -29,265 +29,270 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>, - ITnInPort, ITnOutPort - { - protected readonly IGearboxInfo Gearbox; - protected readonly IShiftStrategy ShiftStrategy; - protected readonly TorqueConverterData ModelData; - private readonly KilogramSquareMeter _engineInertia; - - public ITnOutPort NextComponent { protected internal get; set; } - - public TorqueConverter(IGearboxInfo gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container, - TorqueConverterData tcData, VectoRunData runData) : base(container) - { - Gearbox = gearbox; - ShiftStrategy = shiftStrategy; - ModelData = tcData; - _engineInertia = runData != null && runData.EngineData != null - ? runData.EngineData.Inertia - : 0.SI<KilogramSquareMeter>(); - } - - public void Connect(ITnOutPort other) - { - NextComponent = other; - } - - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed); - TorqueConverterOperatingPoint operatingPoint; - if (operatingPointList.Count > 0) { - operatingPoint = SelectOperatingPoint(operatingPointList); - } else { - Log.Warn( - "TorqueConverter Initialize: No operating point found. Using output as input values as fallback for initialize."); - var inAngularVelocity = outAngularVelocity.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineN95hSpeed); - operatingPoint = new TorqueConverterOperatingPoint { - OutAngularVelocity = outAngularVelocity, - OutTorque = outTorque, - InAngularVelocity = inAngularVelocity, - InTorque = outTorque * (outAngularVelocity / inAngularVelocity) - }; - } - var retVal = NextComponent.Initialize(operatingPoint.InTorque, operatingPoint.InAngularVelocity); - PreviousState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, operatingPoint.OutTorque, - operatingPoint.OutAngularVelocity); - return retVal; - } - - public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - bool dryRun = false) - { - var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity); - var avgEngineSpeed = (PreviousState.InAngularVelocity + operatingPoint.InAngularVelocity) / 2; - var avgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque + - operatingPoint.InAngularVelocity * operatingPoint.InTorque) / 2; - var inTorque = avgPower / avgEngineSpeed; - - if (dryRun) { - // dry run request - var engineResponse = (ResponseDryRun) - NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity, true); - - var engineOK = engineResponse.DeltaDragLoad.IsGreaterOrEqual(0) && engineResponse.DeltaFullLoad.IsSmallerOrEqual(0); - if (DataBus.DriverBehavior != DrivingBehavior.Braking && engineOK && operatingPoint.Creeping) { - var delta = (outTorque - operatingPoint.OutTorque) * - (PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0; - return new ResponseDryRun() { - Source = this, - DeltaFullLoad = delta, - DeltaDragLoad = delta, - TorqueConverterOperatingPoint = operatingPoint - }; - } - - var dryOperatingPointMax = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse, - PreviousState.InTorque * PreviousState.InAngularVelocity); - var avgOutSpeedMax = (PreviousState.OutAngularVelocity + dryOperatingPointMax.OutAngularVelocity) / 2.0; - var deltaMax = (outTorque - dryOperatingPointMax.OutTorque) * avgOutSpeedMax; - - var dryOperatingPointMin = GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse, - PreviousState.InTorque * PreviousState.InAngularVelocity); - var avgOutSpeedMin = (PreviousState.OutAngularVelocity + dryOperatingPointMin.OutAngularVelocity) / 2.0; - var deltaMin = (outTorque - dryOperatingPointMin.OutTorque) * avgOutSpeedMin; - - return new ResponseDryRun { - Source = this, - DeltaFullLoad = 2 * deltaMax, - DeltaDragLoad = 2 * deltaMin, - TorqueConverterOperatingPoint = dryOperatingPointMax - }; - } - - // normal request - - // check if out-side of the operating point is equal to requested values - if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) { - var delta = (outTorque - operatingPoint.OutTorque) * - (PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0; - if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) { - if (delta > 0) { - return new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }; - } else { - return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }; - } - } - } - - CurrentState.SetState(inTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity); - CurrentState.OperatingPoint = operatingPoint; - - var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity); - - // check if shift is required - var ratio = Gearbox.GetGearData(Gearbox.Gear).TorqueConverterRatio; - if (retVal is ResponseSuccess && - ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, inTorque, - operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) { - return new ResponseGearShift { Source = this }; - } - return retVal; - } - - private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, - ResponseDryRun engineResponse, Watt previousPower) - { - try { - var operatingPoint = ModelData.FindOperatingPointForPowerDemand( - engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand, - DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); - var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); - if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { - operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); - } - if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); - } - return operatingPoint; - } catch (VectoException ve) { - Log.Error(ve, "TorqueConverter: Failed to find operating point for DragPower {0}", engineResponse.DragPower); - var retVal = ModelData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity); - retVal.Creeping = true; - return retVal; - } - } - - private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, - ResponseDryRun engineResponse, Watt previousPower) - { - try { - var operatingPoint = ModelData.FindOperatingPointForPowerDemand( - engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand, - DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); - var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); - if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { - operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); - } - return operatingPoint; - } catch (VectoException ve) { - Log.Error(ve, "TorqueConverter: Failed to find operating point for MaxPower {0}", - engineResponse.DynamicFullLoadPower); - var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); - tqOperatingPoint.Creeping = true; - return tqOperatingPoint; - } - } - - protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque, - PerSecond outAngularVelocity) - { - var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed); - if (operatingPointList.Count == 0) { - Log.Debug("TorqueConverter: Failed to find torque converter operating point, fallback: creeping"); - var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); - tqOperatingPoint.Creeping = true; - return tqOperatingPoint; - } - - var operatingPoint = SelectOperatingPoint(operatingPointList); - if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - throw new VectoException( - "TorqueConverter: Invalid operating point, inAngularVelocity would be below engine's idle speed: {0}", - operatingPoint.InAngularVelocity); - } - var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); - if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { - operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); - } - return operatingPoint; - } - - private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList) - { - if (operatingPointList.Count == 1) { - return operatingPointList[0]; - } - - foreach (var x in operatingPointList) { - if ((x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity), - Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) && - (x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity), - Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())) { - return x; - } - } - - return operatingPointList[0]; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - if (CurrentState.OperatingPoint == null) { - container[ModalResultField.TorqueConverterTorqueRatio] = 1.0; - container[ModalResultField.TorqueConverterSpeedRatio] = 1.0; - } else { - container[ModalResultField.TorqueConverterTorqueRatio] = CurrentState.OperatingPoint.TorqueRatio; - container[ModalResultField.TorqueConverterSpeedRatio] = CurrentState.OperatingPoint.SpeedRatio; - } - container[ModalResultField.TC_TorqueIn] = CurrentState.InTorque; - container[ModalResultField.TC_TorqueOut] = CurrentState.OutTorque; - container[ModalResultField.TC_angularSpeedIn] = CurrentState.InAngularVelocity; - container[ModalResultField.TC_angularSpeedOut] = CurrentState.OutAngularVelocity; - - var avgOutVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - var avgInVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; - container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity; - container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity - - CurrentState.OutTorque * avgOutVelocity; - } - - protected override void DoCommitSimulationStep() - { - AdvanceState(); - } - - public void Locked(NewtonMeter inTorque, PerSecond inAngularVelocity, NewtonMeter outTorque, - PerSecond outAngularVelocity) - { - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - } - - public class TorqueConverterComponentState : SimpleComponentState - { - public TorqueConverterOperatingPoint OperatingPoint; - } - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>, + ITnInPort, ITnOutPort + { + protected readonly IGearboxInfo Gearbox; + protected readonly IShiftStrategy ShiftStrategy; + protected readonly TorqueConverterData ModelData; + private readonly KilogramSquareMeter _engineInertia; + + public ITnOutPort NextComponent { protected internal get; set; } + + public TorqueConverter(IGearboxInfo gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container, + TorqueConverterData tcData, VectoRunData runData) : base(container) + { + Gearbox = gearbox; + ShiftStrategy = shiftStrategy; + ModelData = tcData; + _engineInertia = runData != null && runData.EngineData != null + ? runData.EngineData.Inertia + : 0.SI<KilogramSquareMeter>(); + } + + public void Connect(ITnOutPort other) + { + NextComponent = other; + } + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed); + TorqueConverterOperatingPoint operatingPoint; + if (operatingPointList.Count > 0) { + operatingPoint = SelectOperatingPoint(operatingPointList); + } else { + Log.Warn( + "TorqueConverter Initialize: No operating point found. Using output as input values as fallback for initialize."); + var inAngularVelocity = outAngularVelocity.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineN95hSpeed); + operatingPoint = new TorqueConverterOperatingPoint { + OutAngularVelocity = outAngularVelocity, + OutTorque = outTorque, + InAngularVelocity = inAngularVelocity, + InTorque = outTorque * (outAngularVelocity / inAngularVelocity) + }; + } + var retVal = NextComponent.Initialize(operatingPoint.InTorque, operatingPoint.InAngularVelocity); + PreviousState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, operatingPoint.OutTorque, + operatingPoint.OutAngularVelocity); + return retVal; + } + + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity); + var avgEngineSpeed = (PreviousState.InAngularVelocity + operatingPoint.InAngularVelocity) / 2; + var avgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque + + operatingPoint.InAngularVelocity * operatingPoint.InTorque) / 2; + var inTorque = avgPower / avgEngineSpeed; + + if (dryRun) { + return HandleDryRun(absTime, dt, outTorque, outAngularVelocity, inTorque, operatingPoint); + } + + // normal request + + // check if out-side of the operating point is equal to requested values + if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) { + var delta = (outTorque - operatingPoint.OutTorque) * + (PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0; + if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) { + return delta > 0 + ? new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint } + : (IResponse) + new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }; + } + } + + CurrentState.SetState(inTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity); + CurrentState.OperatingPoint = operatingPoint; + + var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity); + + // check if shift is required + var ratio = Gearbox.GetGearData(Gearbox.Gear).TorqueConverterRatio; + if (retVal is ResponseSuccess && + ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, inTorque, + operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) { + return new ResponseGearShift { Source = this }; + } + return retVal; + } + + private IResponse HandleDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, TorqueConverterOperatingPoint operatingPoint) + { +// dry run request + var engineResponse = (ResponseDryRun) + NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity, true); + + var engineOK = engineResponse.DeltaDragLoad.IsGreaterOrEqual(0) && engineResponse.DeltaFullLoad.IsSmallerOrEqual(0); + if (DataBus.DriverBehavior != DrivingBehavior.Braking && engineOK && operatingPoint.Creeping) { + var delta = (outTorque - operatingPoint.OutTorque) * + (PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0; + return new ResponseDryRun() { + Source = this, + DeltaFullLoad = delta, + DeltaDragLoad = delta, + TorqueConverterOperatingPoint = operatingPoint + }; + } + + var dryOperatingPointMax = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse, + PreviousState.InTorque * PreviousState.InAngularVelocity); + var avgOutSpeedMax = (PreviousState.OutAngularVelocity + dryOperatingPointMax.OutAngularVelocity) / 2.0; + var deltaMax = (outTorque - dryOperatingPointMax.OutTorque) * avgOutSpeedMax; + + var dryOperatingPointMin = GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse, + PreviousState.InTorque * PreviousState.InAngularVelocity); + var avgOutSpeedMin = (PreviousState.OutAngularVelocity + dryOperatingPointMin.OutAngularVelocity) / 2.0; + var deltaMin = (outTorque - dryOperatingPointMin.OutTorque) * avgOutSpeedMin; + + return new ResponseDryRun { + Source = this, + DeltaFullLoad = 2 * deltaMax, + DeltaDragLoad = 2 * deltaMin, + TorqueConverterOperatingPoint = dryOperatingPointMax + }; + } + + private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, + ResponseDryRun engineResponse, Watt previousPower) + { + try { + var operatingPoint = ModelData.FindOperatingPointForPowerDemand( + engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand, + DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); + var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); + if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); + } + if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); + } + return operatingPoint; + } catch (VectoException ve) { + Log.Error(ve, "TorqueConverter: Failed to find operating point for DragPower {0}", engineResponse.DragPower); + var retVal = ModelData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity); + retVal.Creeping = true; + return retVal; + } + } + + private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, + ResponseDryRun engineResponse, Watt previousPower) + { + try { + var operatingPoint = ModelData.FindOperatingPointForPowerDemand( + engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand, + DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower); + var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); + if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); + } + return operatingPoint; + } catch (VectoException ve) { + Log.Error(ve, "TorqueConverter: Failed to find operating point for MaxPower {0}", + engineResponse.DynamicFullLoadPower); + var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); + tqOperatingPoint.Creeping = true; + return tqOperatingPoint; + } + } + + protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque, + PerSecond outAngularVelocity) + { + var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed); + if (operatingPointList.Count == 0) { + Log.Debug("TorqueConverter: Failed to find torque converter operating point, fallback: creeping"); + var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); + tqOperatingPoint.Creeping = true; + return tqOperatingPoint; + } + + var operatingPoint = SelectOperatingPoint(operatingPointList); + if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + throw new VectoException( + "TorqueConverter: Invalid operating point, inAngularVelocity would be below engine's idle speed: {0}", + operatingPoint.InAngularVelocity); + } + var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed); + if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity); + } + return operatingPoint; + } + + private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList) + { + if (operatingPointList.Count == 1) { + return operatingPointList[0]; + } + + foreach (var x in operatingPointList) { + if ((x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity), + Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) && + (x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity), + Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())) { + return x; + } + } + + return operatingPointList[0]; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + if (CurrentState.OperatingPoint == null) { + container[ModalResultField.TorqueConverterTorqueRatio] = 1.0; + container[ModalResultField.TorqueConverterSpeedRatio] = 1.0; + } else { + container[ModalResultField.TorqueConverterTorqueRatio] = CurrentState.OperatingPoint.TorqueRatio; + container[ModalResultField.TorqueConverterSpeedRatio] = CurrentState.OperatingPoint.SpeedRatio; + } + container[ModalResultField.TC_TorqueIn] = CurrentState.InTorque; + container[ModalResultField.TC_TorqueOut] = CurrentState.OutTorque; + container[ModalResultField.TC_angularSpeedIn] = CurrentState.InAngularVelocity; + container[ModalResultField.TC_angularSpeedOut] = CurrentState.OutAngularVelocity; + + var avgOutVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + var avgInVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0; + container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity; + container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity - + CurrentState.OutTorque * avgOutVelocity; + } + + protected override void DoCommitSimulationStep() + { + AdvanceState(); + } + + public void Locked(NewtonMeter inTorque, PerSecond inAngularVelocity, NewtonMeter outTorque, + PerSecond outAngularVelocity) + { + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + } + + public class TorqueConverterComponentState : SimpleComponentState + { + public TorqueConverterOperatingPoint OperatingPoint; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs index 5a749e071ff0aa74a8cd1115e933cf0b33739515..57cdd58380c2ac56974b0496f08e483539a41728 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs @@ -29,228 +29,228 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>, - IVehicle, IMileageCounter, IFvInPort, - IDriverDemandOutPort - { - internal readonly VehicleData ModelData; - - public readonly AirdragData AirdragData; - - - public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container) - { - ModelData = modelData; - AirdragData = airdrag; - if (AirdragData.CrossWindCorrectionCurve != null) { - AirdragData.CrossWindCorrectionCurve.SetDataBus(container); - } - } - - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) - { - PreviousState = new VehicleState { - Distance = DataBus.CycleStartDistance, - Velocity = vehicleSpeed, - RollingResistance = RollingResistance(roadGradient), - SlopeResistance = SlopeResistance(roadGradient), - AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed), - }; - PreviousState.VehicleTractionForce = PreviousState.RollingResistance - + PreviousState.AirDragResistance - + PreviousState.SlopeResistance; - - return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed); - } - - public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration) - { - //CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval; - var vehicleAccelerationForce = DriverAcceleration(startAcceleration) - + RollingResistance(roadGradient) - + - AirDragResistance(vehicleSpeed, - vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval) - + SlopeResistance(roadGradient); - - var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed); - return retVal; - } - - public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient, - bool dryRun = false) - { - Log.Debug("Vehicle: acceleration: {0}", acceleration); - CurrentState.SimulationInterval = dt; - CurrentState.Acceleration = acceleration; - CurrentState.Velocity = PreviousState.Velocity + acceleration * dt; - if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(), - Constants.SimulationSettings.VehicleSpeedHaltTolerance)) { - CurrentState.Velocity = 0.SI<MeterPerSecond>(); - } - CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2; - - CurrentState.DriverAcceleration = DriverAcceleration(acceleration); - CurrentState.RollingResistance = RollingResistance(gradient); - try { - CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity); - } catch (VectoException ex) { - Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime, - CurrentState.Distance, CurrentState.Velocity, ex); - CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity), - VectoMath.Max(0, CurrentState.Velocity)); - } - CurrentState.SlopeResistance = SlopeResistance(gradient); - - // DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance - CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration - + CurrentState.RollingResistance - + CurrentState.AirDragResistance - + CurrentState.SlopeResistance; - - var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce, - CurrentState.Velocity, dryRun); - return retval; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0; - - container[ModalResultField.v_act] = averageVelocity; - - container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity; - container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity; - container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity; - container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity; - container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity; - - // sanity check: is the vehicle in step with the cycle? - if (container[ModalResultField.dist] == DBNull.Value) { - Log.Warn("Distance field is not set!"); - } else { - var distance = (SI)container[ModalResultField.dist]; - if (!distance.IsEqual(CurrentState.Distance)) { - Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}", - (distance - CurrentState.Distance).Value(), distance); - } - } - } - - public Newton RollingResistance(Radian gradient) - { - var weight = ModelData.TotalVehicleWeight; - var gravity = Physics.GravityAccelleration; - var rollCoefficient = ModelData.TotalRollResistanceCoefficient; - - var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient; - Log.Debug("RollingResistance: {0}", retVal); - return retVal; - } - - protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration) - { - var retVal = ModelData.TotalVehicleWeight * accelleration; - Log.Debug("DriverAcceleration: {0}", retVal); - return retVal; - } - - public Newton SlopeResistance(Radian gradient) - { - var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value()); - Log.Debug("SlopeResistance: {0}", retVal); - return retVal; - } - - public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) - { - var vAverage = (previousVelocity + nextVelocity) / 2; - if (vAverage.IsEqual(0)) { - return 0.SI<Newton>(); - } - var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage; - - Log.Debug("AirDragResistance: {0}", result); - return result; - } - - private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2) - { - return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2); - } - - public Meter Distance - { - get { return PreviousState.Distance; } - } - - public MeterPerSecond VehicleSpeed - { - get { return PreviousState.Velocity; } - } - - public bool VehicleStopped - { - get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); } - } - - public Kilogram VehicleMass - { - get { return ModelData.TotalCurbWeight; } - } - - public Kilogram VehicleLoading - { - get { return ModelData.Loading; } - } - - public Kilogram TotalMass - { - get { return ModelData.TotalVehicleWeight; } - } - - public CubicMeter CargoVolume - { - get { return ModelData.CargoVolume; } - } - - public class VehicleState - { - public Meter Distance = 0.SI<Meter>(); - public Second SimulationInterval = 0.SI<Second>(); - public Newton AirDragResistance = 0.SI<Newton>(); - public Newton DriverAcceleration = 0.SI<Newton>(); - public Newton RollingResistance = 0.SI<Newton>(); - public Newton SlopeResistance = 0.SI<Newton>(); - public Newton VehicleTractionForce = 0.SI<Newton>(); - public MeterPerSecond Velocity = 0.SI<MeterPerSecond>(); - public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>(); - - public override string ToString() - { - return - string.Format( - "v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}", - Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance, - AirDragResistance, - VehicleTractionForce); - } - } - } +using System; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>, + IVehicle, IMileageCounter, IFvInPort, + IDriverDemandOutPort + { + internal readonly VehicleData ModelData; + + public readonly AirdragData AirdragData; + + + public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container) + { + ModelData = modelData; + AirdragData = airdrag; + if (AirdragData.CrossWindCorrectionCurve != null) { + AirdragData.CrossWindCorrectionCurve.SetDataBus(container); + } + } + + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) + { + PreviousState = new VehicleState { + Distance = DataBus.CycleStartDistance, + Velocity = vehicleSpeed, + RollingResistance = RollingResistance(roadGradient), + SlopeResistance = SlopeResistance(roadGradient), + AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed), + }; + PreviousState.VehicleTractionForce = PreviousState.RollingResistance + + PreviousState.AirDragResistance + + PreviousState.SlopeResistance; + + return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed); + } + + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration) + { + //CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval; + var vehicleAccelerationForce = DriverAcceleration(startAcceleration) + + RollingResistance(roadGradient) + + + AirDragResistance(vehicleSpeed, + vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval) + + SlopeResistance(roadGradient); + + var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed); + return retVal; + } + + public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient, + bool dryRun = false) + { + Log.Debug("Vehicle: acceleration: {0}", acceleration); + CurrentState.SimulationInterval = dt; + CurrentState.Acceleration = acceleration; + CurrentState.Velocity = PreviousState.Velocity + acceleration * dt; + if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(), + Constants.SimulationSettings.VehicleSpeedHaltTolerance)) { + CurrentState.Velocity = 0.SI<MeterPerSecond>(); + } + CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2; + + CurrentState.DriverAcceleration = DriverAcceleration(acceleration); + CurrentState.RollingResistance = RollingResistance(gradient); + try { + CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity); + } catch (VectoException ex) { + Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime, + CurrentState.Distance, CurrentState.Velocity, ex); + CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity), + VectoMath.Max(0, CurrentState.Velocity)); + } + CurrentState.SlopeResistance = SlopeResistance(gradient); + + // DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance + CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration + + CurrentState.RollingResistance + + CurrentState.AirDragResistance + + CurrentState.SlopeResistance; + + var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce, + CurrentState.Velocity, dryRun); + return retval; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0; + + container[ModalResultField.v_act] = averageVelocity; + + container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity; + container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity; + container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity; + container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity; + container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity; + + // sanity check: is the vehicle in step with the cycle? + if (container[ModalResultField.dist] == DBNull.Value) { + Log.Warn("Distance field is not set!"); + } else { + var distance = (SI)container[ModalResultField.dist]; + if (!distance.IsEqual(CurrentState.Distance)) { + Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}", + (distance - CurrentState.Distance).Value(), distance); + } + } + } + + public Newton RollingResistance(Radian gradient) + { + var weight = ModelData.TotalVehicleWeight; + var gravity = Physics.GravityAccelleration; + var rollCoefficient = ModelData.TotalRollResistanceCoefficient; + + var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient; + Log.Debug("RollingResistance: {0}", retVal); + return retVal; + } + + protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration) + { + var retVal = ModelData.TotalVehicleWeight * accelleration; + Log.Debug("DriverAcceleration: {0}", retVal); + return retVal; + } + + public Newton SlopeResistance(Radian gradient) + { + var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value()); + Log.Debug("SlopeResistance: {0}", retVal); + return retVal; + } + + public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) + { + var vAverage = (previousVelocity + nextVelocity) / 2; + if (vAverage.IsEqual(0)) { + return 0.SI<Newton>(); + } + var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage; + + Log.Debug("AirDragResistance: {0}", result); + return result; + } + + private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2) + { + return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2); + } + + public Meter Distance + { + get { return PreviousState.Distance; } + } + + public MeterPerSecond VehicleSpeed + { + get { return PreviousState.Velocity; } + } + + public bool VehicleStopped + { + get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); } + } + + public Kilogram VehicleMass + { + get { return ModelData.TotalCurbWeight; } + } + + public Kilogram VehicleLoading + { + get { return ModelData.Loading; } + } + + public Kilogram TotalMass + { + get { return ModelData.TotalVehicleWeight; } + } + + public CubicMeter CargoVolume + { + get { return ModelData.CargoVolume; } + } + + public class VehicleState + { + public Meter Distance = 0.SI<Meter>(); + public Second SimulationInterval = 0.SI<Second>(); + public Newton AirDragResistance = 0.SI<Newton>(); + public Newton DriverAcceleration = 0.SI<Newton>(); + public Newton RollingResistance = 0.SI<Newton>(); + public Newton SlopeResistance = 0.SI<Newton>(); + public Newton VehicleTractionForce = 0.SI<Newton>(); + public MeterPerSecond Velocity = 0.SI<MeterPerSecond>(); + public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>(); + + public override string ToString() + { + return + string.Format( + "v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}", + Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance, + AirDragResistance, + VehicleTractionForce); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 3ebf64a5186d0987ad6eb90ba3f3d25d3c429998..1167eee4a5069514f9a6e12fc19c8e3ef17ac702 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -29,134 +29,134 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; - -namespace TUGraz.VectoCore.OutputData -{ - public interface IDeclarationReport - { - void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData); - void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData); - void InitializeReport(VectoRunData modelData, Segment segment); - } - - /// <summary> - /// Class for creating a declaration report. - /// </summary> - public abstract class DeclarationReport<T> : IDeclarationReport where T : new() - { - public class ResultContainer<TEntry> - { - public MissionType Mission; - - public Dictionary<LoadingType, TEntry> ModData; - } - - //public class MissionProfile - //{ - // public readonly IList<double> DistanceKm; - // public readonly IList<double> TargetSpeed; - // public readonly IList<double> Altitude; - - // public MissionProfile(IModalDataContainer m) - // { - // DistanceKm = m.GetValues<Meter>(ModalResultField.dist).Select(v => v.ConvertTo().Kilo.Meter).ToDouble(); - // TargetSpeed = - // m.GetValues<MeterPerSecond>(ModalResultField.v_targ).Select(v => v.ConvertTo().Kilo.Meter.Per.Hour).ToDouble(); - // Altitude = m.GetValues<Meter>(ModalResultField.altitude).ToDouble(); - // } - //} - - /// <summary> - /// Dictionary of MissionTypes and their corresponding results. - /// </summary> - protected readonly Dictionary<MissionType, ResultContainer<T>> Missions = - new Dictionary<MissionType, ResultContainer<T>>(); - - /// <summary> - /// The full load curve. - /// </summary> - internal Dictionary<uint, EngineFullLoadCurve> Flc { get; set; } - - /// <summary> - /// The declaration segment from the segment table - /// </summary> - internal Segment Segment { get; set; } - - - /// <summary> - /// The result count determines how many results must be given before the report gets written. - /// </summary> - private int _resultCount; - - [MethodImpl(MethodImplOptions.Synchronized)] - public void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData) - { - if (!Missions.ContainsKey(mission.MissionType)) { - Missions[mission.MissionType] = new ResultContainer<T>() { - Mission = mission.MissionType, - ModData = new Dictionary<LoadingType, T>(), - }; - } - Missions[mission.MissionType].ModData[loading] = new T(); - _resultCount++; - } - - - [MethodImpl(MethodImplOptions.Synchronized)] - public void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, - IModalDataContainer modData) - { - if (modData.RunStatus != VectoRun.Status.Success) { - //Missions.Clear(); - return; - } - if (!Missions.ContainsKey(mission.MissionType)) { - throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType); - } - if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) { - throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType); - } - //if (Missions[mission.MissionType].MissionProfile == null) { - // Missions[mission.MissionType].MissionProfile = new MissionProfile(modData); - //} - _resultCount--; - - DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData); - - if (_resultCount == 0) { - DoWriteReport(); - Flc = null; - Segment = null; - } - } - - /// <summary> - /// Adds the result of one run for the specific mission and loading. If all runs finished (given by the resultCount) the report will be written. - /// </summary> - /// <param name="entry"></param> - /// <param name="runData"></param> - /// <param name="modData">The mod data.</param> - [MethodImpl(MethodImplOptions.Synchronized)] - protected abstract void DoAddResult(T entry, VectoRunData runData, IModalDataContainer modData); - - - protected internal abstract void DoWriteReport(); - - - public void InitializeReport(VectoRunData modelData, Segment segment) - { - Segment = segment; - - DoInitializeReport(modelData, segment); - } - - protected abstract void DoInitializeReport(VectoRunData modelData, Segment segment); - } +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; + +namespace TUGraz.VectoCore.OutputData +{ + public interface IDeclarationReport + { + void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData); + void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, IModalDataContainer modData); + void InitializeReport(VectoRunData modelData, Segment segment); + } + + /// <summary> + /// Class for creating a declaration report. + /// </summary> + public abstract class DeclarationReport<T> : IDeclarationReport where T : new() + { + public class ResultContainer<TEntry> + { + public MissionType Mission; + + public Dictionary<LoadingType, TEntry> ModData; + } + + //public class MissionProfile + //{ + // public readonly IList<double> DistanceKm; + // public readonly IList<double> TargetSpeed; + // public readonly IList<double> Altitude; + + // public MissionProfile(IModalDataContainer m) + // { + // DistanceKm = m.GetValues<Meter>(ModalResultField.dist).Select(v => v.ConvertTo().Kilo.Meter).ToDouble(); + // TargetSpeed = + // m.GetValues<MeterPerSecond>(ModalResultField.v_targ).Select(v => v.ConvertTo().Kilo.Meter.Per.Hour).ToDouble(); + // Altitude = m.GetValues<Meter>(ModalResultField.altitude).ToDouble(); + // } + //} + + /// <summary> + /// Dictionary of MissionTypes and their corresponding results. + /// </summary> + protected readonly Dictionary<MissionType, ResultContainer<T>> Missions = + new Dictionary<MissionType, ResultContainer<T>>(); + + /// <summary> + /// The full load curve. + /// </summary> + internal Dictionary<uint, EngineFullLoadCurve> Flc { get; set; } + + /// <summary> + /// The declaration segment from the segment table + /// </summary> + internal Segment? Segment { get; set; } + + + /// <summary> + /// The result count determines how many results must be given before the report gets written. + /// </summary> + private int _resultCount; + + [MethodImpl(MethodImplOptions.Synchronized)] + public void PrepareResult(LoadingType loading, Mission mission, VectoRunData runData) + { + if (!Missions.ContainsKey(mission.MissionType)) { + Missions[mission.MissionType] = new ResultContainer<T>() { + Mission = mission.MissionType, + ModData = new Dictionary<LoadingType, T>(), + }; + } + Missions[mission.MissionType].ModData[loading] = new T(); + _resultCount++; + } + + + [MethodImpl(MethodImplOptions.Synchronized)] + public void AddResult(LoadingType loadingType, Mission mission, VectoRunData runData, + IModalDataContainer modData) + { + if (modData.RunStatus != VectoRun.Status.Success) { + //Missions.Clear(); + return; + } + if (!Missions.ContainsKey(mission.MissionType)) { + throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType); + } + if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) { + throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType); + } + //if (Missions[mission.MissionType].MissionProfile == null) { + // Missions[mission.MissionType].MissionProfile = new MissionProfile(modData); + //} + _resultCount--; + + DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData); + + if (_resultCount == 0) { + DoWriteReport(); + Flc = null; + Segment = null; + } + } + + /// <summary> + /// Adds the result of one run for the specific mission and loading. If all runs finished (given by the resultCount) the report will be written. + /// </summary> + /// <param name="entry"></param> + /// <param name="runData"></param> + /// <param name="modData">The mod data.</param> + [MethodImpl(MethodImplOptions.Synchronized)] + protected abstract void DoAddResult(T entry, VectoRunData runData, IModalDataContainer modData); + + + protected internal abstract void DoWriteReport(); + + + public void InitializeReport(VectoRunData modelData, Segment segment) + { + Segment = segment; + + DoInitializeReport(modelData, segment); + } + + protected abstract void DoInitializeReport(VectoRunData modelData, Segment segment); + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs index 51f3e6f89c743ec023d4f4d87821b569f1386800..0520e1b177690a05adfe2f0f75cb1efa94c79eb2 100644 --- a/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs +++ b/VectoCore/VectoCore/OutputData/FileIO/FileOutputWriter.cs @@ -29,89 +29,89 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Data; -using System.IO; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.OutputData.FileIO -{ - public class FileOutputWriter : LoggingObject, IOutputDataWriter - { - private readonly string _jobFile; - - private string BasePath - { - get { return Path.GetDirectoryName(_jobFile); } - } - - public string PDFReportName - { - get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.PDFReport); } - } - - public string XMLFullReportName - { - get { return Path.ChangeExtension(_jobFile, "RSLT_MANUFACTURER.xml"); } - } - - public string XMLCustomerReportName - { - get { return Path.ChangeExtension(_jobFile, "RSLT_CUSTOMER.xml"); } - } - - - public string SumFileName - { - get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.SumFile); } - } - - /// <summary> - /// - /// </summary> - /// <param name="jobFile">full path of the json job-file. jobName and basePath are extracted.</param> - public FileOutputWriter(string jobFile) - { - _jobFile = jobFile; - } - - public void WriteSumData(DataTable data) - { - VectoCSVFile.Write(SumFileName, data, true); - } - - public string GetModDataFileName(string runName, string cycleName, string runSuffix) - { - string modFileName; - if (!string.IsNullOrWhiteSpace(cycleName) || !string.IsNullOrWhiteSpace(runSuffix)) { - modFileName = string.Format("{0}_{1}{2}{3}", runName, cycleName, runSuffix, Constants.FileExtensions.ModDataFile); - } else { - modFileName = string.Format("{0}{1}", runName, Constants.FileExtensions.ModDataFile); - } - - return Path.Combine(BasePath, modFileName); - } - - public void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData) - { - VectoCSVFile.Write(GetModDataFileName(runName, cycleName, runSuffix), modData, true); - } - - public Stream WriteStream(ReportType type) - { - switch (type) { - case ReportType.DeclarationReportPdf: - return new FileStream(PDFReportName, FileMode.Create); - case ReportType.DeclarationReportXMLFulll: - return new FileStream(XMLFullReportName, FileMode.Create); - case ReportType.DeclarationReportXMLCOC: - return new FileStream(XMLCustomerReportName, FileMode.Create); - default: - - throw new ArgumentOutOfRangeException("type"); - } - } - } +using System; +using System.Data; +using System.IO; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.FileIO +{ + public class FileOutputWriter : LoggingObject, IOutputDataWriter + { + private readonly string _jobFile; + + private string BasePath + { + get { return Path.GetDirectoryName(_jobFile); } + } + + public string PDFReportName + { + get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.PDFReport); } + } + + public string XMLFullReportName + { + get { return Path.ChangeExtension(_jobFile, "RSLT_MANUFACTURER.xml"); } + } + + public string XMLCustomerReportName + { + get { return Path.ChangeExtension(_jobFile, "RSLT_CUSTOMER.xml"); } + } + + + public string SumFileName + { + get { return Path.ChangeExtension(_jobFile, Constants.FileExtensions.SumFile); } + } + + /// <summary> + /// + /// </summary> + /// <param name="jobFile">full path of the json job-file. jobName and basePath are extracted.</param> + public FileOutputWriter(string jobFile) + { + _jobFile = jobFile; + } + + public void WriteSumData(DataTable data) + { + VectoCSVFile.Write(SumFileName, data, true); + } + + public string GetModDataFileName(string runName, string cycleName, string runSuffix) + { + string modFileName; + if (!string.IsNullOrWhiteSpace(cycleName) || !string.IsNullOrWhiteSpace(runSuffix)) { + modFileName = string.Format("{0}_{1}{2}{3}", runName, cycleName, runSuffix, Constants.FileExtensions.ModDataFile); + } else { + modFileName = string.Format("{0}{1}", runName, Constants.FileExtensions.ModDataFile); + } + + return Path.Combine(BasePath, modFileName); + } + + public void WriteModData(string runName, string cycleName, string runSuffix, DataTable modData) + { + VectoCSVFile.Write(GetModDataFileName(runName, cycleName, runSuffix), modData, true); + } + + public Stream WriteStream(ReportType type) + { + switch (type) { + case ReportType.DeclarationReportPdf: + return new FileStream(PDFReportName, FileMode.Create); + case ReportType.DeclarationReportXMLFulll: + return new FileStream(XMLFullReportName, FileMode.Create); + case ReportType.DeclarationReportXMLCOC: + return new FileStream(XMLCustomerReportName, FileMode.Create); + default: + + throw new ArgumentOutOfRangeException("type"); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index 10c29e57190056f883d4a4147a85447b36f5b292..1e514478daf2189cb6adeb5e73b36615ed3faff7 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -58,7 +58,7 @@ namespace TUGraz.VectoCore.OutputData public const string INPUTFILE = "Input File [-]"; public const string CYCLE = "Cycle [-]"; public const string STATUS = "Status"; - public const string CURB_MASS = "Chassis curb mass [kg]"; + public const string CURB_MASS = "Corrected Actual Curb Mass [kg]"; public const string LOADING = "Loading [kg]"; public const string VEHICLE_MANUFACTURER = "Vehicle manufacturer [-]"; @@ -168,7 +168,7 @@ namespace TUGraz.VectoCore.OutputData public const string CRUISE_TIMESHARE = "CruiseTimeShare [%]"; public const string STOP_TIMESHARE = "StopTimeShare [%]"; - public const string MAX_SPEED = "max. speed [km/h"; + public const string MAX_SPEED = "max. speed [km/h]"; public const string MAX_ACCELERATION = "max. acc [m/s²]"; public const string MAX_DECELERATION = "max. dec [m/s²]"; public const string AVG_ENGINE_SPEED = "n_eng_avg [rpm]"; @@ -180,6 +180,10 @@ namespace TUGraz.VectoCore.OutputData public const string TIME_SHARE_PER_GEAR_FORMAT = "Gear {0} TimeShare [%]"; + public const string NUM_AXLES_DRIVEN = "Number axles vehicle driven [-]"; + public const string NUM_AXLES_NON_DRIVEN = "Number axles vehicle non-driven [-]"; + public const string NUM_AXLES_TRAILER = "Number axles trailer [-]"; + // ReSharper restore InconsistentNaming internal readonly DataTable Table; @@ -228,6 +232,9 @@ namespace TUGraz.VectoCore.OutputData Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)), Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)), Tuple.Create(R_DYN, typeof(SI)), + Tuple.Create(NUM_AXLES_DRIVEN, typeof(int)), + Tuple.Create(NUM_AXLES_NON_DRIVEN, typeof(int)), + Tuple.Create(NUM_AXLES_TRAILER, typeof(int)), Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)), Tuple.Create(GEARBOX_MODEL, typeof(string)), Tuple.Create(GEARBOX_TYPE, typeof(string)), @@ -267,15 +274,16 @@ namespace TUGraz.VectoCore.OutputData E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA, E_AUX, E_CLUTCH_LOSS, E_TC_LOSS, E_SHIFT_LOSS, E_GBX_LOSS, E_RET_LOSS, E_ANGLE_LOSS, E_AXL_LOSS, E_BRAKE, E_VEHICLE_INERTIA, E_AIR, E_ROLL, E_GRAD, - ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, STOP_TIMESHARE, + ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS, - ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE + STOP_TIMESHARE, ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE }.Select(x => new DataColumn(x, typeof(SI))).ToArray()); } /// <summary> /// Finishes the summary data container (writes the data to the sumWriter). /// </summary> + [MethodImpl(MethodImplOptions.Synchronized)] public virtual void Finish() { if (_sumWriter != null) { @@ -293,8 +301,6 @@ namespace TUGraz.VectoCore.OutputData /// Writes the result of one run into the summary data container. /// </summary> [MethodImpl(MethodImplOptions.Synchronized)] - //public virtual void Write(IModalDataContainer modData, string jobFileName, string jobName, string cycleFileName, - // Kilogram vehicleMass, Kilogram vehicleLoading, CubicMeter cargoVolume, uint gearCount) public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData) { var row = Table.NewRow(); @@ -309,108 +315,9 @@ namespace TUGraz.VectoCore.OutputData var vehicleLoading = 0.SI<Kilogram>(); var cargoVolume = 0.SI<CubicMeter>(); - uint gearCount = 0u; + var gearCount = 0u; if (runData.Cycle.CycleType != CycleType.EngineOnly) { - row[VEHICLE_MANUFACTURER] = runData.VehicleData.Manufacturer; - row[VIN_NUMBER] = runData.VehicleData.VIN; - row[VEHICLE_MODEL] = runData.VehicleData.ModelName; - - row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber(); - row[CURB_MASS] = runData.VehicleData.CurbWeight; - // - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>()); - row[LOADING] = runData.VehicleData.Loading; - row[CARGO_VOLUME] = runData.VehicleData.CargoVolume; - - row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight; - row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer; - row[ENGINE_MODEL] = runData.EngineData.ModelName; - row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel(); - row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null - ? runData.EngineData.RatedPowerDeclared.ConvertTo().Kilo.Watt - : runData.EngineData.FullLoadCurves[0].MaxPower.ConvertTo().Kilo.Watt; - row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>(); - row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null - ? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>() - : runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>(); - row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter; - - row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban; - row[ENGINE_WHTC_RURAL] = runData.EngineData.WHTCRural; - row[ENGINE_WHTC_MOTORWAY] = runData.EngineData.WHTCMotorway; - row[ENGINE_BF_COLD_HOT] = runData.EngineData.ColdHotCorrectionFactor; - row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer; - row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor; - - row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea; - - row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] = - runData.VehicleData.RollResistanceCoefficientWithoutTrailer; - row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] = - runData.VehicleData.TotalRollResistanceCoefficient; - - row[R_DYN] = runData.VehicleData.DynamicTyreRadius; - - row[GEARBOX_MANUFACTURER] = runData.GearboxData.Manufacturer; - row[GEARBOX_MODEL] = runData.GearboxData.ModelName; - row[GEARBOX_TYPE] = runData.GearboxData.Type; - if (runData.GearboxData.Type.AutomaticTransmission()) { - row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio) - ? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>() - : runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()) - : 0.SI<Scalar>(); - row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); - row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer; - row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName; - } else { - row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); - row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); - row[TORQUECONVERTER_MANUFACTURER] = "n.a."; - row[TORQUECONVERTER_MODEL] = "n.a."; - } - row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel(); - if (runData.Retarder.Type.IsDedicatedComponent()) { - row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer; - row[RETARDER_MODEL] = runData.Retarder.ModelName; - } else { - row[RETARDER_MANUFACTURER] = "n.a."; - row[RETARDER_MODEL] = "n.a."; - } - - if (runData.AngledriveData != null) { - row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer; - row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName; - row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio; - } else { - row[ANGLEDRIVE_MANUFACTURER] = "n.a."; - row[ANGLEDRIVE_MODEL] = "n.a."; - row[ANGLEDRIVE_RATIO] = "n.a."; - } - - row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer; - row[AXLE_MODEL] = runData.AxleGearData.ModelName; - row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>(); - - foreach (var aux in runData.Aux) { - if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) { - continue; - } - var colName = string.Format(AUX_TECH_FORMAT, aux.ID); - - if (!Table.Columns.Contains(colName)) { - var col = Table.Columns.Add(colName, typeof(string)); - // move the new column to correct position - col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal); - } - - row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology); - } + WriteFullPowertrain(runData, row); cargoVolume = runData.VehicleData.CargoVolume; vehicleLoading = runData.VehicleData.Loading; @@ -433,6 +340,43 @@ namespace TUGraz.VectoCore.OutputData row[ALTITUDE_DELTA] = modData.AltitudeDelta(); + WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume); + + var kilogramPerMeter = modData.CO2PerMeter(); + if (kilogramPerMeter != null) { + row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter; + if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) { + row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton; + } + if (cargoVolume > 0) { + row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume; + } + } + + row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt; + + row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt; + + WriteAuxiliaries(modData, row); + + WriteWorkEntries(modData, row); + + WritePerformanceEntries(modData, row); + + row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare(); + row[COASTING_TIME_SHARE] = modData.CoastingTimeShare(); + row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare(); + + if (gearCount <= 0) { + return; + } + + WriteGearshiftStats(modData, row, gearCount); + } + + private static void WriteFuelconsumptionEntries(IModalDataContainer modData, DataRow row, Kilogram vehicleLoading, + CubicMeter cargoVolume) + { row[FCMAP_H] = modData.FCMapPerSecond().ConvertTo().Gramm.Per.Hour; var fcMapPerMeter = modData.FCMapPerMeter(); if (fcMapPerMeter != null) { @@ -441,27 +385,19 @@ namespace TUGraz.VectoCore.OutputData row[FCAUXC_H] = modData.FuelConsumptionAuxStartStopPerSecond().ConvertTo().Gramm.Per.Hour; var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionAuxStartStop(); - if (fuelConsumptionAuxStartStopCorrected != null) { - row[FCAUXC_KM] = fuelConsumptionAuxStartStopCorrected.ConvertTo().Gramm.Per.Kilo.Meter; - } + row[FCAUXC_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionAuxStartStopCorrected); row[FCWHTCC_H] = modData.FuelConsumptionWHTCPerSecond().ConvertTo().Gramm.Per.Hour; var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC(); - if (fuelConsumptionWHTCCorrected != null) { - row[FCWHTCC_KM] = fuelConsumptionWHTCCorrected.ConvertTo().Gramm.Per.Kilo.Meter; - } + row[FCWHTCC_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionWHTCCorrected); row[FCAAUX_H] = modData.FuelConsumptionAAUXPerSecond().ConvertTo().Gramm.Per.Hour; var fuelConsumptionAaux = modData.FuelConsumptionAAUX(); - if (fuelConsumptionAaux != null) { - row[FCAAUX_KM] = fuelConsumptionAaux.ConvertTo().Gramm.Per.Kilo.Meter; - } + row[FCAAUX_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionAaux); row[FCFINAL_H] = modData.FuelConsumptionFinalPerSecond().ConvertTo().Gramm.Per.Hour; var fcfinal = modData.FuelConsumptionFinal(); - if (fcfinal != null) { - row[FCFINAL_KM] = fcfinal.ConvertTo().Gramm.Per.Kilo.Meter; - } + row[FCFINAL_KM] = FuelConsumptionAsGrammPerKiloMeter(fcfinal); var fcPer100lkm = modData.FuelConsumptionFinalLiterPer100Kilometer(); row[FCFINAL_LITERPER100KM] = fcPer100lkm; @@ -472,22 +408,18 @@ namespace TUGraz.VectoCore.OutputData if (cargoVolume > 0 && fcPer100lkm != null) { row[FCFINAL_LiterPer100M3KM] = fcPer100lkm / cargoVolume; } + } - var kilogramPerMeter = modData.CO2PerMeter(); - if (kilogramPerMeter != null) { - row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter; - if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) { - row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton; - } - if (cargoVolume > 0) { - row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume; - } + private static SI FuelConsumptionAsGrammPerKiloMeter(SI fc) + { + if (fc == null) { + return null; } + return fc.ConvertTo().Gramm.Per.Kilo.Meter; + } - row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt; - - row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt; - + private void WriteAuxiliaries(IModalDataContainer modData, DataRow row) + { foreach (var aux in modData.Auxiliaries) { string colName; if (aux.Key == Constants.Auxiliaries.IDs.PTOConsumer || aux.Key == Constants.Auxiliaries.IDs.PTOTransmission) { @@ -504,27 +436,24 @@ namespace TUGraz.VectoCore.OutputData row[colName] = modData.AuxiliaryWork(aux.Value).ConvertTo().Kilo.Watt.Hour; } + } - row[E_FCMAP_POS] = modData.TotalEngineWorkPositive().ConvertTo().Kilo.Watt.Hour; - row[E_FCMAP_NEG] = -modData.TotalEngineWorkNegative().ConvertTo().Kilo.Watt.Hour; - row[E_POWERTRAIN_INERTIA] = modData.PowerAccelerations().ConvertTo().Kilo.Watt.Hour; - row[E_AUX] = modData.WorkAuxiliaries().ConvertTo().Kilo.Watt.Hour; - row[E_CLUTCH_LOSS] = modData.WorkClutch().ConvertTo().Kilo.Watt.Hour; - row[E_TC_LOSS] = modData.WorkTorqueConverter().ConvertTo().Kilo.Watt.Hour; - row[E_SHIFT_LOSS] = modData.WorkGearshift().ConvertTo().Kilo.Watt.Hour; - row[E_GBX_LOSS] = modData.WorkGearbox().ConvertTo().Kilo.Watt.Hour; - row[E_RET_LOSS] = modData.WorkRetarder().ConvertTo().Kilo.Watt.Hour; - row[E_AXL_LOSS] = modData.WorkAxlegear().ConvertTo().Kilo.Watt.Hour; - row[E_ANGLE_LOSS] = modData.WorkAngledrive().ConvertTo().Kilo.Watt.Hour; - row[E_BRAKE] = modData.WorkTotalMechanicalBrake().ConvertTo().Kilo.Watt.Hour; - row[E_VEHICLE_INERTIA] = modData.WorkVehicleInertia().ConvertTo().Kilo.Watt.Hour; - row[E_AIR] = modData.WorkAirResistance().ConvertTo().Kilo.Watt.Hour; - row[E_ROLL] = modData.WorkRollingResistance().ConvertTo().Kilo.Watt.Hour; - row[E_GRAD] = modData.WorkRoadGradientResistance().ConvertTo().Kilo.Watt.Hour; - - //var acc = modData.AccelerationPer3Seconds(); + private void WriteGearshiftStats(IModalDataContainer modData, DataRow row, uint gearCount) + { + row[NUM_GEARSHIFTS] = modData.GearshiftCount(); + var timeSharePerGear = modData.TimeSharePerGear(gearCount); + for (uint i = 0; i <= gearCount; i++) { + var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i); + if (!Table.Columns.Contains(colName)) { + Table.Columns.Add(colName, typeof(SI)); + } + row[colName] = timeSharePerGear[i]; + } + } + private void WritePerformanceEntries(IModalDataContainer modData, DataRow row) + { row[ACC] = modData.AccelerationAverage(); row[ACC_POS] = modData.AccelerationsPositive(); row[ACC_NEG] = modData.AccelerationsNegative(); @@ -542,25 +471,6 @@ namespace TUGraz.VectoCore.OutputData row[MAX_DECELERATION] = modData.MaxDeceleration(); row[AVG_ENGINE_SPEED] = modData.AvgEngineSpeed().AsRPM.SI<Scalar>(); row[MAX_ENGINE_SPEED] = modData.MaxEngineSpeed().AsRPM.SI<Scalar>(); - - row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare(); - row[COASTING_TIME_SHARE] = modData.CoastingTimeShare(); - row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare(); - - if (gearCount <= 0) { - return; - } - - row[NUM_GEARSHIFTS] = modData.GearshiftCount(); - var timeSharePerGear = modData.TimeSharePerGear(gearCount); - - for (uint i = 0; i <= gearCount; i++) { - var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i); - if (!Table.Columns.Contains(colName)) { - Table.Columns.Add(colName, typeof(SI)); - } - row[colName] = timeSharePerGear[i]; - } if (accTimeShare != null && decTimeShare != null && cruiseTimeShare != null) { var shareSum = accTimeShare + decTimeShare + cruiseTimeShare + stopTimeShare; if (!shareSum.IsEqual(100)) { @@ -573,6 +483,155 @@ namespace TUGraz.VectoCore.OutputData } } + private static void WriteWorkEntries(IModalDataContainer modData, DataRow row) + { + row[E_FCMAP_POS] = modData.TotalEngineWorkPositive().ConvertTo().Kilo.Watt.Hour; + row[E_FCMAP_NEG] = -modData.TotalEngineWorkNegative().ConvertTo().Kilo.Watt.Hour; + row[E_POWERTRAIN_INERTIA] = modData.PowerAccelerations().ConvertTo().Kilo.Watt.Hour; + row[E_AUX] = modData.WorkAuxiliaries().ConvertTo().Kilo.Watt.Hour; + row[E_CLUTCH_LOSS] = modData.WorkClutch().ConvertTo().Kilo.Watt.Hour; + row[E_TC_LOSS] = modData.WorkTorqueConverter().ConvertTo().Kilo.Watt.Hour; + row[E_SHIFT_LOSS] = modData.WorkGearshift().ConvertTo().Kilo.Watt.Hour; + row[E_GBX_LOSS] = modData.WorkGearbox().ConvertTo().Kilo.Watt.Hour; + row[E_RET_LOSS] = modData.WorkRetarder().ConvertTo().Kilo.Watt.Hour; + row[E_AXL_LOSS] = modData.WorkAxlegear().ConvertTo().Kilo.Watt.Hour; + row[E_ANGLE_LOSS] = modData.WorkAngledrive().ConvertTo().Kilo.Watt.Hour; + row[E_BRAKE] = modData.WorkTotalMechanicalBrake().ConvertTo().Kilo.Watt.Hour; + row[E_VEHICLE_INERTIA] = modData.WorkVehicleInertia().ConvertTo().Kilo.Watt.Hour; + row[E_AIR] = modData.WorkAirResistance().ConvertTo().Kilo.Watt.Hour; + row[E_ROLL] = modData.WorkRollingResistance().ConvertTo().Kilo.Watt.Hour; + row[E_GRAD] = modData.WorkRoadGradientResistance().ConvertTo().Kilo.Watt.Hour; + } + + private void WriteFullPowertrain(VectoRunData runData, DataRow row) + { + row[VEHICLE_MANUFACTURER] = runData.VehicleData.Manufacturer; + row[VIN_NUMBER] = runData.VehicleData.VIN; + row[VEHICLE_MODEL] = runData.VehicleData.ModelName; + + row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber(); + row[CURB_MASS] = runData.VehicleData.CurbWeight; + // - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>()); + row[LOADING] = runData.VehicleData.Loading; + row[CARGO_VOLUME] = runData.VehicleData.CargoVolume; + + row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight; + row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer; + row[ENGINE_MODEL] = runData.EngineData.ModelName; + row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel(); + row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null + ? runData.EngineData.RatedPowerDeclared.ConvertTo().Kilo.Watt + : runData.EngineData.FullLoadCurves[0].MaxPower.ConvertTo().Kilo.Watt; + row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>(); + row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null + ? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>() + : runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>(); + row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter; + + row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban; + row[ENGINE_WHTC_RURAL] = runData.EngineData.WHTCRural; + row[ENGINE_WHTC_MOTORWAY] = runData.EngineData.WHTCMotorway; + row[ENGINE_BF_COLD_HOT] = runData.EngineData.ColdHotCorrectionFactor; + row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer; + row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor; + + row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea; + + row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] = + runData.VehicleData.RollResistanceCoefficientWithoutTrailer; + row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] = + runData.VehicleData.TotalRollResistanceCoefficient; + + row[R_DYN] = runData.VehicleData.DynamicTyreRadius; + + row[NUM_AXLES_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleDriven); + row[NUM_AXLES_NON_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleNonDriven); + row[NUM_AXLES_TRAILER] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.Trailer); + + row[GEARBOX_MANUFACTURER] = runData.GearboxData.Manufacturer; + row[GEARBOX_MODEL] = runData.GearboxData.ModelName; + row[GEARBOX_TYPE] = runData.GearboxData.Type; + WriteGearboxData(runData, row); + + row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel(); + WriteRetarderData(runData, row); + + WriteAngledriveData(runData, row); + + row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer; + row[AXLE_MODEL] = runData.AxleGearData.ModelName; + row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>(); + + WriteAuxTechnologies(runData, row); + } + + private void WriteAuxTechnologies(VectoRunData runData, DataRow row) + { + foreach (var aux in runData.Aux) { + if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) { + continue; + } + var colName = string.Format(AUX_TECH_FORMAT, aux.ID); + + if (!Table.Columns.Contains(colName)) { + var col = Table.Columns.Add(colName, typeof(string)); + // move the new column to correct position + col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal); + } + + row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology); + } + } + + private static void WriteAngledriveData(VectoRunData runData, DataRow row) + { + if (runData.AngledriveData != null) { + row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer; + row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName; + row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio; + } else { + row[ANGLEDRIVE_MANUFACTURER] = "n.a."; + row[ANGLEDRIVE_MODEL] = "n.a."; + row[ANGLEDRIVE_RATIO] = "n.a."; + } + } + + private static void WriteRetarderData(VectoRunData runData, DataRow row) + { + if (runData.Retarder.Type.IsDedicatedComponent()) { + row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer; + row[RETARDER_MODEL] = runData.Retarder.ModelName; + } else { + row[RETARDER_MANUFACTURER] = "n.a."; + row[RETARDER_MODEL] = "n.a."; + } + } + + private static void WriteGearboxData(VectoRunData runData, DataRow row) + { + if (runData.GearboxData.Type.AutomaticTransmission()) { + row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 + ? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio) + ? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>() + : runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()) + : 0.SI<Scalar>(); + row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 + ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() + : 0.SI<Scalar>(); + row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer; + row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName; + } else { + row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 + ? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>() + : 0.SI<Scalar>(); + row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 + ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() + : 0.SI<Scalar>(); + row[TORQUECONVERTER_MANUFACTURER] = "n.a."; + row[TORQUECONVERTER_MODEL] = "n.a."; + } + } + private static string ReplaceNotAllowedCharacters(string text) { return text.Replace('#', '_').Replace(',', '_').Replace('\n', '_').Replace('\r', '_'); diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index 8742c8467be3c5437720170033726828683d3488..49a9821d455d6642223baa89463a2e5c5ceb6b64 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer), new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress), new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass.ToXMLFormat()), new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index 65d3a0821cdbf6ba4c82b6014dea707ca390c833..cd8e02123c5fcfd9655c3b31ce0041886c57b222 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -29,204 +29,213 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml; -using System.Xml.Linq; -using System.Xml.XPath; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; - -namespace TUGraz.VectoCore.OutputData.XML -{ - public class XMLDeclarationReport : DeclarationReport<XMLDeclarationReport.ResultEntry> - { - private readonly XMLFullReport _fullReport; - private readonly XMLCustomerReport _customerReport; - - private readonly IOutputDataWriter _writer; - - public class ResultEntry - { - public MeterPerSecond AverageSpeed { get; private set; } - - public Joule EnergyConsumptionTotal { get; private set; } - - public Kilogram CO2Total { get; private set; } - - public Kilogram FuelConsumptionTotal { get; private set; } - - public Meter Distance { get; private set; } - - public Scalar GearshiftCount { get; private set; } - - public Scalar FullLoadPercentage { get; private set; } - - public MeterPerSquareSecond MaxDeceleration { get; private set; } - - public MeterPerSquareSecond MaxAcceleration { get; private set; } - - public MeterPerSecond MaxSpeed { get; private set; } - - public MeterPerSecond MinSpeed { get; private set; } - - public string Error { get; private set; } - - public VectoRun.Status Status { get; private set; } - - public string StackTrace { get; private set; } - - public FuelType FuelType { get; private set; } - - public Kilogram Payload { get; private set; } - - public Kilogram TotalVehicleWeight { get; private set; } - - public CubicMeter CargoVolume { get; private set; } - - - public void SetResultData(VectoRunData runData, IModalDataContainer data) - { - FuelType = data.FuelData.FuelType; - Payload = runData.VehicleData.Loading; - CargoVolume = runData.VehicleData.CargoVolume; - TotalVehicleWeight = runData.VehicleData.TotalVehicleWeight; - Status = data.RunStatus; - Error = data.Error; - StackTrace = data.StackTrace; - AverageSpeed = data.Speed(); - MinSpeed = data.MinSpeed(); - MaxSpeed = data.MaxSpeed(); - MaxAcceleration = data.MaxAcceleration(); - MaxDeceleration = data.MaxDeceleration(); - FullLoadPercentage = data.EngineMaxLoadTimeShare(); - GearshiftCount = data.GearshiftCount(); - - Distance = data.Distance(); - - FuelConsumptionTotal = data.TimeIntegral<Kilogram>(ModalResultField.FCFinal); - CO2Total = FuelConsumptionTotal * data.FuelData.CO2PerFuelWeight; - EnergyConsumptionTotal = FuelConsumptionTotal * data.FuelData.LowerHeatingValue; - } - } - - public XMLDeclarationReport(IOutputDataWriter writer = null) - { - _fullReport = new XMLFullReport(); //new XDocument(new XDeclaration("1.0", "utf-8", "yes")); - _customerReport = new XMLCustomerReport(); - //CustomerReport = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); - - _writer = writer; - } - - public XDocument FullReport - { - get { return _fullReport.Report; } - } - - public XDocument CustomerReport - { - get { return _customerReport.Report; } - } - - - protected override void DoAddResult(ResultEntry entry, VectoRunData runData, IModalDataContainer modData) - { - entry.SetResultData(runData, modData); - } - - protected internal override void DoWriteReport() - { - foreach (var result in Missions.OrderBy(m => m.Key)) { - _fullReport.AddResult(result.Value); - _customerReport.AddResult(result.Value); - } - - _fullReport.GenerateReport(); - var fullReportHash = GetSignature(_fullReport.Report); - _customerReport.GenerateReport(fullReportHash); - - if (_writer != null) { - using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLFulll), Encoding.UTF8)) { - xmlWriter.Formatting = Formatting.Indented; - _fullReport.Report.WriteTo(xmlWriter); - xmlWriter.Flush(); - xmlWriter.Close(); - } - - using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLCOC), Encoding.UTF8)) { - xmlWriter.Formatting = Formatting.Indented; - _customerReport.Report.WriteTo(xmlWriter); - xmlWriter.Flush(); - xmlWriter.Close(); - } - } - } - - private XElement GetSignature(XDocument report) - { - return report.XPathSelectElement("/*[local-name()='VectoOutput']/*[local-name()='Signature']/*"); - } - - - protected override void DoInitializeReport(VectoRunData modelData, Segment segment) - { - _fullReport.Initialize(modelData, segment); - _customerReport.Initialize(modelData, segment); - } - - - public static IEnumerable<XElement> GetResults(ResultEntry result, XNamespace tns, bool fullOutput) - { - var fuel = FuelData.Instance().Lookup(result.FuelType); - var retVal = new List<XElement> { - new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter).Value() - .ToMinSignificantDigits(3, 1)), - new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/t-km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / - result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1)), - new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/m³-km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume).Value - ().ToMinSignificantDigits(3, 1)) - }; - //FC - if (fullOutput) { - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / 1e6).Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/t-km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / result.Payload.ConvertTo().Ton / 1e6) - .Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/m³-km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume / 1e6).Value() - .ToMinSignificantDigits(3, 1))); - } - if (fuel.FuelDensity != null) { - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/100km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter * 100) - .Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/t-km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter / - result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/m³-km"), - (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter / - result.CargoVolume).Value().ToMinSignificantDigits(3, 1))); - } - //CO2 - retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/km"), - (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter).Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/t-km"), - (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / - result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1))); - retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/m³-km"), - (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume).Value() - .ToMinSignificantDigits(3, 1))); - - return retVal; - } - } +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; + +namespace TUGraz.VectoCore.OutputData.XML +{ + public class XMLDeclarationReport : DeclarationReport<XMLDeclarationReport.ResultEntry> + { + private readonly XMLFullReport _fullReport; + private readonly XMLCustomerReport _customerReport; + + private readonly IOutputDataWriter _writer; + + public class ResultEntry + { + public MeterPerSecond AverageSpeed { get; private set; } + + public Joule EnergyConsumptionTotal { get; private set; } + + public Kilogram CO2Total { get; private set; } + + public Kilogram FuelConsumptionTotal { get; private set; } + + public Meter Distance { get; private set; } + + public Scalar GearshiftCount { get; private set; } + + public Scalar FullLoadPercentage { get; private set; } + + public MeterPerSquareSecond MaxDeceleration { get; private set; } + + public MeterPerSquareSecond MaxAcceleration { get; private set; } + + public MeterPerSecond MaxSpeed { get; private set; } + + public MeterPerSecond MinSpeed { get; private set; } + + public string Error { get; private set; } + + public VectoRun.Status Status { get; private set; } + + public string StackTrace { get; private set; } + + public FuelType FuelType { get; private set; } + + public Kilogram Payload { get; private set; } + + public Kilogram TotalVehicleWeight { get; private set; } + + public CubicMeter CargoVolume { get; private set; } + + + public void SetResultData(VectoRunData runData, IModalDataContainer data) + { + FuelType = data.FuelData.FuelType; + Payload = runData.VehicleData.Loading; + CargoVolume = runData.VehicleData.CargoVolume; + TotalVehicleWeight = runData.VehicleData.TotalVehicleWeight; + Status = data.RunStatus; + Error = data.Error; + StackTrace = data.StackTrace; + AverageSpeed = data.Speed(); + MinSpeed = data.MinSpeed(); + MaxSpeed = data.MaxSpeed(); + MaxAcceleration = data.MaxAcceleration(); + MaxDeceleration = data.MaxDeceleration(); + FullLoadPercentage = data.EngineMaxLoadTimeShare(); + GearshiftCount = data.GearshiftCount(); + + Distance = data.Distance(); + + FuelConsumptionTotal = data.TimeIntegral<Kilogram>(ModalResultField.FCFinal); + CO2Total = FuelConsumptionTotal * data.FuelData.CO2PerFuelWeight; + EnergyConsumptionTotal = FuelConsumptionTotal * data.FuelData.LowerHeatingValue; + } + } + + public XMLDeclarationReport(IOutputDataWriter writer = null) + { + _fullReport = new XMLFullReport(); //new XDocument(new XDeclaration("1.0", "utf-8", "yes")); + _customerReport = new XMLCustomerReport(); + //CustomerReport = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); + + _writer = writer; + } + + public XDocument FullReport + { + get { return _fullReport.Report; } + } + + public XDocument CustomerReport + { + get { return _customerReport.Report; } + } + + + protected override void DoAddResult(ResultEntry entry, VectoRunData runData, IModalDataContainer modData) + { + entry.SetResultData(runData, modData); + } + + protected internal override void DoWriteReport() + { + foreach (var result in Missions.OrderBy(m => m.Key)) { + _fullReport.AddResult(result.Value); + _customerReport.AddResult(result.Value); + } + + _fullReport.GenerateReport(); + var fullReportHash = GetSignature(_fullReport.Report); + _customerReport.GenerateReport(fullReportHash); + + if (_writer != null) { + using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLFulll), Encoding.UTF8)) { + xmlWriter.Formatting = Formatting.Indented; + _fullReport.Report.WriteTo(xmlWriter); + xmlWriter.Flush(); + xmlWriter.Close(); + } + + using (var xmlWriter = new XmlTextWriter(_writer.WriteStream(ReportType.DeclarationReportXMLCOC), Encoding.UTF8)) { + xmlWriter.Formatting = Formatting.Indented; + _customerReport.Report.WriteTo(xmlWriter); + xmlWriter.Flush(); + xmlWriter.Close(); + } + } + } + + private XElement GetSignature(XDocument report) + { + return report.XPathSelectElement("/*[local-name()='VectoOutput']/*[local-name()='Signature']/*"); + } + + + protected override void DoInitializeReport(VectoRunData modelData, Segment segment) + { + _fullReport.Initialize(modelData, segment); + _customerReport.Initialize(modelData, segment); + } + + + public static IEnumerable<XElement> GetResults(ResultEntry result, XNamespace tns, bool fullOutput) + { + var fuel = FuelData.Instance().Lookup(result.FuelType); + var retVal = new List<XElement> { + new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter).Value() + .ToMinSignificantDigits(3, 1)), + new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/t-km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / + result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1)), + result.CargoVolume > 0 + ? new XElement(tns + "FuelConsumption", new XAttribute("unit", "g/m³-km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume) + .Value + ().ToMinSignificantDigits(3, 1)) + : null + }; + //FC + if (fullOutput) { + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/km"), + (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / 1e6).Value().ToMinSignificantDigits(3, 1))); + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/t-km"), + (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / result.Payload.ConvertTo().Ton / 1e6) + .Value().ToMinSignificantDigits(3, 1))); + if (result.CargoVolume > 0) { + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "MJ/m³-km"), + (result.EnergyConsumptionTotal / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume / 1e6).Value() + .ToMinSignificantDigits(3, 1))); + } + } + if (fuel.FuelDensity != null) { + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/100km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter * 100) + .Value().ToMinSignificantDigits(3, 1))); + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/t-km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter / + result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1))); + if (result.CargoVolume > 0) { + retVal.Add(new XElement(tns + "FuelConsumption", new XAttribute("unit", "l/m³-km"), + (result.FuelConsumptionTotal.ConvertTo().Gramm / fuel.FuelDensity / result.Distance.ConvertTo().Kilo.Meter / + result.CargoVolume).Value().ToMinSignificantDigits(3, 1))); + } + } + //CO2 + retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/km"), + (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter).Value().ToMinSignificantDigits(3, 1))); + retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/t-km"), + (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / + result.Payload.ConvertTo().Ton).Value().ToMinSignificantDigits(3, 1))); + if (result.CargoVolume > 0) { + retVal.Add(new XElement(tns + "CO2", new XAttribute("unit", "g/m³-km"), + (result.CO2Total.ConvertTo().Gramm / result.Distance.ConvertTo().Kilo.Meter / result.CargoVolume).Value() + .ToMinSignificantDigits(3, 1))); + } + + return retVal; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs index 2dc022a0de6aefedd23278404165c24ac7b09dd1..2a1503b998a9b1dd17f244dee84956d5eee9f13d 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs @@ -73,7 +73,7 @@ namespace TUGraz.VectoCore.OutputData.XML { VehiclePart.Add( new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass.ToXMLFormat()), new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), @@ -90,8 +90,8 @@ namespace TUGraz.VectoCore.OutputData.XML GetAirDragDescription(modelData.AirdragData), GetAxleWheelsDescription(modelData.VehicleData), GetAuxiliariesDescription(modelData.Aux) - ) - ); + ) + ); InputDataIntegrity = new XElement(tns + "InputDataSignature", modelData.InputDataHash == null ? CreateDummySig() : new XElement(modelData.InputDataHash)); } @@ -102,7 +102,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "null")), new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "NOT AVAILABLE") - ); + ); } private XElement GetTorqueLimits(CombustionEngineData modelData) @@ -133,7 +133,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Engine_Displacement, engineData.Displacement.ConvertTo().Cubic.Centi.Meter.ToXMLFormat(0)), new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelType.ToXMLFormat()) - ); + ); } private XElement GetGearboxDescription(GearboxData gearboxData) @@ -143,7 +143,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Gearbox_TransmissionType, gearboxData.Type.ToXMLFormat()), new XElement(tns + "GearsCount", gearboxData.Gears.Count), new XElement(tns + "TransmissionRatioFinalGear", gearboxData.Gears.Last().Value.Ratio.ToXMLFormat(3)) - ); + ); } private XElement GetTorqueConverterDescription(TorqueConverterData torqueConverterData) @@ -186,7 +186,7 @@ namespace TUGraz.VectoCore.OutputData.XML return new XElement(tns + XMLNames.Component_AirDrag, new XElement(tns + "CertificationMethod", airdragData.CertificationMethod.ToXMLFormat()), new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); + ); } return new XElement(tns + XMLNames.Component_AirDrag, new XElement(tns + XMLNames.Component_Model, airdragData.ModelName), @@ -194,7 +194,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + "CertificationNumber", airdragData.CertificationNumber), new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, airdragData.DigestValueInput), new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); + ); } private XElement GetAxleWheelsDescription(VehicleData vehicleData) @@ -302,16 +302,16 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + "TotalVehicleMass", new XAttribute("unit", "kg"), result.TotalVehicleWeight.ToXMLFormat(0)), new XElement(tns + "Payload", new XAttribute("unit", "kg"), result.Payload.ToXMLFormat(0)), new XElement(tns + "FuelType", result.FuelType.ToXMLFormat()) - ), + ), new XElement(tns + "VehiclePerformance", new XElement(tns + "AverageSpeed", new XAttribute("unit", "km/h"), result.AverageSpeed.AsKmph.ToXMLFormat(1)), new XElement(tns + "MinSpeed", new XAttribute("unit", "km/h"), result.MinSpeed.AsKmph.ToXMLFormat(1)), new XElement(tns + "MaxSpeed", new XAttribute("unit", "km/h"), result.MaxSpeed.AsKmph.ToXMLFormat(1)), new XElement(tns + "MaxDeceleration", new XAttribute("unit", "m/s²"), result.MaxDeceleration.ToXMLFormat(2)), new XElement(tns + "MaxAcceleration", new XAttribute("unit", "m/s²"), result.MaxAcceleration.ToXMLFormat(2)), - new XElement(tns + "FullLoadDrivingtimePercentage", result.FullLoadPercentage.ToXMLFormat(0)), + new XElement(tns + "FullLoadDrivingtimePercentage", result.FullLoadPercentage.ToXMLFormat(2)), new XElement(tns + "GearshiftCount", result.GearshiftCount.ToXMLFormat(0)) - ), + ), //FC XMLDeclarationReport.GetResults(result, tns, true).Cast<object>().ToArray() }; @@ -334,18 +334,18 @@ namespace TUGraz.VectoCore.OutputData.XML var vehicle = new XElement(VehiclePart); vehicle.Add(InputDataIntegrity); retVal.Add(new XElement(tns + "VectoOutput", - new XAttribute("schemaVersion", "0.4"), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "di", di), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), - new XElement(tns + "Data", - vehicle, - results, - GetApplicationInfo()) + new XAttribute("schemaVersion", "0.4"), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "di", di), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + new XElement(tns + "Data", + vehicle, + results, + GetApplicationInfo()) ) - ); + ); var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.Write(retVal); diff --git a/VectoCore/VectoCore/Resources/XSD/VectoDeclarationDefinitions.1.0.xsd b/VectoCore/VectoCore/Resources/XSD/VectoDeclarationDefinitions.1.0.xsd index 9871aac1d6a1f527a3b3e8713fa7df721c29702d..c42a880d61856a8b937ee092ee0322164cc6e15a 100644 --- a/VectoCore/VectoCore/Resources/XSD/VectoDeclarationDefinitions.1.0.xsd +++ b/VectoCore/VectoCore/Resources/XSD/VectoDeclarationDefinitions.1.0.xsd @@ -1910,6 +1910,7 @@ ToDo: -0.00 <xs:documentation>P251 - enum</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> + <xs:enumeration value="N2"/> <xs:enumeration value="N3"/> </xs:restriction> </xs:simpleType> diff --git a/VectoCore/VectoCore/Resources/XSD/VectoOutputCustomer.xsd b/VectoCore/VectoCore/Resources/XSD/VectoOutputCustomer.xsd index aeb336e3e43219ec874004f95210c29f7331956e..52463b1c70511d16d264d9b5c9c8a9a3c3d214c1 100644 --- a/VectoCore/VectoCore/Resources/XSD/VectoOutputCustomer.xsd +++ b/VectoCore/VectoCore/Resources/XSD/VectoOutputCustomer.xsd @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- edited with XMLSpy v2016 rel. 2 (x64) (http://www.altova.com) by Helmut Eichlseder (TU Graz/Inst. f. VKM und THD) --> <!--W3C XML Schema generated by XMLSpy vXMLSpy Professional Edition v2016 rel. 2 (x64) (http://www.altova.com)--> -<xs:schema xmlns="urn:tugraz:ivt:VectoAPI:COCOutput:v0.4" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vdecdef="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.8" targetNamespace="urn:tugraz:ivt:VectoAPI:COCOutput:v0.4" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.4"> - <xs:import namespace="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.8" schemaLocation="VectoDeclarationDefinitions.0.8.xsd"/> +<xs:schema xmlns="urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.4" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vdecdef="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" targetNamespace="urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.4" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.4"> + <xs:import namespace="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" schemaLocation="VectoDeclarationDefinitions.1.0.xsd"/> <xs:element name="VectoCustomerInformation"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> diff --git a/VectoCore/VectoCore/Resources/XSD/VectoOutputManufacturer.xsd b/VectoCore/VectoCore/Resources/XSD/VectoOutputManufacturer.xsd index 214b10f49d4ce751414d8730cc79f394d2ca5474..e1bc1a3fa3118ee96b015bc4a3a5cefe2c72689f 100644 --- a/VectoCore/VectoCore/Resources/XSD/VectoOutputManufacturer.xsd +++ b/VectoCore/VectoCore/Resources/XSD/VectoOutputManufacturer.xsd @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- edited with XMLSpy v2016 rel. 2 (x64) (http://www.altova.com) by Helmut Eichlseder (TU Graz/Inst. f. VKM und THD) --> <!--W3C XML Schema generated by XMLSpy vXMLSpy Professional Edition v2016 rel. 2 (x64) (http://www.altova.com)--> -<xs:schema xmlns="urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vdecdef="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.8" targetNamespace="urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.4"> - <xs:import namespace="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v0.8" schemaLocation="VectoDeclarationDefinitions.0.8.xsd"/> +<xs:schema xmlns="urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vdecdef="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" targetNamespace="urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.4"> + <xs:import namespace="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" schemaLocation="VectoDeclarationDefinitions.1.0.xsd"/> <xs:element name="VectoOutput"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> diff --git a/VectoCore/VectoCore/Utils/DelaunayMap.cs b/VectoCore/VectoCore/Utils/DelaunayMap.cs index 57a7739e6136db7e0ccba3d683fc4c3f74c18bd6..c91dc714f38f3d18b0f5b3c2a1f61135855e9c6e 100644 --- a/VectoCore/VectoCore/Utils/DelaunayMap.cs +++ b/VectoCore/VectoCore/Utils/DelaunayMap.cs @@ -29,315 +29,316 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Windows.Forms.DataVisualization.Charting; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using Point = TUGraz.VectoCommon.Utils.Point; - -namespace TUGraz.VectoCore.Utils -{ - public sealed class DelaunayMap : LoggingObject - { - private ICollection<Point> _points = new HashSet<Point>(); - private Triangle[] _triangles; - private Edge[] _convexHull; - - private readonly string _mapName; - private double _minY; - private double _minX; - private double _maxY; - private double _maxX; - - public DelaunayMap(string name) - { - _mapName = name; - } - - public void AddPoint(double x, double y, double z) - { - _points.Add(new Point(x, y, z)); - } - - public IReadOnlyCollection<Point> Entries - { - get { - var retVal = new Point[_points.Count]; - var i = 0; - foreach (var pt in _points) { - retVal[i++] = new Point(pt.X * (_maxX - _minX) + _minX, pt.Y * (_maxY - _minY) + _minY, pt.Z); - } - return retVal; - } - } - - /// <summary> - /// Triangulate the points. - /// </summary> - /// <remarks> - /// Triangulation with the Bowyer-Watson algorithm (iteratively insert points into a super triangle). - /// https://en.wikipedia.org/wiki/Bowyer%E2%80%93Watson_algorithm - /// </remarks> - public void Triangulate() - { - if (_points.Count < 3) { - throw new ArgumentException(string.Format("{0}: Triangulation needs at least 3 Points. Got {1} Points.", _mapName, - _points.Count)); - } - - SanitycheckInputPoints(); - - // The "supertriangle" encompasses all triangulation points. - // This is just a helper triangle which initializes the algorithm and will be removed in the end of the algorithm. - _maxX = _points.Max(p => p.X); - _maxY = _points.Max(p => p.Y); - _minX = _points.Min(p => p.X); - _minY = _points.Min(p => p.Y); - _points = - _points.Select(p => new Point((p.X - _minX) / (_maxX - _minX), (p.Y - _minY) / (_maxY - _minY), p.Z)).ToList(); - var superTriangle = new Triangle(new Point(-1, -1), new Point(4, -1), new Point(-1, 4)); - var triangles = new List<Triangle> { superTriangle }; - - var pointCount = 0; - - var points = _points.ToArray(); - - // iteratively add each point into the correct triangle and split up the triangle - foreach (var point in points) { - // If the vertex lies inside the circumcircle of a triangle, the edges of this triangle are - // added to the edge buffer and the triangle is removed from list. - // Remove duplicate edges. This leaves the convex hull of the edges. - // The edges in this convex hull are oriented counterclockwise! - - var newTriangles = triangles.Select((t, i) => Tuple.Create(i, t, t.ContainsInCircumcircle(point))) - .Where(t => t.Item3) - .Reverse() - .SelectMany(t => { - triangles.RemoveAt(t.Item1); - return t.Item2.GetEdges(); - }) - .GroupBy(edge => edge) - .Where(group => group.Count() == 1) - .Select(group => new Triangle(group.Key.P1, group.Key.P2, point)).ToList(); - - triangles.AddRange(newTriangles); - - //DrawGraph(pointCount, triangles, superTriangle, xmin, xmax, ymin, ymax, point); - pointCount++; - - // check invariant: m = 2n-2-k - // m...triangle count - // n...point count (pointCount +3 points on the supertriangle) - // k...points on convex hull (exactly 3 --> supertriangle) - if (triangles.Count != 2 * (pointCount + 3) - 2 - 3) { - throw new VectoException( - "Delaunay-Triangulation invariant violated! Triangle count and point count doesn't fit together."); - } - } - -#if TRACE - DrawGraph(pointCount, triangles, superTriangle, points); -#endif - _convexHull = triangles.FindAll(t => t.SharesVertexWith(superTriangle)). - SelectMany(t => t.GetEdges()). - Where(e => !(superTriangle.Contains(e.P1) || superTriangle.Contains(e.P2))).ToArray(); - - _triangles = triangles.FindAll(t => !t.SharesVertexWith(superTriangle)).ToArray(); - } - - private void SanitycheckInputPoints() - { - var duplicates = _points.GroupBy(pt => new { pt.X, pt.Y }, x => x).Where(g => g.Count() > 1).ToList(); - - foreach (var duplicate in duplicates) { - Log.Error("{0}: Input Point appears twice: x: {1}, y: {2}", duplicate.Key.X, duplicate.Key.Y); - } - if (duplicates.Any()) { - throw new VectoException("{0}: Input Data for Delaunay map contains duplicates! \n{1}", _mapName, - string.Join("\n", duplicates.Select(pt => string.Format("{0} / {1}", pt.Key.X, pt.Key.Y)))); - } - } - - public void DrawGraph() - { - var superTriangle = new Triangle(new Point(-1, -1), new Point(4, -1), new Point(-1, 4)); - DrawGraph(0, _triangles, superTriangle, _points.ToArray()); - } - - /// <summary> - /// Draws the delaunay map (except supertriangle). - /// </summary> - private static void DrawGraph(int i, IEnumerable<Triangle> triangles, Triangle superTriangle, Point[] points, - Point lastPoint = null) - { - var xmin = Math.Min(points.Min(p => p.X), lastPoint != null ? lastPoint.X : double.NaN); - var xmax = Math.Max(points.Max(p => p.X), lastPoint != null ? lastPoint.X : double.NaN); - var ymin = Math.Min(points.Min(p => p.Y), lastPoint != null ? lastPoint.Y : double.NaN); - var ymax = Math.Max(points.Max(p => p.Y), lastPoint != null ? lastPoint.Y : double.NaN); - - using (var chart = new Chart { Width = 1000, Height = 1000 }) { - chart.ChartAreas.Add(new ChartArea("main") { - AxisX = new Axis { Minimum = Math.Min(xmin, xmin), Maximum = Math.Max(xmax, xmax) }, - AxisY = new Axis { Minimum = Math.Min(ymin, ymin), Maximum = Math.Max(ymax, ymax) } - }); - - foreach (var tr in triangles) { - if (tr.SharesVertexWith(superTriangle)) { - continue; - } - - var series = new Series { - ChartType = SeriesChartType.FastLine, - Color = lastPoint != null && tr.Contains(lastPoint) ? Color.Red : Color.Blue - }; - series.Points.AddXY(tr.P1.X, tr.P1.Y); - series.Points.AddXY(tr.P2.X, tr.P2.Y); - series.Points.AddXY(tr.P3.X, tr.P3.Y); - series.Points.AddXY(tr.P1.X, tr.P1.Y); - chart.Series.Add(series); - } - - if (lastPoint != null) { - var series = new Series { - ChartType = SeriesChartType.Point, - Color = Color.Red, - MarkerSize = 5, - MarkerStyle = MarkerStyle.Circle - }; - series.Points.AddXY(lastPoint.X, lastPoint.Y); - chart.Series.Add(series); - } - - var frame = new StackFrame(2); - var method = frame.GetMethod(); - System.Diagnostics.Debug.Assert(method.DeclaringType != null, "method.DeclaringType != null"); - var type = string.Join("", method.DeclaringType.Name.Split(Path.GetInvalidFileNameChars())); - var methodName = string.Join("", method.Name.Split(Path.GetInvalidFileNameChars())); - Directory.CreateDirectory("delaunay"); - chart.SaveImage(string.Format("delaunay\\{0}_{1}_{2}_{3}.png", type, methodName, superTriangle.GetHashCode(), i), - ChartImageFormat.Png); - } - } - - public double? Interpolate(SI x, SI y) - { - return Interpolate(x.Value(), y.Value()); - } - - /// <summary> - /// Interpolates the value of an point in the delaunay map. - /// </summary> - /// <param name="x"></param> - /// <param name="y"></param> - /// <returns>a value if interpolation is successfull, - /// null if interpolation has failed.</returns> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public double? Interpolate(double x, double y) - { - if (_triangles == null) { - throw new VectoException("Interpolation not possible. Call DelaunayMap.Triangulate first."); - } - - x = (x - _minX) / (_maxX - _minX); - y = (y - _minY) / (_maxY - _minY); - - var i = 0; - while (i < _triangles.Length && !_triangles[i].IsInside(x, y, true)) { - i++; - } - if (i == _triangles.Length) { - i = 0; - while (i < _triangles.Length && !_triangles[i].IsInside(x, y, false)) { - i++; - } - } - - if (i == _triangles.Length) { - return null; - } - - var tr = _triangles[i]; - var plane = new Plane(tr); - return (plane.W - plane.X * x - plane.Y * y) / plane.Z; - } - - public double Extrapolate(SI x, SI y) - { - return Extrapolate(x.Value(), y.Value()); - } - - /// <summary> - /// Extrapolates the value of an point on the edges of a delaunay map. - /// </summary> - /// <param name="x"></param> - /// <param name="y"></param> - /// <returns></returns> - public double Extrapolate(double x, double y) - { - x = (x - _minX) / (_maxX - _minX); - y = (y - _minY) / (_maxY - _minY); - var point = new Point(x, y); - - // get nearest point on convex hull - var nearestPoint = _convexHull.Select(e => e.P1).MinBy(p => Math.Pow(p.X - x, 2) + Math.Pow(p.Y - y, 2)); - - // test if point is on left side of the perpendicular vector (to x,y coordinates) of edge1 in the nearest point - // ^ - // (point) | - // | - // (p1)--edge1-->(nearestPoint) - var edge1 = _convexHull.First(e => e.P2.Equals(nearestPoint)); - if (point.IsLeftOf(new Edge(nearestPoint, edge1.Vector.Perpendicular() + nearestPoint))) { - return ExtrapolateOnEdge(x, y, edge1); - } - - // test if point is on right side of the perpendicular vector of edge2 in the nearest point - // ^ - // | (point) - // | - // (nearestPoint)--edge2-->(p2) - var edge2 = _convexHull.First(e => e.P1.Equals(nearestPoint)); - if (!point.IsLeftOf(new Edge(nearestPoint, edge2.Vector.Perpendicular() + nearestPoint))) { - return ExtrapolateOnEdge(x, y, edge2); - } - - // if point is right of perpendicular vector of edge1 and left of perpendicular vector of edge2: take the nearest point z-value - return nearestPoint.Z; - } - - /// <summary> - /// Constant z-axis-extrapolation of a point from a line - /// </summary> - /// <remarks> - /// https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line - /// </remarks> - /// <param name="x"></param> - /// <param name="y"></param> - /// <param name="edge"></param> - /// <returns></returns> - private static double ExtrapolateOnEdge(double x, double y, Edge edge) - { - // shortcut if edge end points have same Z values - if (edge.P1.Z.IsEqual(edge.P2.Z)) { - return edge.P1.Z; - } - - // 2d vector of the edge: A--->B - var ab = new Point(edge.Vector.X, edge.Vector.Y); - - // 2d vector of the point: A---->P - var ap = new Point(x - edge.P1.X, y - edge.P1.Y); - - // projection of point (x,y) onto the edge - var z = edge.P1.Z + edge.Vector.Z * (ap.Dot(ab) / ab.Dot(ab)); - return z; - } - } +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Windows.Forms.DataVisualization.Charting; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using Point = TUGraz.VectoCommon.Utils.Point; + +namespace TUGraz.VectoCore.Utils +{ + public sealed class DelaunayMap : LoggingObject + { + private ICollection<Point> _points = new HashSet<Point>(); + private Triangle[] _triangles; + private Edge[] _convexHull; + + private readonly string _mapName; + private double _minY; + private double _minX; + private double _maxY; + private double _maxX; + + public DelaunayMap(string name) + { + _mapName = name; + } + + public void AddPoint(double x, double y, double z) + { + _points.Add(new Point(x, y, z)); + } + + public IReadOnlyCollection<Point> Entries + { + get + { + var retVal = new Point[_points.Count]; + var i = 0; + foreach (var pt in _points) { + retVal[i++] = new Point(pt.X * (_maxX - _minX) + _minX, pt.Y * (_maxY - _minY) + _minY, pt.Z); + } + return retVal; + } + } + + /// <summary> + /// Triangulate the points. + /// </summary> + /// <remarks> + /// Triangulation with the Bowyer-Watson algorithm (iteratively insert points into a super triangle). + /// https://en.wikipedia.org/wiki/Bowyer%E2%80%93Watson_algorithm + /// </remarks> + public void Triangulate() + { + if (_points.Count < 3) { + throw new ArgumentException(string.Format("{0}: Triangulation needs at least 3 Points. Got {1} Points.", _mapName, + _points.Count)); + } + + SanitycheckInputPoints(); + + // The "supertriangle" encompasses all triangulation points. + // This is just a helper triangle which initializes the algorithm and will be removed in the end of the algorithm. + _maxX = _points.Max(p => p.X); + _maxY = _points.Max(p => p.Y); + _minX = _points.Min(p => p.X); + _minY = _points.Min(p => p.Y); + _points = + _points.Select(p => new Point((p.X - _minX) / (_maxX - _minX), (p.Y - _minY) / (_maxY - _minY), p.Z)).ToList(); + var superTriangle = new Triangle(new Point(-1, -1), new Point(4, -1), new Point(-1, 4)); + var triangles = new List<Triangle> { superTriangle }; + + var pointCount = 0; + + var points = _points.ToArray(); + + // iteratively add each point into the correct triangle and split up the triangle + foreach (var point in points) { + // If the vertex lies inside the circumcircle of a triangle, the edges of this triangle are + // added to the edge buffer and the triangle is removed from list. + // Remove duplicate edges. This leaves the convex hull of the edges. + // The edges in this convex hull are oriented counterclockwise! + + var newTriangles = triangles.Select((t, i) => Tuple.Create(i, t, t.ContainsInCircumcircle(point))) + .Where(t => t.Item3) + .Reverse() + .SelectMany(t => { + triangles.RemoveAt(t.Item1); + return t.Item2.GetEdges(); + }) + .GroupBy(edge => edge) + .Where(group => group.Count() == 1) + .Select(group => new Triangle(group.Key.P1, group.Key.P2, point)).ToList(); + + triangles.AddRange(newTriangles); + + //DrawGraph(pointCount, triangles, superTriangle, xmin, xmax, ymin, ymax, point); + pointCount++; + + // check invariant: m = 2n-2-k + // m...triangle count + // n...point count (pointCount +3 points on the supertriangle) + // k...points on convex hull (exactly 3 --> supertriangle) + if (triangles.Count != 2 * (pointCount + 3) - 2 - 3) { + throw new VectoException( + "Delaunay-Triangulation invariant violated! Triangle count and point count doesn't fit together."); + } + } + +#if TRACE + DrawGraph(pointCount, triangles, superTriangle, points); +#endif + _convexHull = triangles.FindAll(t => t.SharesVertexWith(superTriangle)). + SelectMany(t => t.GetEdges()). + Where(e => !(superTriangle.Contains(e.P1) || superTriangle.Contains(e.P2))).ToArray(); + + _triangles = triangles.FindAll(t => !t.SharesVertexWith(superTriangle)).ToArray(); + } + + private void SanitycheckInputPoints() + { + var duplicates = _points.GroupBy(pt => new { pt.X, pt.Y }, x => x).Where(g => g.Count() > 1).ToList(); + + foreach (var duplicate in duplicates) { + Log.Error("{0}: Input Point appears twice: x: {1}, y: {2}", duplicate.Key.X, duplicate.Key.Y); + } + if (duplicates.Any()) { + throw new VectoException("{0}: Input Data for Delaunay map contains duplicates! \n{1}", _mapName, + string.Join("\n", duplicates.Select(pt => string.Format("{0} / {1}", pt.Key.X, pt.Key.Y)))); + } + } + + public void DrawGraph() + { + var superTriangle = new Triangle(new Point(-1, -1), new Point(4, -1), new Point(-1, 4)); + DrawGraph(0, _triangles, superTriangle, _points.ToArray()); + } + + /// <summary> + /// Draws the delaunay map (except supertriangle). + /// </summary> + private static void DrawGraph(int i, IEnumerable<Triangle> triangles, Triangle superTriangle, Point[] points, + Point lastPoint = null) + { + var xmin = Math.Min(points.Min(p => p.X), lastPoint != null ? lastPoint.X : double.NaN); + var xmax = Math.Max(points.Max(p => p.X), lastPoint != null ? lastPoint.X : double.NaN); + var ymin = Math.Min(points.Min(p => p.Y), lastPoint != null ? lastPoint.Y : double.NaN); + var ymax = Math.Max(points.Max(p => p.Y), lastPoint != null ? lastPoint.Y : double.NaN); + + using (var chart = new Chart { Width = 1000, Height = 1000 }) { + chart.ChartAreas.Add(new ChartArea("main") { + AxisX = new Axis { Minimum = Math.Min(xmin, xmin), Maximum = Math.Max(xmax, xmax) }, + AxisY = new Axis { Minimum = Math.Min(ymin, ymin), Maximum = Math.Max(ymax, ymax) } + }); + + foreach (var tr in triangles) { + if (tr.SharesVertexWith(superTriangle)) { + continue; + } + + var series = new Series { + ChartType = SeriesChartType.FastLine, + Color = lastPoint != null && tr.Contains(lastPoint) ? Color.Red : Color.Blue + }; + series.Points.AddXY(tr.P1.X, tr.P1.Y); + series.Points.AddXY(tr.P2.X, tr.P2.Y); + series.Points.AddXY(tr.P3.X, tr.P3.Y); + series.Points.AddXY(tr.P1.X, tr.P1.Y); + chart.Series.Add(series); + } + + if (lastPoint != null) { + var series = new Series { + ChartType = SeriesChartType.Point, + Color = Color.Red, + MarkerSize = 5, + MarkerStyle = MarkerStyle.Circle + }; + series.Points.AddXY(lastPoint.X, lastPoint.Y); + chart.Series.Add(series); + } + + var frame = new StackFrame(2); + var method = frame.GetMethod(); + System.Diagnostics.Debug.Assert(method.DeclaringType != null, "method.DeclaringType != null"); + var type = string.Join("", method.DeclaringType.Name.Split(Path.GetInvalidFileNameChars())); + var methodName = string.Join("", method.Name.Split(Path.GetInvalidFileNameChars())); + Directory.CreateDirectory("delaunay"); + chart.SaveImage(string.Format("delaunay\\{0}_{1}_{2}_{3}.png", type, methodName, superTriangle.GetHashCode(), i), + ChartImageFormat.Png); + } + } + + public double? Interpolate(SI x, SI y) + { + return Interpolate(x.Value(), y.Value()); + } + + /// <summary> + /// Interpolates the value of an point in the delaunay map. + /// </summary> + /// <param name="x"></param> + /// <param name="y"></param> + /// <returns>a value if interpolation is successfull, + /// null if interpolation has failed.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double? Interpolate(double x, double y) + { + if (_triangles == null) { + throw new VectoException("Interpolation not possible. Call DelaunayMap.Triangulate first."); + } + + x = (x - _minX) / (_maxX - _minX); + y = (y - _minY) / (_maxY - _minY); + + var i = 0; + while (i < _triangles.Length && !_triangles[i].IsInside(x, y, true)) { + i++; + } + if (i == _triangles.Length) { + i = 0; + while (i < _triangles.Length && !_triangles[i].IsInside(x, y, false)) { + i++; + } + } + + if (i == _triangles.Length) { + return null; + } + + var tr = _triangles[i]; + var plane = new Plane(tr); + return (plane.W - plane.X * x - plane.Y * y) / plane.Z; + } + + public double Extrapolate(SI x, SI y) + { + return Extrapolate(x.Value(), y.Value()); + } + + /// <summary> + /// Extrapolates the value of an point on the edges of a delaunay map. + /// </summary> + /// <param name="x"></param> + /// <param name="y"></param> + /// <returns></returns> + public double Extrapolate(double x, double y) + { + x = (x - _minX) / (_maxX - _minX); + y = (y - _minY) / (_maxY - _minY); + var point = new Point(x, y); + + // get nearest point on convex hull + var nearestPoint = _convexHull.Select(e => e.P1).MinBy(p => Math.Pow(p.X - x, 2) + Math.Pow(p.Y - y, 2)); + + // test if point is on left side of the perpendicular vector (to x,y coordinates) of edge1 in the nearest point + // ^ + // (point) | + // | + // (p1)--edge1-->(nearestPoint) + var edge1 = _convexHull.First(e => e.P2.Equals(nearestPoint)); + if (point.IsLeftOf(new Edge(nearestPoint, edge1.Vector.Perpendicular() + nearestPoint))) { + return ExtrapolateOnEdge(x, y, edge1); + } + + // test if point is on right side of the perpendicular vector of edge2 in the nearest point + // ^ + // | (point) + // | + // (nearestPoint)--edge2-->(p2) + var edge2 = _convexHull.First(e => e.P1.Equals(nearestPoint)); + if (!point.IsLeftOf(new Edge(nearestPoint, edge2.Vector.Perpendicular() + nearestPoint))) { + return ExtrapolateOnEdge(x, y, edge2); + } + + // if point is right of perpendicular vector of edge1 and left of perpendicular vector of edge2: take the nearest point z-value + return nearestPoint.Z; + } + + /// <summary> + /// Constant z-axis-extrapolation of a point from a line + /// </summary> + /// <remarks> + /// https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line + /// </remarks> + /// <param name="x"></param> + /// <param name="y"></param> + /// <param name="edge"></param> + /// <returns></returns> + private static double ExtrapolateOnEdge(double x, double y, Edge edge) + { + // shortcut if edge end points have same Z values + if (edge.P1.Z.IsEqual(edge.P2.Z)) { + return edge.P1.Z; + } + + // 2d vector of the edge: A--->B + var ab = new Point(edge.Vector.X, edge.Vector.Y); + + // 2d vector of the point: A---->P + var ap = new Point(x - edge.P1.X, y - edge.P1.Y); + + // projection of point (x,y) onto the edge + var z = edge.P1.Z + edge.Vector.Z * (ap.Dot(ab) / ab.Dot(ab)); + return z; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs index e904ab0adeb9f252dca49b16d2d47476c175298d..72ad52041301e8e2e387014c0b517774a0383ec7 100644 --- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs +++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs @@ -38,6 +38,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using DocumentFormat.OpenXml.Spreadsheet; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -111,19 +112,13 @@ namespace TUGraz.VectoCore.Utils TrimWhiteSpace = true }; - string[] colsWithoutComment = { }; - - try { - var fields = p.ReadFields(); - if (fields == null) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - colsWithoutComment = fields - .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .ToArray(); - } catch (ArgumentNullException) { + var hdrFields = p.ReadFields(); + if (hdrFields == null) { throw new CSVReadException("CSV Read Error: File was empty."); } + var colsWithoutComment = hdrFields + .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .ToArray(); double tmp; var columns = colsWithoutComment @@ -142,17 +137,10 @@ namespace TUGraz.VectoCore.Utils columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); } - //var table = new DataTable(); - foreach (var col in columns) { - table.Columns.Add(col); - } - - if (p.EndOfData) { - return; - } + columns.ForEach(col => table.Columns.Add(col)); var lineNumber = 1; - do { + while (!p.EndOfData) { string[] cells = { }; if (firstLineIsData) { cells = colsWithoutComment; @@ -179,7 +167,7 @@ namespace TUGraz.VectoCore.Utils string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e); } lineNumber++; - } while (!p.EndOfData); + } } /// <summary> diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index aae00d06abb7382634365a52ac96303aa8ee38ce..72a0ccda5bb9b2d4c02324f48c836f848d279cab 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -155,6 +155,7 @@ <Compile Include="InputData\Reader\Impl\EngineeringModeVectoRunDataFactory.cs" /> <Compile Include="InputData\Reader\Impl\EngineOnlyVectoRunDataFactory.cs" /> <Compile Include="InputData\Reader\ShiftPolygonReader.cs" /> + <Compile Include="Models\Declaration\AuxDemandEntry.cs" /> <Compile Include="Models\Declaration\AuxiliaryTypeHelper.cs" /> <Compile Include="Models\Connector\Ports\IDriverDemandPort.cs" /> <Compile Include="Models\Connector\Ports\IDrivingCyclePort.cs" /> diff --git a/VectoCore/VectoCoreTest/FileIO/JsonTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonTest.cs index 25bd9dda532352fcec1dd26b0776a82f9fb0d67c..c33efbd250ff758d48976aeeab3d394d1e937870 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonTest.cs @@ -29,420 +29,476 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.IO; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.Tests.Utils; - -namespace TUGraz.VectoCore.Tests.FileIO -{ - [TestClass] - public class JsonTest - { - private const string TestJobFile = @"Testdata\Jobs\40t_Long_Haul_Truck.vecto"; - private const string TestVehicleFile = @"Testdata\Components\24t Coach.vveh"; - - [TestMethod] - public void ReadJobTest() - { - var job = JSONInputDataFactory.ReadJsonJob(TestJobFile); - - Assert.IsNotNull(job); - // AssertHelper.Exception<InvalidFileFormatException>(() => ); - } - - [TestMethod] - public void NoEngineFileTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("EngineFile").Remove(); - - AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), - "JobFile: Failed to read Engine file '': Key EngineFile not found"); - } - - [TestMethod] - public void NoGearboxFileTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("GearboxFile").Remove(); - - AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), - "JobFile: Failed to read Gearbox file '': Key GearboxFile not found"); - } - - [TestMethod] - public void NoVehicleFileTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("VehicleFile").Remove(); - - AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), - "JobFile: Failed to read Vehicle file '': Key VehicleFile not found"); - } - - [TestMethod] - public void NoCyclesTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("Cycles").Remove(); - - var tmp = new JSONInputDataV2(json, TestJobFile).Cycles; - Assert.AreEqual(0, tmp.Count); - } - - [TestMethod] - public void NoAuxTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("Aux").Remove(); - - // MK,2016-01-20: Changed for PWheel: aux entry may be missing, and that is ok. - var tmp = new JSONInputDataV2(json, TestJobFile).AuxiliaryInputData().Auxiliaries; - Assert.IsTrue(tmp.Count == 0); - } - - [TestMethod] - public void NoDriverAccCurveTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("VACC").Remove(); - - IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); - var tmp = input.DriverInputData.AccelerationCurve; - Assert.IsNull(tmp); - } - - [TestMethod] - public void UseDeclarationDriverAccCurveTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - json["Body"]["VACC"] = "Truck"; - - IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); - var tmp = input.DriverInputData.AccelerationCurve; - Assert.IsNotNull(tmp); - } - - [TestMethod] - public void NoLookaheadCoastingTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("LAC").Remove(); - - IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); - var tmp = input.DriverInputData.Lookahead; - Assert.IsNull(tmp); - } - - [TestMethod] - public void NoOverspeedEcoRollTest() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - ((JObject)json["Body"]).Property("OverSpeedEcoRoll").Remove(); - - AssertHelper.Exception<VectoException>( - () => { var tmp = new JSONInputDataV2(json, TestJobFile).DriverInputData.OverSpeedEcoRoll; }, - "Key OverSpeedEcoRoll not found"); - } - - [TestMethod] - public void ReadGearboxV5() - { - var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\Gearbox_v5.vgbx"); - - var ratios = new[] { 3.0, 1.0, 0.8 }; - Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); - for (int i = 0; i < ratios.Length; i++) { - Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); - } - var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, - MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, - 0.5.SI<Meter>(), - true); - Assert.AreEqual(ratios.Length, gbxData.Gears.Count); - - // interpreted as gearbox with first and second gear using TC (due to gear ratios) - Assert.IsFalse(gbxData.Gears[1].HasLockedGear); - Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[2].HasLockedGear); - Assert.IsTrue(gbxData.Gears[2].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[3].HasLockedGear); - Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); - } - - [TestMethod] - public void ReadGearboxSerialTC() - { - var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerial.vgbx"); - - var ratios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 }; - Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); - for (int i = 0; i < ratios.Length; i++) { - Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); - } - var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, - MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, - 0.5.SI<Meter>(), - true); - Assert.AreEqual(ratios.Length, gbxData.Gears.Count); - - Assert.IsTrue(gbxData.Gears[1].HasLockedGear); - Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[2].HasLockedGear); - Assert.IsFalse(gbxData.Gears[2].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[3].HasLockedGear); - Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); - - var gear = gbxData.Gears[1]; - Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); - } - - [TestMethod] - public void ReadGearboxPowersplitTC() - { - var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxPowerSplit.vgbx"); - - var ratios = new[] { 1.35, 1.0, 0.73 }; - Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); - for (int i = 0; i < ratios.Length; i++) { - Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); - } - var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, - MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, - 0.5.SI<Meter>(), - true); - Assert.AreEqual(ratios.Length, gbxData.Gears.Count); - - Assert.IsTrue(gbxData.Gears[1].HasLockedGear); - Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[2].HasLockedGear); - Assert.IsFalse(gbxData.Gears[2].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[3].HasLockedGear); - Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); - - Assert.AreEqual(1, gbxData.Gears[1].TorqueConverterRatio); - } - - [TestMethod] - public void ReadGearboxDualTC() - { - var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerialDualTC.vgbx"); - - var ratios = new[] { 4.35, 2.4, 1.8, 1.3, 1.0 }; - Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); - for (int i = 0; i < ratios.Length; i++) { - Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); - } - var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, - MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, - 0.5.SI<Meter>(), - true); - Assert.AreEqual(ratios.Length, gbxData.Gears.Count); - - Assert.IsFalse(gbxData.Gears[1].HasLockedGear); - Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[2].HasLockedGear); - Assert.IsTrue(gbxData.Gears[2].HasTorqueConverter); - Assert.IsTrue(gbxData.Gears[3].HasLockedGear); - Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); - - - var gear = gbxData.Gears[2]; - Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); - } - - //[TestMethod] - //public void TestReadingElectricTechlist() - //{ - // var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); - // ((JArray)json["Body"]["Aux"][3]["TechList"]).Add("LED lights"); - - // var job = new JSONInputDataV2(json, TestJobFile); - // foreach (var aux in job.Auxiliaries) { - // if (aux.ID == "ES") { - // Assert.AreEqual(1, aux.TechList.Count); - // Assert.AreEqual("LED lights", aux.TechList.First()); - // } - // } - //} - - [TestMethod] - public void JSON_Read_AngleGear() - { - var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestVehicleFile))); - var angleGear = json["Body"]["Angledrive"]; - - Assert.AreEqual(AngledriveType.SeparateAngledrive, - angleGear["Type"].Value<string>().ParseEnum<AngledriveType>()); - Assert.AreEqual(3.5, angleGear["Ratio"].Value<double>()); - Assert.AreEqual("AngleGear.vtlm", angleGear["LossMap"].Value<string>()); - } - } - - // [TestClass] - // public class JsonTest - // { - // private const string jsonExpected = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""2015-11-17T11:49:03Z"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - - // private const string jsonExpected2 = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""2015-01-07T11:49:03Z"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - - // [TestMethod] - // public void TestJsonHeaderEquality() - // { - // var h1 = new JsonDataHeader { - // AppVersion = "MyVecto3", - // CreatedBy = "UnitTest", - // Date = new DateTime(1970, 1, 1), - // FileVersion = 3 - // }; - // var h2 = new JsonDataHeader { - // AppVersion = "MyVecto3", - // CreatedBy = "UnitTest", - // Date = new DateTime(1970, 1, 1), - // FileVersion = 3 - // }; - // Assert.AreEqual(h1, h1); - // Assert.AreEqual(h1, h2); - // Assert.AreNotEqual(h1, null); - // Assert.AreNotEqual(h1, "hello world"); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_German() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""17.11.2015 11:49:03"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(jsonExpected, jsonCompare); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_German2() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""7.1.2015 11:49:03"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 1, 7, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(jsonExpected2, jsonCompare); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_English() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""11/17/2015 11:49:03 AM"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(jsonExpected, jsonCompare); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_English2() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""1/7/2015 11:49:03 AM"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 1, 7, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(jsonExpected2, jsonCompare); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_ISO8601() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""2015-11-17T11:49:03Z"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(json, jsonCompare); - // } - - // [TestMethod] - // public void Test_Json_DateFormat_ISO8601_CET() - // { - // var json = @"{ - // ""CreatedBy"": ""Michael Krisper"", - // ""Date"": ""2015-11-17T11:49:03+01:00"", - // ""AppVersion"": ""3.0.1.320"", - // ""FileVersion"": 7 - //}"; - // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); - - // Assert.AreEqual("3.0.1.320", header.AppVersion); - // Assert.AreEqual(7u, header.FileVersion); - // Assert.AreEqual("Michael Krisper", header.CreatedBy); - // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); - - // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); - // Assert.AreEqual(json, jsonCompare); - // } - // } +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.IO; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.FileIO +{ + [TestClass] + public class JsonTest + { + private const string TestJobFile = @"Testdata\Jobs\40t_Long_Haul_Truck.vecto"; + private const string TestVehicleFile = @"Testdata\Components\24t Coach.vveh"; + + [TestMethod] + public void ReadJobTest() + { + var job = JSONInputDataFactory.ReadJsonJob(TestJobFile); + + Assert.IsNotNull(job); + // AssertHelper.Exception<InvalidFileFormatException>(() => ); + } + + [TestMethod] + public void NoEngineFileTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("EngineFile").Remove(); + + AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), + "JobFile: Failed to read Engine file '': Key EngineFile not found"); + } + + [TestMethod] + public void NoGearboxFileTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("GearboxFile").Remove(); + + AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), + "JobFile: Failed to read Gearbox file '': Key GearboxFile not found"); + } + + [TestMethod] + public void NoVehicleFileTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("VehicleFile").Remove(); + + AssertHelper.Exception<VectoException>(() => new JSONInputDataV2(json, TestJobFile), + "JobFile: Failed to read Vehicle file '': Key VehicleFile not found"); + } + + [TestMethod] + public void NoCyclesTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("Cycles").Remove(); + + var tmp = new JSONInputDataV2(json, TestJobFile).Cycles; + Assert.AreEqual(0, tmp.Count); + } + + [TestMethod] + public void NoAuxTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("Aux").Remove(); + + // MK,2016-01-20: Changed for PWheel: aux entry may be missing, and that is ok. + var tmp = new JSONInputDataV2(json, TestJobFile).AuxiliaryInputData().Auxiliaries; + Assert.IsTrue(tmp.Count == 0); + } + + [TestMethod] + public void NoDriverAccCurveTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("VACC").Remove(); + + IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); + var tmp = input.DriverInputData.AccelerationCurve; + Assert.IsNull(tmp); + } + + [TestMethod] + public void UseDeclarationDriverAccCurveTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + json["Body"]["VACC"] = "Truck"; + + IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); + var tmp = input.DriverInputData.AccelerationCurve; + Assert.IsNotNull(tmp); + } + + [TestMethod] + public void NoLookaheadCoastingTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("LAC").Remove(); + + IEngineeringInputDataProvider input = new JSONInputDataV2(json, TestJobFile); + var tmp = input.DriverInputData.Lookahead; + Assert.IsNull(tmp); + } + + [TestMethod] + public void NoOverspeedEcoRollTest() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + ((JObject)json["Body"]).Property("OverSpeedEcoRoll").Remove(); + + AssertHelper.Exception<VectoException>( + () => { var tmp = new JSONInputDataV2(json, TestJobFile).DriverInputData.OverSpeedEcoRoll; }, + "Key OverSpeedEcoRoll not found"); + } + + [TestMethod] + public void ReadGearboxV5() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\Gearbox_v5.vgbx"); + + var ratios = new[] { 3.0, 1.0, 0.8 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.RigidTruck, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + // interpreted as gearbox with first and second gear using TC (due to gear ratios) + Assert.IsFalse(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsTrue(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + } + + [TestMethod] + public void ReadGearboxSerialTC() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerial.vgbx"); + + var ratios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.RigidTruck, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + Assert.IsTrue(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsFalse(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + + var gear = gbxData.Gears[1]; + Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); + } + + [TestMethod] + public void ReadGearboxPowersplitTC() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxPowerSplit.vgbx"); + + var ratios = new[] { 1.35, 1.0, 0.73 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.RigidTruck, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + Assert.IsTrue(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsFalse(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + + Assert.AreEqual(1, gbxData.Gears[1].TorqueConverterRatio); + } + + [TestMethod] + public void ReadGearboxDualTCTruck() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerialDualTC.vgbx"); + + var ratios = new[] { 4.35, 2.4, 1.8, 1.3, 1.0 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.RigidTruck, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + Assert.IsFalse(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsTrue(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + + + var gear = gbxData.Gears[2]; + Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); + } + + [TestMethod] + public void ReadGearboxSingleTCBus() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerialDualTC.vgbx"); + + var ratios = new[] { 4.35, 2.4, 1.8, 1.3, 1.0 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.InterurbanBus, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + Assert.IsTrue(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsFalse(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + + + var gear = gbxData.Gears[1]; + Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); + } + + [TestMethod] + public void ReadGearboxDualTCBus() + { + var inputProvider = JSONInputDataFactory.ReadGearbox(@"TestData\Components\AT_GBX\GearboxSerialDualTCBus.vgbx"); + + var ratios = new[] { 4.58, 2.4, 1.8, 1.3, 1.0 }; + Assert.AreEqual(ratios.Length, inputProvider.Gears.Count); + for (int i = 0; i < ratios.Length; i++) { + Assert.AreEqual(ratios[i], inputProvider.Gears[i].Ratio); + } + var gbxData = new EngineeringDataAdapter().CreateGearboxData(inputProvider, + MockSimulationDataFactory.CreateEngineDataFromFile(@"TestData\Components\AT_GBX\Engine.veng", 0), 2.1, + 0.5.SI<Meter>(), VehicleCategory.InterurbanBus, + true); + Assert.AreEqual(ratios.Length, gbxData.Gears.Count); + + Assert.IsFalse(gbxData.Gears[1].HasLockedGear); + Assert.IsTrue(gbxData.Gears[1].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[2].HasLockedGear); + Assert.IsTrue(gbxData.Gears[2].HasTorqueConverter); + Assert.IsTrue(gbxData.Gears[3].HasLockedGear); + Assert.IsFalse(gbxData.Gears[3].HasTorqueConverter); + + + var gear = gbxData.Gears[2]; + Assert.AreEqual(gear.Ratio, gear.TorqueConverterRatio); + } + + //[TestMethod] + //public void TestReadingElectricTechlist() + //{ + // var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestJobFile))); + // ((JArray)json["Body"]["Aux"][3]["TechList"]).Add("LED lights"); + + // var job = new JSONInputDataV2(json, TestJobFile); + // foreach (var aux in job.Auxiliaries) { + // if (aux.ID == "ES") { + // Assert.AreEqual(1, aux.TechList.Count); + // Assert.AreEqual("LED lights", aux.TechList.First()); + // } + // } + //} + + [TestMethod] + public void JSON_Read_AngleGear() + { + var json = (JObject)JToken.ReadFrom(new JsonTextReader(File.OpenText(TestVehicleFile))); + var angleGear = json["Body"]["Angledrive"]; + + Assert.AreEqual(AngledriveType.SeparateAngledrive, + angleGear["Type"].Value<string>().ParseEnum<AngledriveType>()); + Assert.AreEqual(3.5, angleGear["Ratio"].Value<double>()); + Assert.AreEqual("AngleGear.vtlm", angleGear["LossMap"].Value<string>()); + } + } + + // [TestClass] + // public class JsonTest + // { + // private const string jsonExpected = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""2015-11-17T11:49:03Z"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + + // private const string jsonExpected2 = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""2015-01-07T11:49:03Z"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + + // [TestMethod] + // public void TestJsonHeaderEquality() + // { + // var h1 = new JsonDataHeader { + // AppVersion = "MyVecto3", + // CreatedBy = "UnitTest", + // Date = new DateTime(1970, 1, 1), + // FileVersion = 3 + // }; + // var h2 = new JsonDataHeader { + // AppVersion = "MyVecto3", + // CreatedBy = "UnitTest", + // Date = new DateTime(1970, 1, 1), + // FileVersion = 3 + // }; + // Assert.AreEqual(h1, h1); + // Assert.AreEqual(h1, h2); + // Assert.AreNotEqual(h1, null); + // Assert.AreNotEqual(h1, "hello world"); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_German() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""17.11.2015 11:49:03"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(jsonExpected, jsonCompare); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_German2() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""7.1.2015 11:49:03"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 1, 7, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(jsonExpected2, jsonCompare); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_English() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""11/17/2015 11:49:03 AM"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(jsonExpected, jsonCompare); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_English2() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""1/7/2015 11:49:03 AM"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 1, 7, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(jsonExpected2, jsonCompare); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_ISO8601() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""2015-11-17T11:49:03Z"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(json, jsonCompare); + // } + + // [TestMethod] + // public void Test_Json_DateFormat_ISO8601_CET() + // { + // var json = @"{ + // ""CreatedBy"": ""Michael Krisper"", + // ""Date"": ""2015-11-17T11:49:03+01:00"", + // ""AppVersion"": ""3.0.1.320"", + // ""FileVersion"": 7 + //}"; + // var header = JsonConvert.DeserializeObject<JsonDataHeader>(json); + + // Assert.AreEqual("3.0.1.320", header.AppVersion); + // Assert.AreEqual(7u, header.FileVersion); + // Assert.AreEqual("Michael Krisper", header.CreatedBy); + // Assert.AreEqual(new DateTime(2015, 11, 17, 11, 49, 3, DateTimeKind.Utc), header.Date); + + // var jsonCompare = JsonConvert.SerializeObject(header, Formatting.Indented); + // Assert.AreEqual(json, jsonCompare); + // } + // } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs index 6cd925541c89a17dc27b2294757601f6319de202..d1f2dcec0a15f2d063463da5ea7bb693310932ba 100644 --- a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs @@ -29,207 +29,207 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Integration -{ - public class CoachPowerTrain - { - public const string AccelerationFile = @"TestData\Components\Truck.vacc"; - public const string EngineFile = @"TestData\Components\24t Coach.veng"; - public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; - public const string AxleGearLossMap = @"TestData\Components\Axle.vtlm"; - public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; - public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; - public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; - //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; - - public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, - bool overspeed = false, KilogramSquareMeter gearBoxInertia = null, bool highEnginePower = true) - { - var container = CreatePowerTrain(cycleData, Path.GetFileNameWithoutExtension(modFileName), overspeed, gearBoxInertia, - highEnginePower); - return new DistanceRun(container); - } - - public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, bool overspeed = false, - KilogramSquareMeter gearBoxInertia = null, bool engineHighPower = true) - { - var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(modFileName, FuelType.DieselCI, fileWriter) { WriteModalResults = true }; - var container = new VehicleContainer(ExecutionMode.Engineering, modData) { - RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } - }; - - var gearboxData = CreateGearboxData(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineHighPower ? EngineFileHigh : EngineFile, gearboxData.Gears.Count); - var axleGearData = CreateAxleGearData(); - if (gearBoxInertia != null) { - gearboxData.Inertia = gearBoxInertia; - } - - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - var driverData = CreateDriverData(AccelerationFile, overspeed); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - var engine = new CombustionEngine(container, engineData); - var clutch = new Clutch(container, engineData); - var airDragData = CreateAirdragData(); - - var runData = new VectoRunData() { - VehicleData = vehicleData, - AxleGearData = axleGearData, - GearboxData = gearboxData, - EngineData = engineData, - AirdragData = airDragData - }; - - var tmp = cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, airDragData)) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new DummyRetarder(container)) - .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) - .AddComponent(clutch) - .AddComponent(engine); - - var aux = new EngineAuxiliary(container); - aux.AddConstant("ZERO", 0.SI<Watt>()); - container.ModalData.AddAuxiliary("ZERO"); - - engine.Connect(aux.Port()); - - return container; - } - - private static GearboxData CreateGearboxData() - { - var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; - - return new GearboxData { - Gears = ratios.Select((ratio, i) => - Tuple.Create((uint)i, - new GearData { - //MaxTorque = 2300.SI<NewtonMeter>(), - LossMap = ratio.IsEqual(1) - ? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i)) - : TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)), - Ratio = ratio, - ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) - })) - .ToDictionary(k => k.Item1 + 1, v => v.Item2), - ShiftTime = 2.SI<Second>(), - Inertia = 0.SI<KilogramSquareMeter>(), - TractionInterruption = 1.SI<Second>(), - StartSpeed = 2.SI<MeterPerSecond>(), - StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), - StartTorqueReserve = 0.2, - TorqueReserve = 0.2, - DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, - UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, - UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration - }; - } - - private static AxleGearData CreateAxleGearData() - { - const double ratio = 3.240355; - return new AxleGearData { - AxleGear = new GearData { - Ratio = ratio, - LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") - } - }; - } - - private static VehicleData CreateVehicleData(Kilogram loading) - { - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.4375, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.375, - Inertia = 10.83333.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = true, - TyreTestLoad = 52532.55.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.1875, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - //AerodynamicDragAera = 3.2634.SI<SquareMeter>(), - //CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, - - CurbWeight = 15700.SI<Kilogram>(), - Loading = loading, - DynamicTyreRadius = 0.52.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData() { - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection), - }; - } - - private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = true, - MinSpeed = 50.KMPHtoMeterPerSecond(), - //Deceleration = -0.5.SI<MeterPerSquareSecond>() - LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, - LookAheadDecisionFactor = new LACDecisionFactor() - }, - OverSpeedEcoRoll = overspeed - ? new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Overspeed, - MinSpeed = 50.KMPHtoMeterPerSecond(), - OverSpeed = 5.KMPHtoMeterPerSecond() - } - : new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration +{ + public class CoachPowerTrain + { + public const string AccelerationFile = @"TestData\Components\Truck.vacc"; + public const string EngineFile = @"TestData\Components\24t Coach.veng"; + public const string EngineFileHigh = @"TestData\Components\24t Coach_high.veng"; + public const string AxleGearLossMap = @"TestData\Components\Axle.vtlm"; + public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; + public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; + public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs"; + //public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld"; + + public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, + bool overspeed = false, KilogramSquareMeter gearBoxInertia = null, bool highEnginePower = true) + { + var container = CreatePowerTrain(cycleData, Path.GetFileNameWithoutExtension(modFileName), overspeed, gearBoxInertia, + highEnginePower); + return new DistanceRun(container); + } + + public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, bool overspeed = false, + KilogramSquareMeter gearBoxInertia = null, bool engineHighPower = true) + { + var fileWriter = new FileOutputWriter(modFileName); + var modData = new ModalDataContainer(modFileName, FuelType.DieselCI, fileWriter) { WriteModalResults = true }; + var container = new VehicleContainer(ExecutionMode.Engineering, modData) { + RunData = new VectoRunData { JobName = modFileName, Cycle = cycleData } + }; + + var gearboxData = CreateGearboxData(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(engineHighPower ? EngineFileHigh : EngineFile, gearboxData.Gears.Count); + var axleGearData = CreateAxleGearData(); + if (gearBoxInertia != null) { + gearboxData.Inertia = gearBoxInertia; + } + + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var driverData = CreateDriverData(AccelerationFile, overspeed); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + var engine = new CombustionEngine(container, engineData); + var clutch = new Clutch(container, engineData); + var airDragData = CreateAirdragData(); + + var runData = new VectoRunData() { + VehicleData = vehicleData, + AxleGearData = axleGearData, + GearboxData = gearboxData, + EngineData = engineData, + AirdragData = airDragData + }; + + var tmp = cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, airDragData)) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new DummyRetarder(container)) + .AddComponent(new Gearbox(container, new AMTShiftStrategy(runData, container), runData)) + .AddComponent(clutch) + .AddComponent(engine); + + var aux = new EngineAuxiliary(container); + aux.AddConstant("ZERO", 0.SI<Watt>()); + container.ModalData.AddAuxiliary("ZERO"); + + engine.Connect(aux.Port()); + + return container; + } + + private static GearboxData CreateGearboxData() + { + var ratios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 }; + + return new GearboxData { + Gears = ratios.Select((ratio, i) => + Tuple.Create((uint)i, + new GearData { + //MaxTorque = 2300.SI<NewtonMeter>(), + LossMap = ratio.IsEqual(1) + ? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i)) + : TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)), + Ratio = ratio, + ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile) + })) + .ToDictionary(k => k.Item1 + 1, v => v.Item2), + ShiftTime = 2.SI<Second>(), + Inertia = 0.SI<KilogramSquareMeter>(), + TractionInterruption = 1.SI<Second>(), + StartSpeed = 2.SI<MeterPerSecond>(), + StartAcceleration = 0.6.SI<MeterPerSquareSecond>(), + StartTorqueReserve = 0.2, + TorqueReserve = 0.2, + DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay, + UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay, + UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration + }; + } + + private static AxleGearData CreateAxleGearData() + { + const double ratio = 3.240355; + return new AxleGearData { + AxleGear = new GearData { + Ratio = ratio, + LossMap = TransmissionLossMapReader.ReadFromFile(AxleGearLossMap, ratio, "AxleGear") + } + }; + } + + private static VehicleData CreateVehicleData(Kilogram loading) + { + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.4375, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.375, + Inertia = 10.83333.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = true, + TyreTestLoad = 52532.55.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.1875, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + //AerodynamicDragAera = 3.2634.SI<SquareMeter>(), + //CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection, + + CurbWeight = 15700.SI<Kilogram>(), + Loading = loading, + DynamicTyreRadius = 0.52.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData() { + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + }; + } + + private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = true, + MinSpeed = 50.KMPHtoMeterPerSecond(), + //Deceleration = -0.5.SI<MeterPerSquareSecond>() + LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor, + LookAheadDecisionFactor = new LACDecisionFactor() + }, + OverSpeedEcoRoll = overspeed + ? new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Overspeed, + MinSpeed = 50.KMPHtoMeterPerSecond(), + OverSpeed = 5.KMPHtoMeterPerSecond() + } + : new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs index fff3f7d93b238c83a36577876a5727bad032b0fd..c2d71d2899c22398f022107134bbf745dd1975c5 100644 --- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs @@ -29,284 +29,284 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; -using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; - -namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns -{ - [TestClass] - public class MinimalPowertrain - { - public const string CycleFile = @"TestData\Integration\MinimalPowerTrain\1-Gear-Test-dist.vdri"; - public const string CycleFileStop = @"TestData\Integration\MinimalPowerTrain\1-Gear-StopTest-dist.vdri"; - public const string EngineFile = @"TestData\Integration\MinimalPowerTrain\24t Coach.veng"; - public const string GearboxFile = @"TestData\Integration\MinimalPowerTrain\24t Coach-1Gear.vgbx"; - public const string GbxLossMap = @"TestData\Integration\MinimalPowerTrain\NoLossGbxMap.vtlm"; - public const string AccelerationFile = @"TestData\Components\Coach.vacc"; - public const string AccelerationFile2 = @"TestData\Components\Truck.vacc"; - public const double Tolerance = 0.001; - - [TestMethod] - public void TestWheelsAndEngineInitialize() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); - - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - - var axleGearData = CreateAxleGearData(); - - var driverData = CreateDriverData(AccelerationFile); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); - var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var driver = new Driver(container, driverData, new DefaultDriverStrategy()); - var engine = new CombustionEngine(container, engineData); - driver.AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(engine); - - var gbx = new MockGearbox(container); - - var driverPort = driver.OutPort(); - - gbx.Gear = 1; - - var response = driverPort.Initialize(18.KMPHtoMeterPerSecond(), - VectoMath.InclinationToAngle(2.842372037 / 100)); - - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - // time [s] , dist [m] , v_act [km/h] , v_targ [km/h] , acc [m/s²] , grad [%] , n_eng_avg [1/min] , T_eng_fcmap [Nm] , Tq_clutch [Nm] , Tq_full [Nm] , Tq_drag [Nm] , P_eng_out [kW] , P_eng_full [kW] , P_eng_drag [kW] , P_clutch_out [kW] , Pa Eng [kW] , P_aux [kW] , Gear [-] , Ploss GB [kW] , Ploss Diff [kW] , Ploss Retarder [kW] , Pa GB [kW] , Pa Veh [kW] , P_roll [kW] , P_air [kW] , P_slope [kW] , P_wheel_in [kW] , P_brake_loss [kW] , FC-Map [g/h] , FC-AUXc [g/h] , FC-WHTCc [g/h] - // 1.5 , 5 , 18 , 18 , 0 , 2.842372 , 964.1117 , 323.7562 , 323.7562 , 2208.664 , -158.0261 , 32.68693 , 222.9902 , -15.95456 , 32.68693 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 5.965827 , 0.2423075 , 26.47879 , 32.68693 , 0 , 7574.113 , - , - - - AssertHelper.AreRelativeEqual(964.1117.RPMtoRad().Value(), container.Engine.EngineSpeed.Value()); - Assert.AreEqual(2208.664, engine.PreviousState.StationaryFullLoadTorque.Value(), Tolerance); - Assert.AreEqual(-158.0261, engine.PreviousState.FullDragTorque.Value(), Tolerance); - - Assert.AreEqual(323.6485, engine.PreviousState.EngineTorque.Value(), Tolerance); - } - - [TestMethod, TestCategory("LongRunning")] - public void TestWheelsAndEngine() - { - NLog.LogManager.DisableLogging(); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); - var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); - - var axleGearData = CreateAxleGearData(); - - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - - var driverData = CreateDriverData(AccelerationFile); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(new CombustionEngine(container, engineData)); - //engine.IdleController.RequestPort = clutch.IdleControlPort; - - var gbx = new MockGearbox(container); - - var cyclePort = cycle.OutPort(); - - cyclePort.Initialize(); - - gbx.Gear = 0; - - var absTime = 0.SI<Second>(); - var ds = Constants.SimulationSettings.DriveOffDistance; - var response = cyclePort.Request(absTime, ds); - Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - container.CommitSimulationStep(absTime, response.SimulationInterval); - absTime += response.SimulationInterval; - - gbx.Gear = 1; - var cnt = 0; - while (!(response is ResponseCycleFinished) && container.Distance < 17000) { - response = cyclePort.Request(absTime, ds); - response.Switch(). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseCycleFinished>(r => { }). - Case<ResponseSuccess>(r => { - container.CommitSimulationStep(absTime, r.SimulationInterval); - absTime += r.SimulationInterval; - - ds = container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed) - .Cast<Meter>(); - - if (cnt++ % 100 == 0) { - modData.Finish(VectoRun.Status.Success); - } - }). - Default(r => Assert.Fail("Unexpected Response: {0}", r)); - } - - Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); - - modData.Finish(VectoRun.Status.Success); - - NLog.LogManager.EnableLogging(); - } - - [TestMethod] - public void TestWheelsAndEngineLookahead() - { - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); - var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFileStop, CycleType.DistanceBased, false); - - var axleGearData = CreateAxleGearData(); - - var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); - - var driverData = CreateDriverData(AccelerationFile2); - - var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); - var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelType.DieselCI, fileWriter); - var container = new VehicleContainer(ExecutionMode.Engineering, modData); - - var cycle = new DistanceBasedDrivingCycle(container, cycleData); - cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) - .AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) - .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) - .AddComponent(new Brakes(container)) - .AddComponent(new AxleGear(container, axleGearData)) - .AddComponent(new Clutch(container, engineData)) - .AddComponent(new CombustionEngine(container, engineData)); - //engine.IdleController.RequestPort = clutch.IdleControlPort; - - var gbx = new MockGearbox(container); - - var cyclePort = cycle.OutPort(); - - cyclePort.Initialize(); - - gbx.Gear = 0; - - var absTime = 0.SI<Second>(); - - gbx.Gear = 1; - var ds = Constants.SimulationSettings.DriveOffDistance; - while (container.Distance < 100) { - var response = cyclePort.Request(absTime, ds); - response.Switch(). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseSuccess>(r => { - container.CommitSimulationStep(absTime, r.SimulationInterval); - absTime += r.SimulationInterval; - - ds = container.VehicleSpeed.IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed) - .Cast<Meter>(); - - modData.Finish(VectoRun.Status.Success); - }); - } - - modData.Finish(VectoRun.Status.Success); - } - - private static AxleGearData CreateAxleGearData() - { - return new AxleGearData() { - AxleGear = new GearData { - Ratio = 3.0 * 3.5, - LossMap = TransmissionLossMapReader.ReadFromFile(GbxLossMap, 3.0 * 3.5, "AxleGear") - } - }; - } - - private static VehicleData CreateVehicleData(Kilogram loading) - { - var axles = new List<Axle> { - new Axle { - AxleWeightShare = 0.4375, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.375, - Inertia = 10.83333.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0065, - TwinTyres = true, - TyreTestLoad = 52532.55.SI<Newton>() - }, - new Axle { - AxleWeightShare = 0.1875, - Inertia = 21.66667.SI<KilogramSquareMeter>(), - RollResistanceCoefficient = 0.0055, - TwinTyres = false, - TyreTestLoad = 62538.75.SI<Newton>() - } - }; - return new VehicleData { - AxleConfiguration = AxleConfiguration.AxleConfig_6x2, - - CurbWeight = 15700.SI<Kilogram>(), - Loading = loading, - DynamicTyreRadius = 0.52.SI<Meter>(), - AxleData = axles, - SavedInDeclarationMode = false - }; - } - - private static AirdragData CreateAirdragData() - { - return new AirdragData() { - CrossWindCorrectionCurve = - new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), - CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), - CrossWindCorrectionMode.NoCorrection), - }; - } - - private static DriverData CreateDriverData(string accelerationFile) - { - return new DriverData { - AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData { - Enabled = false, - //Deceleration = -0.5.SI<MeterPerSquareSecond>() - LookAheadDecisionFactor = new LACDecisionFactor() - }, - OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { - Mode = DriverMode.Off - }, - }; - } - } +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; +using Wheels = TUGraz.VectoCore.Models.SimulationComponent.Impl.Wheels; + +namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns +{ + [TestClass] + public class MinimalPowertrain + { + public const string CycleFile = @"TestData\Integration\MinimalPowerTrain\1-Gear-Test-dist.vdri"; + public const string CycleFileStop = @"TestData\Integration\MinimalPowerTrain\1-Gear-StopTest-dist.vdri"; + public const string EngineFile = @"TestData\Integration\MinimalPowerTrain\24t Coach.veng"; + public const string GearboxFile = @"TestData\Integration\MinimalPowerTrain\24t Coach-1Gear.vgbx"; + public const string GbxLossMap = @"TestData\Integration\MinimalPowerTrain\NoLossGbxMap.vtlm"; + public const string AccelerationFile = @"TestData\Components\Coach.vacc"; + public const string AccelerationFile2 = @"TestData\Components\Truck.vacc"; + public const double Tolerance = 0.001; + + [TestMethod] + public void TestWheelsAndEngineInitialize() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); + + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + + var axleGearData = CreateAxleGearData(); + + var driverData = CreateDriverData(AccelerationFile); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); + var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var driver = new Driver(container, driverData, new DefaultDriverStrategy()); + var engine = new CombustionEngine(container, engineData); + driver.AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(engine); + + var gbx = new MockGearbox(container); + + var driverPort = driver.OutPort(); + + gbx.Gear = 1; + + var response = driverPort.Initialize(18.KMPHtoMeterPerSecond(), + VectoMath.InclinationToAngle(2.842372037 / 100)); + + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + + // time [s] , dist [m] , v_act [km/h] , v_targ [km/h] , acc [m/s²] , grad [%] , n_eng_avg [1/min] , T_eng_fcmap [Nm] , Tq_clutch [Nm] , Tq_full [Nm] , Tq_drag [Nm] , P_eng_out [kW] , P_eng_full [kW] , P_eng_drag [kW] , P_clutch_out [kW] , Pa Eng [kW] , P_aux [kW] , Gear [-] , Ploss GB [kW] , Ploss Diff [kW] , Ploss Retarder [kW] , Pa GB [kW] , Pa Veh [kW] , P_roll [kW] , P_air [kW] , P_slope [kW] , P_wheel_in [kW] , P_brake_loss [kW] , FC-Map [g/h] , FC-AUXc [g/h] , FC-WHTCc [g/h] + // 1.5 , 5 , 18 , 18 , 0 , 2.842372 , 964.1117 , 323.7562 , 323.7562 , 2208.664 , -158.0261 , 32.68693 , 222.9902 , -15.95456 , 32.68693 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 5.965827 , 0.2423075 , 26.47879 , 32.68693 , 0 , 7574.113 , - , - + + AssertHelper.AreRelativeEqual(964.1117.RPMtoRad().Value(), container.Engine.EngineSpeed.Value()); + Assert.AreEqual(2208.664, engine.PreviousState.StationaryFullLoadTorque.Value(), Tolerance); + Assert.AreEqual(-158.0261, engine.PreviousState.FullDragTorque.Value(), Tolerance); + + Assert.AreEqual(323.6485, engine.PreviousState.EngineTorque.Value(), Tolerance); + } + + [TestMethod, TestCategory("LongRunning")] + public void TestWheelsAndEngine() + { + NLog.LogManager.DisableLogging(); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); + var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFile, CycleType.DistanceBased, false); + + var axleGearData = CreateAxleGearData(); + + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + + var driverData = CreateDriverData(AccelerationFile); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); + var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(new CombustionEngine(container, engineData)); + //engine.IdleController.RequestPort = clutch.IdleControlPort; + + var gbx = new MockGearbox(container); + + var cyclePort = cycle.OutPort(); + + cyclePort.Initialize(); + + gbx.Gear = 0; + + var absTime = 0.SI<Second>(); + var ds = Constants.SimulationSettings.DriveOffDistance; + var response = cyclePort.Request(absTime, ds); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); + container.CommitSimulationStep(absTime, response.SimulationInterval); + absTime += response.SimulationInterval; + + gbx.Gear = 1; + var cnt = 0; + while (!(response is ResponseCycleFinished) && container.Distance < 17000) { + response = cyclePort.Request(absTime, ds); + response.Switch(). + Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseCycleFinished>(r => { }). + Case<ResponseSuccess>(r => { + container.CommitSimulationStep(absTime, r.SimulationInterval); + absTime += r.SimulationInterval; + + ds = container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed) + .Cast<Meter>(); + + if (cnt++ % 100 == 0) { + modData.Finish(VectoRun.Status.Success); + } + }). + Default(r => Assert.Fail("Unexpected Response: {0}", r)); + } + + Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); + + modData.Finish(VectoRun.Status.Success); + + NLog.LogManager.EnableLogging(); + } + + [TestMethod] + public void TestWheelsAndEngineLookahead() + { + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 1); + var cycleData = DrivingCycleDataReader.ReadFromFile(CycleFileStop, CycleType.DistanceBased, false); + + var axleGearData = CreateAxleGearData(); + + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + + var driverData = CreateDriverData(AccelerationFile2); + + var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); + var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelType.DieselCI, fileWriter); + var container = new VehicleContainer(ExecutionMode.Engineering, modData); + + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy())) + .AddComponent(new Vehicle(container, vehicleData, CreateAirdragData())) + .AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + .AddComponent(new AxleGear(container, axleGearData)) + .AddComponent(new Clutch(container, engineData)) + .AddComponent(new CombustionEngine(container, engineData)); + //engine.IdleController.RequestPort = clutch.IdleControlPort; + + var gbx = new MockGearbox(container); + + var cyclePort = cycle.OutPort(); + + cyclePort.Initialize(); + + gbx.Gear = 0; + + var absTime = 0.SI<Second>(); + + gbx.Gear = 1; + var ds = Constants.SimulationSettings.DriveOffDistance; + while (container.Distance < 100) { + var response = cyclePort.Request(absTime, ds); + response.Switch(). + Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseSuccess>(r => { + container.CommitSimulationStep(absTime, r.SimulationInterval); + absTime += r.SimulationInterval; + + ds = container.VehicleSpeed.IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed) + .Cast<Meter>(); + + modData.Finish(VectoRun.Status.Success); + }); + } + + modData.Finish(VectoRun.Status.Success); + } + + private static AxleGearData CreateAxleGearData() + { + return new AxleGearData() { + AxleGear = new GearData { + Ratio = 3.0 * 3.5, + LossMap = TransmissionLossMapReader.ReadFromFile(GbxLossMap, 3.0 * 3.5, "AxleGear") + } + }; + } + + private static VehicleData CreateVehicleData(Kilogram loading) + { + var axles = new List<Axle> { + new Axle { + AxleWeightShare = 0.4375, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.375, + Inertia = 10.83333.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0065, + TwinTyres = true, + TyreTestLoad = 52532.55.SI<Newton>() + }, + new Axle { + AxleWeightShare = 0.1875, + Inertia = 21.66667.SI<KilogramSquareMeter>(), + RollResistanceCoefficient = 0.0055, + TwinTyres = false, + TyreTestLoad = 62538.75.SI<Newton>() + } + }; + return new VehicleData { + AxleConfiguration = AxleConfiguration.AxleConfig_6x2, + + CurbWeight = 15700.SI<Kilogram>(), + Loading = loading, + DynamicTyreRadius = 0.52.SI<Meter>(), + AxleData = axles, + SavedInDeclarationMode = false + }; + } + + private static AirdragData CreateAirdragData() + { + return new AirdragData() { + CrossWindCorrectionCurve = + new CrosswindCorrectionCdxALookup(3.2634.SI<SquareMeter>(), + CrossWindCorrectionCurveReader.GetNoCorrectionCurve(3.2634.SI<SquareMeter>()), + CrossWindCorrectionMode.NoCorrection), + }; + } + + private static DriverData CreateDriverData(string accelerationFile) + { + return new DriverData { + AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), + LookAheadCoasting = new DriverData.LACData { + Enabled = false, + //Deceleration = -0.5.SI<MeterPerSquareSecond>() + LookAheadDecisionFactor = new LACDecisionFactor() + }, + OverSpeedEcoRoll = new DriverData.OverSpeedEcoRollData { + Mode = DriverMode.Off + }, + }; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index ffb5f6d5dfca18bda17ec7e5907414defe6cc607..239fea37bb56b44af61e40fe1020adf9b4df1a53 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -269,8 +269,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void CrossWindAreaCdxANotSet_Other() { foreach (var correctionMode in EnumHelper.GetValues<CrossWindCorrectionMode>()) { - if (correctionMode == CrossWindCorrectionMode.DeclarationModeCorrection) + if (correctionMode == CrossWindCorrectionMode.DeclarationModeCorrection) { continue; + } var airDrag = new AirdragData { CrossWindCorrectionMode = correctionMode, @@ -295,7 +296,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration TestCase(MissionType.Construction, "Standard technology - LED headlights, all", 950, 0.7),] public void AuxElectricSystemTest(MissionType mission, string technology, double value, double efficiency) { - AssertHelper.AreRelativeEqual(value / efficiency, DeclarationData.ElectricSystem.Lookup(mission, technology)); + AssertHelper.AreRelativeEqual(value / efficiency, DeclarationData.ElectricSystem.Lookup(mission, technology).PowerDemand.Value()); } [TestCase(MissionType.Interurban, "Standard technology"), @@ -317,7 +318,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration TestCase("only one engaged gearwheel above oil level", 0)] public void AuxPTOTransmissionTest(string technology, double value) { - AssertHelper.AreRelativeEqual(value, DeclarationData.PTOTransmission.Lookup(technology)); + AssertHelper.AreRelativeEqual(value, DeclarationData.PTOTransmission.Lookup(technology).PowerDemand.Value()); } [TestCase("Superfluid")] @@ -343,8 +344,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void AuxFanTechTest(string technology, int[] expected) { for (var i = 0; i < _missions.Length; i++) { - var value = DeclarationData.Fan.Lookup(_missions[i], technology); - Assert.AreEqual(expected[i], value.Value(), Tolerance); + var lookup = DeclarationData.Fan.Lookup(_missions[i], technology); + Assert.AreEqual(expected[i], lookup.PowerDemand.Value(), Tolerance); } } @@ -372,7 +373,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration for (var i = 0; i < expected.Length; i++) { if (expected[i] > 0) { AssertHelper.AreRelativeEqual(expected[i], - DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "Default", vehicleClass)); + DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "Default", vehicleClass).PowerDemand.Value()); } else { var i1 = i; AssertHelper.Exception<VectoException>( @@ -395,7 +396,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration { for (var i = 0; i < expected.Length; i++) { AssertHelper.AreRelativeEqual(expected[i], - DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "None", vehicleClass)); + DeclarationData.HeatingVentilationAirConditioning.Lookup(_missions[i], "None", vehicleClass).PowerDemand.Value()); } } @@ -442,8 +443,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void AuxPneumaticSystemTest(string technology, int[] expected) { for (var i = 0; i < _missions.Length; i++) { - var value = DeclarationData.PneumaticSystem.Lookup(_missions[i], technology); - AssertHelper.AreRelativeEqual(expected[i], value); + var lookup = DeclarationData.PneumaticSystem.Lookup(_missions[i], technology); + AssertHelper.AreRelativeEqual(expected[i], lookup.PowerDemand.Value()); } } @@ -502,6 +503,27 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration new[] { axle1, axle2, axle3, axle4 }.TakeWhile(a => a != null).ToArray())); } + [TestCase] + public void Aux_SteeringpumpMultipleLookups() + { + // testcase to illustrate modification of lookup-data for steering pump + const string axle1 = "Electric"; + const MissionType mission = MissionType.LongHaul; + const VehicleClass hdvClass = VehicleClass.Class5; + var first = DeclarationData.SteeringPump.Lookup(mission, hdvClass, + new[] { axle1 }.TakeWhile(a => a != null).ToArray()); + + for (var i = 0; i < 10; i++) { + DeclarationData.SteeringPump.Lookup(mission, hdvClass, + new[] { axle1 }.TakeWhile(a => a != null).ToArray()); + } + + var last = DeclarationData.SteeringPump.Lookup(mission, hdvClass, + new[] { axle1 }.TakeWhile(a => a != null).ToArray()); + + Assert.AreEqual(first.Value(), last.Value(), 1e-3); + } + [TestCase(MissionType.LongHaul, VehicleClass.Class1, "Dual displacement", TestName = "Aux_SteeringPumpLookupFail( No Value )"), TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Super displacement", @@ -526,11 +548,11 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void SegmentWeightOutOfRange4X2(double weight) { AssertHelper.Exception<VectoException>(() => - DeclarationData.Segments.Lookup( - VehicleCategory.RigidTruck, - AxleConfiguration.AxleConfig_4x2, - weight.SI<Kilogram>(), - 0.SI<Kilogram>()), + DeclarationData.Segments.Lookup( + VehicleCategory.RigidTruck, + AxleConfiguration.AxleConfig_4x2, + weight.SI<Kilogram>(), + 0.SI<Kilogram>()), "Gross vehicle mass must be greater than 7.5 tons"); } @@ -543,11 +565,11 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void SegmentWeightOutOfRange4X4(double weight) { AssertHelper.Exception<VectoException>(() => - DeclarationData.Segments.Lookup( - VehicleCategory.RigidTruck, - AxleConfiguration.AxleConfig_4x4, - weight.SI<Kilogram>(), - 0.SI<Kilogram>()), + DeclarationData.Segments.Lookup( + VehicleCategory.RigidTruck, + AxleConfiguration.AxleConfig_4x4, + weight.SI<Kilogram>(), + 0.SI<Kilogram>()), "Gross vehicle mass must be greater than 7.5 tons"); } @@ -775,7 +797,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration trailerCurbWeight: new[] { 3400.0 }, trailerType: new[] { TrailerType.T1 }, lowLoad: 1306.8235, - refLoad: 9813.2353, + refLoad: 9475, trailerGrossVehicleWeight: new[] { 10500.0 }, deltaCdA: 1.3, maxLoad: 11250); @@ -813,6 +835,80 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration maxLoad: 4150); } + + /// <summary> + /// trailer in longhaul, always pc formula + /// </summary> + [TestCase] + public void Segment2TestHeavy() + { + var vehicleData = new { + VehicleCategory = VehicleCategory.RigidTruck, + AxleConfiguration = AxleConfiguration.AxleConfig_4x2, + GrossVehicleMassRating = 11990.SI<Kilogram>(), + CurbWeight = 9500.SI<Kilogram>() + }; + + var segment = DeclarationData.Segments.Lookup(vehicleData.VehicleCategory, vehicleData.AxleConfiguration, + vehicleData.GrossVehicleMassRating, vehicleData.CurbWeight); + + Assert.AreEqual(VehicleClass.Class2, segment.VehicleClass); + + var data = AccelerationCurveReader.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + + Assert.AreEqual(3, segment.Missions.Length); + + AssertMission(segment.Missions[0], + vehicleData: vehicleData, + missionType: MissionType.LongHaul, + cosswindCorrection: "RigidTrailer", + axleWeightDistribution: new[] { 0.225, 0.325 }, + trailerAxleWeightDistribution: new[] { 0.45 }, + trailerAxleCount: new[] { 2 }, + bodyCurbWeight: 1900, + trailerCurbWeight: new[] { 3400.0 }, + trailerType: new[] { TrailerType.T1 }, + lowLoad: 1300, + refLoad: 5915, + trailerGrossVehicleWeight: new[] { 10500.0 }, + deltaCdA: 1.3, + maxLoad: 7690); + + AssertMission(segment.Missions[1], + vehicleData: vehicleData, + missionType: MissionType.RegionalDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 1900, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 590, + refLoad: 590, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 590); + + AssertMission(segment.Missions[2], + vehicleData: vehicleData, + missionType: MissionType.UrbanDelivery, + cosswindCorrection: "RigidSolo", + axleWeightDistribution: new[] { 0.45, 0.55 }, + trailerAxleWeightDistribution: new double[] { }, + trailerAxleCount: new int[] { }, + bodyCurbWeight: 1900, + trailerCurbWeight: new double[] { }, + trailerType: new TrailerType[] { }, + lowLoad: 590, + refLoad: 590, + trailerGrossVehicleWeight: new double[] { }, + deltaCdA: 0, + maxLoad: 590); + } + + /// <summary> /// normal pc formula, no trailer /// </summary> diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index 8d73537a0b633d77c197010cf02d8adf3575159e..d84faffa190492ef352f0d218d513a98b92ca77a 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -83,14 +83,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var mission = MissionType.LongHaul; aux.AddConstant("FAN", - DeclarationData.Fan.Lookup(MissionType.LongHaul, "Hydraulic driven - Constant displacement pump")); - aux.AddConstant("PS", DeclarationData.PneumaticSystem.Lookup(mission, "Medium Supply 1-stage")); + DeclarationData.Fan.Lookup(MissionType.LongHaul, "Hydraulic driven - Constant displacement pump").PowerDemand); + aux.AddConstant("PS", DeclarationData.PneumaticSystem.Lookup(mission, "Medium Supply 1-stage").PowerDemand); aux.AddConstant("STP", DeclarationData.SteeringPump.Lookup(MissionType.LongHaul, hdvClass, new[] { "Variable displacement mech. controlled" })); - aux.AddConstant("ES", DeclarationData.ElectricSystem.Lookup(mission)); + aux.AddConstant("ES", DeclarationData.ElectricSystem.Lookup(mission).PowerDemand); aux.AddConstant("AC", - DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, "Default", hdvClass)); + DeclarationData.HeatingVentilationAirConditioning.Lookup(mission, "Default", hdvClass).PowerDemand); var speed = 1400.RPMtoRad(); var torque = 500.SI<NewtonMeter>(); diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs index 2467116af3c24bf893d8cb08daadc902671ddac9..b2d433c1ccd20dc90c3892fda5ff95220b93c23e 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs @@ -29,177 +29,177 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.IO; -using System.Text; -using System.Data; -using System.Linq; -using System.Collections.Generic; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.Models.Simulation.Impl; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; - -namespace TUGraz.VectoCore.Tests.Models.Simulation -{ - [TestClass] - public class PwheelModeTests - { - /// <summary> - /// Test if the cycle file can be read. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_ReadCycle_Test() - { - var container = new VehicleContainer(ExecutionMode.Engineering); - var inputData = @"<t>,<Pwheel>,<gear>,<n>,<Padd> - 1,89,2,1748,1.300 - 2,120,2,1400,0.4"; - - var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); - var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); - - var gearbox = new CycleGearbox(container, new VectoRunData() { - GearboxData = new GearboxData { - Gears = new Dictionary<uint, GearData> { { 1, new GearData { Ratio = 2.0 } }, { 2, new GearData { Ratio = 3.5 } } } - } - }); - - var cycle = new PWheelCycle(container, drivingCycle, 2.3, null, - gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)); - - Assert.AreEqual(container.CycleData.LeftSample.Time, 1.SI<Second>()); - Assert.AreEqual(container.CycleData.RightSample.Time, 2.SI<Second>()); - - Assert.AreEqual(1748.RPMtoRad() / (2.3 * 3.5), container.CycleData.LeftSample.WheelAngularVelocity); - Assert.AreEqual(1400.RPMtoRad() / (2.3 * 3.5), container.CycleData.RightSample.WheelAngularVelocity); - - Assert.AreEqual(89.SI().Kilo.Watt, container.CycleData.LeftSample.PWheel); - Assert.AreEqual(120.SI().Kilo.Watt, container.CycleData.RightSample.PWheel); - - Assert.AreEqual(2u, container.CycleData.LeftSample.Gear); - Assert.AreEqual(2u, container.CycleData.RightSample.Gear); - - Assert.AreEqual(1300.SI<Watt>(), container.CycleData.LeftSample.AdditionalAuxPowerDemand); - Assert.AreEqual(400.SI<Watt>(), container.CycleData.RightSample.AdditionalAuxPowerDemand); - - Assert.AreEqual(89.SI().Kilo.Watt / (1748.RPMtoRad() / (2.3 * 3.5)), container.CycleData.LeftSample.Torque); - Assert.AreEqual(120.SI().Kilo.Watt / (1400.RPMtoRad() / (2.3 * 3.5)), container.CycleData.RightSample.Torque); - } - - /// <summary> - /// Tests if the powertrain can be created in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_CreatePowertrain_Test() - { - // prepare input data - var inputData = @"<t>,<Pwheel>,<gear>,<n>, <Padd> - 1, 89, 2, 1748, 1.3 - 2, 120, 2, 1400, 0.4"; - - var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); - var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); - - var fuelConsumption = new DataTable(); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Columns.Add(""); - fuelConsumption.Rows.Add("1", "1", "1"); - fuelConsumption.Rows.Add("2", "2", "2"); - fuelConsumption.Rows.Add("3", "3", "3"); - - var fullLoad = new DataTable(); - fullLoad.Columns.Add("Engine speed"); - fullLoad.Columns.Add("max torque"); - fullLoad.Columns.Add("drag torque"); - fullLoad.Columns.Add("PT1"); - fullLoad.Rows.Add("0", "5000", "-5000", "0"); - fullLoad.Rows.Add("3000", "5000", "-5000", "0"); - - var fullLoadCurve = FullLoadCurveReader.Create(fullLoad); - var data = new VectoRunData { - Cycle = drivingCycle, - AxleGearData = new AxleGearData { AxleGear = new GearData { Ratio = 2.3 } }, - EngineData = - new CombustionEngineData { - IdleSpeed = 560.RPMtoRad(), - FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, fullLoadCurve }, { 1, fullLoadCurve } } - }, - GearboxData = new GearboxData { Gears = new Dictionary<uint, GearData> { { 2, new GearData { Ratio = 3.5 } } } }, - Retarder = new RetarderData() - }; - - // call builder (actual test) - var builder = new PowertrainBuilder(new MockModalDataContainer()); - var jobContainer = builder.Build(data); - } - - /// <summary> - /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_Run_Test() - { - var jobFile = @"TestData\Pwheel\Pwheel.vecto"; - var fileWriter = new FileOutputWriter(jobFile); - var sumWriter = new SummaryDataContainer(fileWriter); - var jobContainer = new JobContainer(sumWriter); - - var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); - var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); - - jobContainer.AddRuns(runsFactory); - jobContainer.Execute(); - - jobContainer.WaitFinished(); - - Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); - - ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel.vsum", @"TestData\Pwheel\Pwheel.vsum"); - - ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_Gear2_pt1_rep1_actual.vmod", - @"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod"); - } - - /// <summary> - /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. - /// </summary> - /// <remarks>VECTO-177</remarks> - [TestMethod] - public void Pwheel_ultimate_Run_Test() - { - var jobFile = @"TestData\Pwheel\Pwheel_ultimate.vecto"; - var fileWriter = new FileOutputWriter(jobFile); - var sumWriter = new SummaryDataContainer(fileWriter); - var jobContainer = new JobContainer(sumWriter); - - var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); - var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); - - jobContainer.AddRuns(runsFactory); - jobContainer.Execute(); - - jobContainer.WaitFinished(); - - Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); - - ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel_ultimate.vsum", @"TestData\Pwheel\Pwheel_ultimate.vsum"); - - ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod", - @"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod"); - } - } +using System.IO; +using System.Text; +using System.Data; +using System.Linq; +using System.Collections.Generic; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.Models.Simulation.Impl; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; + +namespace TUGraz.VectoCore.Tests.Models.Simulation +{ + [TestClass] + public class PwheelModeTests + { + /// <summary> + /// Test if the cycle file can be read. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_ReadCycle_Test() + { + var container = new VehicleContainer(ExecutionMode.Engineering); + var inputData = @"<t>,<Pwheel>,<gear>,<n>,<Padd> + 1,89,2,1748,1.300 + 2,120,2,1400,0.4"; + + var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); + var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); + + var gearbox = new CycleGearbox(container, new VectoRunData() { + GearboxData = new GearboxData { + Gears = new Dictionary<uint, GearData> { { 1, new GearData { Ratio = 2.0 } }, { 2, new GearData { Ratio = 3.5 } } } + } + }); + + var cycle = new PWheelCycle(container, drivingCycle, 2.3, null, + gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio)); + + Assert.AreEqual(container.CycleData.LeftSample.Time, 1.SI<Second>()); + Assert.AreEqual(container.CycleData.RightSample.Time, 2.SI<Second>()); + + Assert.AreEqual(1748.RPMtoRad() / (2.3 * 3.5), container.CycleData.LeftSample.WheelAngularVelocity); + Assert.AreEqual(1400.RPMtoRad() / (2.3 * 3.5), container.CycleData.RightSample.WheelAngularVelocity); + + Assert.AreEqual(89.SI().Kilo.Watt, container.CycleData.LeftSample.PWheel); + Assert.AreEqual(120.SI().Kilo.Watt, container.CycleData.RightSample.PWheel); + + Assert.AreEqual(2u, container.CycleData.LeftSample.Gear); + Assert.AreEqual(2u, container.CycleData.RightSample.Gear); + + Assert.AreEqual(1300.SI<Watt>(), container.CycleData.LeftSample.AdditionalAuxPowerDemand); + Assert.AreEqual(400.SI<Watt>(), container.CycleData.RightSample.AdditionalAuxPowerDemand); + + Assert.AreEqual(89.SI().Kilo.Watt / (1748.RPMtoRad() / (2.3 * 3.5)), container.CycleData.LeftSample.Torque); + Assert.AreEqual(120.SI().Kilo.Watt / (1400.RPMtoRad() / (2.3 * 3.5)), container.CycleData.RightSample.Torque); + } + + /// <summary> + /// Tests if the powertrain can be created in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_CreatePowertrain_Test() + { + // prepare input data + var inputData = @"<t>,<Pwheel>,<gear>,<n>, <Padd> + 1, 89, 2, 1748, 1.3 + 2, 120, 2, 1400, 0.4"; + + var cycleFile = new MemoryStream(Encoding.UTF8.GetBytes(inputData)); + var drivingCycle = DrivingCycleDataReader.ReadFromStream(cycleFile, CycleType.PWheel, "", false); + + var fuelConsumption = new DataTable(); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Columns.Add(""); + fuelConsumption.Rows.Add("1", "1", "1"); + fuelConsumption.Rows.Add("2", "2", "2"); + fuelConsumption.Rows.Add("3", "3", "3"); + + var fullLoad = new DataTable(); + fullLoad.Columns.Add("Engine speed"); + fullLoad.Columns.Add("max torque"); + fullLoad.Columns.Add("drag torque"); + fullLoad.Columns.Add("PT1"); + fullLoad.Rows.Add("0", "5000", "-5000", "0"); + fullLoad.Rows.Add("3000", "5000", "-5000", "0"); + + var fullLoadCurve = FullLoadCurveReader.Create(fullLoad); + var data = new VectoRunData { + Cycle = drivingCycle, + AxleGearData = new AxleGearData { AxleGear = new GearData { Ratio = 2.3 } }, + EngineData = + new CombustionEngineData { + IdleSpeed = 560.RPMtoRad(), + FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, fullLoadCurve }, { 1, fullLoadCurve } } + }, + GearboxData = new GearboxData { Gears = new Dictionary<uint, GearData> { { 2, new GearData { Ratio = 3.5 } } } }, + Retarder = new RetarderData() + }; + + // call builder (actual test) + var builder = new PowertrainBuilder(new MockModalDataContainer()); + var jobContainer = builder.Build(data); + } + + /// <summary> + /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_Run_Test() + { + var jobFile = @"TestData\Pwheel\Pwheel.vecto"; + var fileWriter = new FileOutputWriter(jobFile); + var sumWriter = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumWriter); + + var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); + var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); + + jobContainer.AddRuns(runsFactory); + jobContainer.Execute(); + + jobContainer.WaitFinished(); + + Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); + + ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel.vsum", @"TestData\Pwheel\Pwheel.vsum"); + + ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_Gear2_pt1_rep1_actual.vmod", + @"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod"); + } + + /// <summary> + /// Tests if the simulation works and the modfile and sumfile are correct in P_wheel_in mode. + /// </summary> + /// <remarks>VECTO-177</remarks> + [TestMethod] + public void Pwheel_ultimate_Run_Test() + { + var jobFile = @"TestData\Pwheel\Pwheel_ultimate.vecto"; + var fileWriter = new FileOutputWriter(jobFile); + var sumWriter = new SummaryDataContainer(fileWriter); + var jobContainer = new JobContainer(sumWriter); + + var inputData = JSONInputDataFactory.ReadJsonJob(jobFile); + var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter); + + jobContainer.AddRuns(runsFactory); + jobContainer.Execute(); + + jobContainer.WaitFinished(); + + Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); + + ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel_ultimate.vsum", @"TestData\Pwheel\Pwheel_ultimate.vsum"); + + ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod", + @"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod"); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/ATGearboxTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/ATGearboxTest.cs index f0c12bd791d2c05813804a0ec23572c6f94fed24..a93409ff24f34a6922b33b23fa94139e533f9b6a 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/ATGearboxTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/ATGearboxTest.cs @@ -29,140 +29,140 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using NUnit.Framework; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Integration; -using TUGraz.VectoCore.Tests.Utils; - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponent -{ - [TestFixture] - public class ATGearboxTest - { - public const string EngineDataFile = @"TestData\Components\AT_GBX\Engine.veng"; - public const string GearboxDataFile = @"TestData\Components\AT_GBX\GearboxSerial.vgbx"; - - [Test, - TestCase(0, 100, 1), - TestCase(0, 200, 1), - TestCase(5, 100, 1), - TestCase(5, 300, 1), - TestCase(5, 600, 1), - TestCase(15, 100, 3), - TestCase(15, 300, 3), - TestCase(15, 600, 3), - TestCase(40, 100, 6), - TestCase(40, 300, 6), - TestCase(40, 600, 6), - TestCase(70, 100, 6), - TestCase(70, 300, 6), - TestCase(70, 600, 6), - ] - public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear) - { - var gearboxData = MockSimulationDataFactory.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile, false); - var vehicleContainer = new MockVehicleContainer(); //(ExecutionMode.Engineering); - var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineDataFile, gearboxData.Gears.Count); - vehicleContainer.Engine = new CombustionEngine(vehicleContainer, engineData); - var runData = new VectoRunData() { GearboxData = gearboxData }; - var gearbox = new ATGearbox(vehicleContainer, new ATShiftStrategy(gearboxData, vehicleContainer), runData); - - vehicleContainer.VehicleSpeed = vehicleSpeed.KMPHtoMeterPerSecond(); - - var tnPort = new MockTnOutPort(); - gearbox.Connect(tnPort); - - // r_dyn = 0.465m, i_axle = 6.2 - var angularVelocity = vehicleSpeed.KMPHtoMeterPerSecond() / 0.465.SI<Meter>() * 6.2; - var response = gearbox.Initialize(torque.SI<NewtonMeter>(), angularVelocity); - - Assert.IsInstanceOf(typeof(ResponseSuccess), response); - Assert.AreEqual(expectedGear, gearbox.Gear); - Assert.AreEqual(vehicleSpeed.IsEqual(0), gearbox.Disengaged); - } - - [Test, - TestCase(GearboxType.ATSerial, TestName = "Drive TorqueConverter - Serial"), - TestCase(GearboxType.ATPowerSplit, TestName = "Drive TorqueConverter - PowerSplit")] - public void TestATGearboxDriveTorqueConverter(GearboxType gbxType) - { - var cycleData = @" 0, 0, 0, 2 - 20, 8, 0, 0 - 200, 0, 0, 2"; - var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); - var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, - string.Format("AT_Vehicle_Drive-TC-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); - - run.Run(); - Assert.IsTrue(run.FinishedWithoutErrors); - } - - [Test, - TestCase(GearboxType.ATSerial, TestName = "ShiftUp TorqueConverter - Serial"), - TestCase(GearboxType.ATPowerSplit, TestName = "ShiftUp TorqueConverter - PowerSplit")] - public void TestATGearboxShiftUp(GearboxType gbxType) - { - var cycleData = @" 0, 0, 0, 2 - 500, 40, 0, 0"; - var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); - var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, - string.Format("AT_Vehicle_Drive-TC_shiftup-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); - - run.Run(); - Assert.IsTrue(run.FinishedWithoutErrors); - } - - [Test, - TestCase(GearboxType.ATSerial, TestName = "ShiftDown TorqueConverter - Serial"), - TestCase(GearboxType.ATPowerSplit, TestName = "ShiftDown TorqueConverter - PowerSplit")] - public void TestATGearboxShiftDown(GearboxType gbxType) - { - var cycleData = @" 0, 70, 0, 0 - 500, 0, 0, 2"; - var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); - var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, - string.Format("AT_Vehicle_Drive-TC_shiftdown-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); - - run.Run(); - Assert.IsTrue(run.FinishedWithoutErrors); - } - - - [Test, - TestCase("Urban", GearboxType.ATSerial), - TestCase("Suburban", GearboxType.ATSerial), - TestCase("Interurban", GearboxType.ATSerial), - TestCase("HeavyUrban", GearboxType.ATSerial), - TestCase("Urban", GearboxType.ATPowerSplit), - TestCase("Suburban", GearboxType.ATPowerSplit), - TestCase("Interurban", GearboxType.ATPowerSplit), - TestCase("HeavyUrban", GearboxType.ATPowerSplit) - ] - public void TestATGearboxDriveCycle(string cycleName, GearboxType gbxType) - { - Assert.IsTrue(gbxType.AutomaticTransmission()); - var cycle = SimpleDrivingCycles.ReadDeclarationCycle(cycleName); - var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, - string.Format("AT_Vehicle_Drive-TC_{0}-{1}.vmod", cycleName, gbxType == GearboxType.ATSerial ? "ser" : "ps")); - - var sumWriter = - new SummaryDataContainer( - new FileOutputWriter(string.Format("AT_Vehicle_Drive-TC_{0}-{1}", cycleName, - gbxType == GearboxType.ATSerial ? "ser" : "ps"))); - ((VehicleContainer)run.GetContainer()).WriteSumData = (modData) => - sumWriter.Write(run.GetContainer().ModalData, 0, 0, run.GetContainer().RunData); - run.Run(); - sumWriter.Finish(); - Assert.IsTrue(run.FinishedWithoutErrors); - } - } +using NUnit.Framework; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Integration; +using TUGraz.VectoCore.Tests.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponent +{ + [TestFixture] + public class ATGearboxTest + { + public const string EngineDataFile = @"TestData\Components\AT_GBX\Engine.veng"; + public const string GearboxDataFile = @"TestData\Components\AT_GBX\GearboxSerial.vgbx"; + + [Test, + TestCase(0, 100, 1), + TestCase(0, 200, 1), + TestCase(5, 100, 1), + TestCase(5, 300, 1), + TestCase(5, 600, 1), + TestCase(15, 100, 3), + TestCase(15, 300, 3), + TestCase(15, 600, 3), + TestCase(40, 100, 6), + TestCase(40, 300, 6), + TestCase(40, 600, 6), + TestCase(70, 100, 6), + TestCase(70, 300, 6), + TestCase(70, 600, 6), + ] + public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear) + { + var gearboxData = MockSimulationDataFactory.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile, false); + var vehicleContainer = new MockVehicleContainer(); //(ExecutionMode.Engineering); + var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineDataFile, gearboxData.Gears.Count); + vehicleContainer.Engine = new CombustionEngine(vehicleContainer, engineData); + var runData = new VectoRunData() { GearboxData = gearboxData }; + var gearbox = new ATGearbox(vehicleContainer, new ATShiftStrategy(gearboxData, vehicleContainer), runData); + + vehicleContainer.VehicleSpeed = vehicleSpeed.KMPHtoMeterPerSecond(); + + var tnPort = new MockTnOutPort(); + gearbox.Connect(tnPort); + + // r_dyn = 0.465m, i_axle = 6.2 + var angularVelocity = vehicleSpeed.KMPHtoMeterPerSecond() / 0.465.SI<Meter>() * 6.2; + var response = gearbox.Initialize(torque.SI<NewtonMeter>(), angularVelocity); + + Assert.IsInstanceOf(typeof(ResponseSuccess), response); + Assert.AreEqual(expectedGear, gearbox.Gear); + Assert.AreEqual(vehicleSpeed.IsEqual(0), gearbox.Disengaged); + } + + [Test, + TestCase(GearboxType.ATSerial, TestName = "Drive TorqueConverter - Serial"), + TestCase(GearboxType.ATPowerSplit, TestName = "Drive TorqueConverter - PowerSplit")] + public void TestATGearboxDriveTorqueConverter(GearboxType gbxType) + { + var cycleData = @" 0, 0, 0, 2 + 20, 8, 0, 0 + 200, 0, 0, 2"; + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, + string.Format("AT_Vehicle_Drive-TC-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + } + + [Test, + TestCase(GearboxType.ATSerial, TestName = "ShiftUp TorqueConverter - Serial"), + TestCase(GearboxType.ATPowerSplit, TestName = "ShiftUp TorqueConverter - PowerSplit")] + public void TestATGearboxShiftUp(GearboxType gbxType) + { + var cycleData = @" 0, 0, 0, 2 + 500, 40, 0, 0"; + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, + string.Format("AT_Vehicle_Drive-TC_shiftup-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + } + + [Test, + TestCase(GearboxType.ATSerial, TestName = "ShiftDown TorqueConverter - Serial"), + TestCase(GearboxType.ATPowerSplit, TestName = "ShiftDown TorqueConverter - PowerSplit")] + public void TestATGearboxShiftDown(GearboxType gbxType) + { + var cycleData = @" 0, 70, 0, 0 + 500, 0, 0, 2"; + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, + string.Format("AT_Vehicle_Drive-TC_shiftdown-{0}.vmod", gbxType == GearboxType.ATSerial ? "ser" : "ps")); + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + } + + + [Test, + TestCase("Urban", GearboxType.ATSerial), + TestCase("Suburban", GearboxType.ATSerial), + TestCase("Interurban", GearboxType.ATSerial), + TestCase("HeavyUrban", GearboxType.ATSerial), + TestCase("Urban", GearboxType.ATPowerSplit), + TestCase("Suburban", GearboxType.ATPowerSplit), + TestCase("Interurban", GearboxType.ATPowerSplit), + TestCase("HeavyUrban", GearboxType.ATPowerSplit) + ] + public void TestATGearboxDriveCycle(string cycleName, GearboxType gbxType) + { + Assert.IsTrue(gbxType.AutomaticTransmission()); + var cycle = SimpleDrivingCycles.ReadDeclarationCycle(cycleName); + var run = ATPowerTrain.CreateEngineeringRun(cycle, gbxType, + string.Format("AT_Vehicle_Drive-TC_{0}-{1}.vmod", cycleName, gbxType == GearboxType.ATSerial ? "ser" : "ps")); + + var sumWriter = + new SummaryDataContainer( + new FileOutputWriter(string.Format("AT_Vehicle_Drive-TC_{0}-{1}", cycleName, + gbxType == GearboxType.ATSerial ? "ser" : "ps"))); + ((VehicleContainer)run.GetContainer()).WriteSumData = (modData) => + sumWriter.Write(run.GetContainer().ModalData, 0, 0, run.GetContainer().RunData); + run.Run(); + sumWriter.Finish(); + Assert.IsTrue(run.FinishedWithoutErrors); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs index 886e71bdac7041a357de56e0149cfc666e3e1f4e..925f6301b079eb7fc36f739b974a04ec27af2fb6 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs @@ -29,273 +29,273 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using NLog; -using NLog.Config; -using NLog.Targets; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData -{ - [TestClass] - public class FullLoadCurveTest - { - private const string CoachEngineFLD = @"TestData\Components\24t Coach.vfld"; - private const double Tolerance = 0.0001; - - public static List<string> LogList = new List<string>(); - - [TestMethod] - public void TestFullLoadStaticTorque() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - - Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); - } - - [TestMethod] - public void TestFullLoadEngineSpeedRated() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - Assert.AreEqual(181.8444, fldCurve.RatedSpeed.Value(), Tolerance); - } - - [TestMethod] - public void TestFullLoadStaticPower() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - - Assert.AreEqual(69198.814183, fldCurve.FullLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(283162.218372, fldCurve.FullLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(74767.810760, fldCurve.FullLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); - } - - [TestMethod] - public void TestDragLoadStaticTorque() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - - Assert.AreEqual(-149, fldCurve.DragLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-150, fldCurve.DragLoadStationaryTorque(520.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-339, fldCurve.DragLoadStationaryTorque(2200.RPMtoRad()).Value(), Tolerance); - } - - [TestMethod] - public void TestDragLoadStaticPower() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - - Assert.AreEqual(-8737.81636, fldCurve.DragLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-63041.29254, fldCurve.DragLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(-9019.51251, fldCurve.DragLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); - } - - [TestMethod] - public void TestPT1() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - - Assert.AreEqual(0.6, fldCurve.PT1(560.RPMtoRad()).Value.Value(), Tolerance); - Assert.AreEqual(0.25, fldCurve.PT1(2000.RPMtoRad()).Value.Value(), Tolerance); - Assert.AreEqual(0.37, fldCurve.PT1(1700.RPMtoRad()).Value.Value(), Tolerance); - } - - [TestMethod] - public void TestPreferredSpeed() - { - var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); - fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; - AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); - var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.N95hSpeed); - Assert.AreEqual((0.51 * totalArea).Value(), - fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); - AssertHelper.AreRelativeEqual(194.515816596908.SI<PerSecond>(), fldCurve.N95hSpeed); - AssertHelper.AreRelativeEqual(83.81645.SI<PerSecond>(), fldCurve.LoSpeed); - AssertHelper.AreRelativeEqual(219.084329211505.SI<PerSecond>(), fldCurve.HiSpeed); - AssertHelper.AreRelativeEqual(2300.SI<NewtonMeter>(), fldCurve.MaxTorque); - AssertHelper.AreRelativeEqual(-320.SI<NewtonMeter>(), fldCurve.MaxDragTorque); - } - - [TestMethod] - public void TestPreferredSpeed2() - { - var fldData = new[] { - "560,1180,-149,0.6", - "600,1282,-148,0.6", - "800,1791,-149,0.6", - "1000,2300,-160,0.6", - "1200,2400,-179,0.6", - "1400,2300,-203,0.6", - "1600,2079,-235,0.49", - "1800,1857,-264,0.25", - "2000,1352,-301,0.25", - "2100,1100,-320,0.25", - }; - var fldEntries = InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s] ", fldData); - var fldCurve = FullLoadCurveReader.Create(VectoCSVFile.ReadStream(fldEntries)); - fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; - - var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.N95hSpeed); - Assert.AreEqual((0.51 * totalArea).Value(), - fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); - //AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); - } - - [TestMethod] - public void TestN95hSpeedInvalid() - { - var fldData = new[] { - "600,539.8228,-59.02274, 1.0", - "821,673.5694587,-62.77795, 1.0", - "1041,1102.461949,-68.37734, 1.0", - "1262,1112.899122,-76.0485, 1.0", - "1482,1098.632364,-85.00573, 1.0", - "1606,1093.403667,-90.9053, 1.0", - "1800,1058.081866,-100.937, 1.0", - "1995,992.0155535,-112.1166, 1.0", - "2189,926.7779212,-124.9432, 1.0", - "4000,811.7189964,-138.7132, 1.0", - }; - var fldEntries = InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s] ", fldData); - var fldCurve = FullLoadCurveReader.Create(VectoCSVFile.ReadStream(fldEntries)); - fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; - - AssertHelper.Exception<VectoException>(() => { var tmp = fldCurve.N95hSpeed; }); - //var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, ); - //Assert.AreEqual((0.51 * totalArea).Value(), - // fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); - //AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); - } - - /// <summary> - /// [VECTO-78] - /// </summary> - [TestMethod] - public void Test_FileRead_WrongFileFormat_InsufficientColumns() - { - AssertHelper.Exception<VectoException>( - () => FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve insufficient columns.vfld"), - "ERROR while reading FullLoadCurve File: Engine FullLoadCurve Data File must consist of at least 3 columns."); - } - - /// <summary> - /// [VECTO-78] - /// </summary> - [TestMethod] - public void Test_FileRead_HeaderColumnsNotNamedCorrectly() - { - LogList.Clear(); - var target = new MethodCallTarget { - ClassName = typeof(FullLoadCurveTest).AssemblyQualifiedName, - MethodName = "LogMethod_Test_FileRead_HeaderColumnsNotNamedCorrectly" - }; - target.Parameters.Add(new MethodCallParameter("${level}")); - target.Parameters.Add(new MethodCallParameter("${message}")); - SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Warn); - FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve wrong header.vfld"); - Assert.IsTrue( - LogList.Contains( - "FullLoadCurve: Header Line is not valid. Expected: \'engine speed, full load torque, motoring torque\', Got: \'n, Mfull, Mdrag, PT1\'. Falling back to column index."), - string.Join("\n", LogList)); - LogList.Clear(); - } - - public static void LogMethod_Test_FileRead_HeaderColumnsNotNamedCorrectly(string level, string message) - { - LogList.Add(message); - } - - /// <summary> - /// [VECTO-78] - /// </summary> - [TestMethod] - public void Test_FileRead_NoHeader() - { - var curve = FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve no header.vfld"); - var result = curve.FullLoadStationaryTorque(1.SI<PerSecond>()); - Assert.AreNotEqual(result.Value(), 0.0); - } - - /// <summary> - /// [VECTO-78] - /// </summary> - [TestMethod] - public void Test_FileRead_InsufficientEntries() - { - AssertHelper.Exception<VectoException>( - () => FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve insufficient entries.vfld"), - "ERROR while reading FullLoadCurve File: FullLoadCurve must consist of at least two lines with numeric values (below file header)"); - } - - [TestMethod] - public void FullLoad_LossMap_Test() - { - var engineData = new CombustionEngineData { - FullLoadCurves = - new Dictionary<uint, EngineFullLoadCurve>() { - { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, - { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") } - }, - IdleSpeed = 560.RPMtoRad() - }; - - var gearboxData = new GearboxData(); - gearboxData.Gears[1] = new GearData { - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), - Ratio = 1 - }; - - var axleGearData = new AxleGearData() { - AxleGear = new GearData { - Ratio = 1, - LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), - } - }; - - var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; - Assert.IsFalse(runData.IsValid()); - } - - /// <summary> - /// [VECTO-190] - /// </summary> - [TestMethod] - public void TestSortingFullLoadEntries() - { - var fldEntries = new[] { - "600,1282,-148,0.6 ", - "799.9999999,1791,-149,0.6 ", - "560,1180,-149,0.6 ", - "1000,2300,-160,0.6 ", - "1599.999999,2079,-235,0.49 ", - "1200,2300,-179,0.6 ", - "1800,1857,-264,0.25 ", - "1400,2300,-203,0.6 ", - "2000.000001,1352,-301,0.25 ", - "2100,1100,-320,0.25 ", - }; - - var fldCurve = - FullLoadCurveReader.Create( - VectoCSVFile.ReadStream(InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s]", fldEntries))); - - Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); - Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); - } - } +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NLog; +using NLog.Config; +using NLog.Targets; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData +{ + [TestClass] + public class FullLoadCurveTest + { + private const string CoachEngineFLD = @"TestData\Components\24t Coach.vfld"; + private const double Tolerance = 0.0001; + + public static List<string> LogList = new List<string>(); + + [TestMethod] + public void TestFullLoadStaticTorque() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + + Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); + } + + [TestMethod] + public void TestFullLoadEngineSpeedRated() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + Assert.AreEqual(181.8444, fldCurve.RatedSpeed.Value(), Tolerance); + } + + [TestMethod] + public void TestFullLoadStaticPower() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + + Assert.AreEqual(69198.814183, fldCurve.FullLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(283162.218372, fldCurve.FullLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(74767.810760, fldCurve.FullLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); + } + + [TestMethod] + public void TestDragLoadStaticTorque() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + + Assert.AreEqual(-149, fldCurve.DragLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-150, fldCurve.DragLoadStationaryTorque(520.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-339, fldCurve.DragLoadStationaryTorque(2200.RPMtoRad()).Value(), Tolerance); + } + + [TestMethod] + public void TestDragLoadStaticPower() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + + Assert.AreEqual(-8737.81636, fldCurve.DragLoadStationaryPower(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-63041.29254, fldCurve.DragLoadStationaryPower(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(-9019.51251, fldCurve.DragLoadStationaryPower(580.RPMtoRad()).Value(), Tolerance); + } + + [TestMethod] + public void TestPT1() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + + Assert.AreEqual(0.6, fldCurve.PT1(560.RPMtoRad()).Value.Value(), Tolerance); + Assert.AreEqual(0.25, fldCurve.PT1(2000.RPMtoRad()).Value.Value(), Tolerance); + Assert.AreEqual(0.37, fldCurve.PT1(1700.RPMtoRad()).Value.Value(), Tolerance); + } + + [TestMethod] + public void TestPreferredSpeed() + { + var fldCurve = FullLoadCurveReader.ReadFromFile(CoachEngineFLD); + fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; + AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); + var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.N95hSpeed); + Assert.AreEqual((0.51 * totalArea).Value(), + fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); + AssertHelper.AreRelativeEqual(194.515816596908.SI<PerSecond>(), fldCurve.N95hSpeed); + AssertHelper.AreRelativeEqual(83.81645.SI<PerSecond>(), fldCurve.LoSpeed); + AssertHelper.AreRelativeEqual(219.084329211505.SI<PerSecond>(), fldCurve.HiSpeed); + AssertHelper.AreRelativeEqual(2300.SI<NewtonMeter>(), fldCurve.MaxTorque); + AssertHelper.AreRelativeEqual(-320.SI<NewtonMeter>(), fldCurve.MaxDragTorque); + } + + [TestMethod] + public void TestPreferredSpeed2() + { + var fldData = new[] { + "560,1180,-149,0.6", + "600,1282,-148,0.6", + "800,1791,-149,0.6", + "1000,2300,-160,0.6", + "1200,2400,-179,0.6", + "1400,2300,-203,0.6", + "1600,2079,-235,0.49", + "1800,1857,-264,0.25", + "2000,1352,-301,0.25", + "2100,1100,-320,0.25", + }; + var fldEntries = InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s] ", fldData); + var fldCurve = FullLoadCurveReader.Create(VectoCSVFile.ReadStream(fldEntries)); + fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; + + var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.N95hSpeed); + Assert.AreEqual((0.51 * totalArea).Value(), + fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); + //AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); + } + + [TestMethod] + public void TestN95hSpeedInvalid() + { + var fldData = new[] { + "600,539.8228,-59.02274, 1.0", + "821,673.5694587,-62.77795, 1.0", + "1041,1102.461949,-68.37734, 1.0", + "1262,1112.899122,-76.0485, 1.0", + "1482,1098.632364,-85.00573, 1.0", + "1606,1093.403667,-90.9053, 1.0", + "1800,1058.081866,-100.937, 1.0", + "1995,992.0155535,-112.1166, 1.0", + "2189,926.7779212,-124.9432, 1.0", + "4000,811.7189964,-138.7132, 1.0", + }; + var fldEntries = InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s] ", fldData); + var fldCurve = FullLoadCurveReader.Create(VectoCSVFile.ReadStream(fldEntries)); + fldCurve.EngineData = new CombustionEngineData { IdleSpeed = 560.RPMtoRad() }; + + AssertHelper.Exception<VectoException>(() => { var tmp = fldCurve.N95hSpeed; }); + //var totalArea = fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, ); + //Assert.AreEqual((0.51 * totalArea).Value(), + // fldCurve.ComputeArea(fldCurve.EngineData.IdleSpeed, fldCurve.PreferredSpeed).Value(), 1E-3); + //AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed); + } + + /// <summary> + /// [VECTO-78] + /// </summary> + [TestMethod] + public void Test_FileRead_WrongFileFormat_InsufficientColumns() + { + AssertHelper.Exception<VectoException>( + () => FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve insufficient columns.vfld"), + "ERROR while reading FullLoadCurve File: Engine FullLoadCurve Data File must consist of at least 3 columns."); + } + + /// <summary> + /// [VECTO-78] + /// </summary> + [TestMethod] + public void Test_FileRead_HeaderColumnsNotNamedCorrectly() + { + LogList.Clear(); + var target = new MethodCallTarget { + ClassName = typeof(FullLoadCurveTest).AssemblyQualifiedName, + MethodName = "LogMethod_Test_FileRead_HeaderColumnsNotNamedCorrectly" + }; + target.Parameters.Add(new MethodCallParameter("${level}")); + target.Parameters.Add(new MethodCallParameter("${message}")); + SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Warn); + FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve wrong header.vfld"); + Assert.IsTrue( + LogList.Contains( + "FullLoadCurve: Header Line is not valid. Expected: \'engine speed, full load torque, motoring torque\', Got: \'n, Mfull, Mdrag, PT1\'. Falling back to column index."), + string.Join("\n", LogList)); + LogList.Clear(); + } + + public static void LogMethod_Test_FileRead_HeaderColumnsNotNamedCorrectly(string level, string message) + { + LogList.Add(message); + } + + /// <summary> + /// [VECTO-78] + /// </summary> + [TestMethod] + public void Test_FileRead_NoHeader() + { + var curve = FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve no header.vfld"); + var result = curve.FullLoadStationaryTorque(1.SI<PerSecond>()); + Assert.AreNotEqual(result.Value(), 0.0); + } + + /// <summary> + /// [VECTO-78] + /// </summary> + [TestMethod] + public void Test_FileRead_InsufficientEntries() + { + AssertHelper.Exception<VectoException>( + () => FullLoadCurveReader.ReadFromFile(@"TestData\Components\FullLoadCurve insufficient entries.vfld"), + "ERROR while reading FullLoadCurve File: FullLoadCurve must consist of at least two lines with numeric values (below file header)"); + } + + [TestMethod] + public void FullLoad_LossMap_Test() + { + var engineData = new CombustionEngineData { + FullLoadCurves = + new Dictionary<uint, EngineFullLoadCurve>() { + { 0, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") }, + { 1, FullLoadCurveReader.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld") } + }, + IdleSpeed = 560.RPMtoRad() + }; + + var gearboxData = new GearboxData(); + gearboxData.Gears[1] = new GearData { + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + Ratio = 1 + }; + + var axleGearData = new AxleGearData() { + AxleGear = new GearData { + Ratio = 1, + LossMap = TransmissionLossMapReader.ReadFromFile(@"TestData\Components\limited.vtlm", 1, "1"), + } + }; + + var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData }; + Assert.IsFalse(runData.IsValid()); + } + + /// <summary> + /// [VECTO-190] + /// </summary> + [TestMethod] + public void TestSortingFullLoadEntries() + { + var fldEntries = new[] { + "600,1282,-148,0.6 ", + "799.9999999,1791,-149,0.6 ", + "560,1180,-149,0.6 ", + "1000,2300,-160,0.6 ", + "1599.999999,2079,-235,0.49 ", + "1200,2300,-179,0.6 ", + "1800,1857,-264,0.25 ", + "1400,2300,-203,0.6 ", + "2000.000001,1352,-301,0.25 ", + "2100,1100,-320,0.25 ", + }; + + var fldCurve = + FullLoadCurveReader.Create( + VectoCSVFile.ReadStream(InputDataHelper.InputDataAsStream("n [U/min],Mfull [Nm],Mdrag [Nm],<PT1> [s]", fldEntries))); + + Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000.RPMtoRad()).Value(), Tolerance); + Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580.RPMtoRad()).Value(), Tolerance); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/Components/AT_GBX/GearboxSerialDualTCBus.vgbx b/VectoCore/VectoCoreTest/TestData/Components/AT_GBX/GearboxSerialDualTCBus.vgbx new file mode 100644 index 0000000000000000000000000000000000000000..cf00163cc28aa4f96ce9e8e2f8c5e96c2f41a9d7 --- /dev/null +++ b/VectoCore/VectoCoreTest/TestData/Components/AT_GBX/GearboxSerialDualTCBus.vgbx @@ -0,0 +1,68 @@ +{ + "Header": { + "CreatedBy": " ()", + "Date": "03.08.2016 14:22:48", + "AppVersion": "2.2", + "FileVersion": 6 + }, + "Body": { + "SavedInDeclMode": false, + "ModelName": "AT Serial", + "Inertia": 0.0, + "TracInt": 0.0, + "Gears": [ + { + "Ratio": 2.1, + "Efficiency": "0.98" + }, + { + "Ratio": 4.58, + "Efficiency": "0.98", + "ShiftPolygon": "AT-Shift.vgbs", + "FullLoadCurve": "<NOFILE>" + }, + { + "Ratio": 2.4, + "Efficiency": "0.98", + "ShiftPolygon": "AT-Shift.vgbs", + "FullLoadCurve": "<NOFILE>" + }, + { + "Ratio": 1.8, + "Efficiency": "0.98", + "ShiftPolygon": "AT-Shift.vgbs", + "FullLoadCurve": "<NOFILE>" + }, + { + "Ratio": 1.3, + "Efficiency": "0.98", + "ShiftPolygon": "AT-Shift.vgbs", + "FullLoadCurve": "<NOFILE>" + }, + { + "Ratio": 1.0, + "Efficiency": "0.98", + "ShiftPolygon": "AT-Shift.vgbs", + "FullLoadCurve": "<NOFILE>" + } + ], + "TqReserve": 0.0, + "SkipGears": false, + "ShiftTime": 0, + "EaryShiftUp": false, + "StartTqReserve": 0.0, + "StartSpeed": 0.0, + "StartAcc": 0.0, + "GearboxType": "ATSerial", + "TorqueConverter": { + "Enabled": true, + "File": "TorqueConverter.vtcc", + "ShiftPolygon": "AT-Shift.vgbs", + "RefRPM": 1000.0, + "Inertia": 0.0 + }, + "DownshiftAferUpshiftDelay": 0.0, + "UpshiftAfterDownshiftDelay": 0.0, + "UpshiftMinAcceleration": 0.0 + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeed.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeed.vsum index 55c1370d9ef54039aabbf8637047a006c82cf4a3..3f2951b5c6494c2af70f7a35f731c435d2f6f8f5 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeed.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeed.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -11-0,MeasuredSpeed,MeasuredSpeed.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8354,46.6571,15.8669,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,20.1009,,,528.4772,,,27.2225,37.8292,13.6500,0.2247,0.0000,1.9832,1.9832,0.0054,0.0000,0.0000,0.3207,0.0000,0.0000,1.8492,0.4631,0.0000,5.3351,3.1090,0.3597,0.0000,0.3186,-0.3291,23.3256,22.8637,39.4149,14.3957,80.5095,1.1306,1.6261,1126.9852,1962.5826,215.0000,4.3880,0.0000,39.8768,17.6289,6.9284,0.7698,1.0778,5.1578,48.0370,20.4003 +# VECTO 3.1.2.810 - 04.07.2017 09:12 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +11-0,MeasuredSpeed,MeasuredSpeed.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8354,46.6571,15.8669,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,7802.9085,167.2396,20.0047,,,523.4600,,,27.2225,37.8292,13.6500,0.2247,0.0000,1.9832,1.9832,0.0054,0.0000,0.0000,0.3207,0.0000,0.0000,1.8492,0.4631,0.0000,5.3351,3.1090,0.3597,0.0000,0.3186,-0.3291,23.3256,22.8637,39.4149,80.5095,1.1306,1.6261,1126.9852,1962.5826,215.0000,14.3957,4.3880,0.0000,39.8768,17.6289,6.9284,0.7698,1.0778,5.1578,48.0370,20.4003 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedAux.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedAux.vsum index 1507e0519ddf9f361cda12c4a8613ddfd7f27eca..b01407a3dff5d4dc204304bf2c596f96a0976817 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedAux.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedAux.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -12-0,MeasuredSpeedAux,MeasuredSpeedAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8340,46.6530,15.8669,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,20.5606,,,540.5634,,,27.2187,38.7930,13.9978,0.2090,0.0000,1.9832,0.3805,2.3637,0.0054,0.0000,0.0000,0.3207,0.0000,0.0000,1.8490,0.4477,0.0000,5.3340,3.1087,0.3597,0.0000,0.3178,-0.3291,23.4026,22.8637,39.3380,14.3957,80.5095,1.1306,1.6261,1126.6442,1962.5826,215.0000,4.6189,0.0000,39.7998,17.6289,6.9284,0.7698,1.0778,5.1578,48.0370,20.4003 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +29-0,MeasuredSpeedAux,MeasuredSpeedAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8340,46.6530,15.8669,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,7980.6637,171.0644,20.4622,,,535.4315,,,27.2187,38.7930,13.9978,0.2090,0.0000,1.9832,0.3805,2.3637,0.0054,0.0000,0.0000,0.3207,0.0000,0.0000,1.8490,0.4477,0.0000,5.3340,3.1087,0.3597,0.0000,0.3178,-0.3291,23.4026,22.8637,39.3380,80.5095,1.1306,1.6261,1126.6442,1962.5826,215.0000,14.3957,4.6189,0.0000,39.7998,17.6289,6.9284,0.7698,1.0778,5.1578,48.0370,20.4003 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear.vsum index f69b5970911632f5067de92d9409bcc83224950e..6351924524f416361db88aa964d612219929cf82 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -18-0,MeasuredSpeedGear,MeasuredSpeed_Gear_Rural.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8712,46.7563,15.8669,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,20.0479,,,527.0839,,,27.2335,37.7843,13.6338,0.1855,0.0000,1.9832,1.9832,0.0227,0.0000,0.0000,0.3036,0.0000,0.0000,1.8506,0.4425,0.0000,5.3535,3.1156,0.3598,0.0000,0.3070,-0.3441,23.5566,21.4011,40.6467,14.3957,80.5095,1.4057,1.9402,1082.0265,1962.3354,210.0000,3.3872,0.0000,40.1848,14.3957,1.7706,7.2363,1.6166,1.6936,49.9615,23.3256 +# VECTO 3.1.2.810 - 04.07.2017 09:11 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +2-0,MeasuredSpeedGear,MeasuredSpeed_Gear_Rural.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8712,46.7563,15.8669,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,7798.8920,166.7987,19.9520,,,522.0799,,,27.2335,37.7843,13.6338,0.1855,0.0000,1.9832,1.9832,0.0227,0.0000,0.0000,0.3036,0.0000,0.0000,1.8506,0.4425,0.0000,5.3535,3.1156,0.3598,0.0000,0.3070,-0.3441,23.5566,21.4011,40.6467,80.5095,1.4057,1.9402,1082.0265,1962.3354,211.0000,14.3957,3.3872,0.0000,40.1848,14.3957,1.7706,7.2363,1.6166,1.6936,49.9615,23.3256 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-PS.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-PS.vsum index ac48ed31fb069fd9b81bca6c785e32038effa169..4f8177821d8430c3e9e3c984db4a7bae2cd5ec42 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-PS.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-PS.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%] -23-0,MeasuredSpeedGearAT-PS,MeasuredSpeedGear_AT-PS.vdri,Success,N/A,,N.A.,0,17000.0000,4800.0000,21800.0000,N/A,Generic Engine,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2500,0.00590364808199548,0.00590364808199548,0.4700,N/A,AT Serial,ATPowerSplit,1.3500,0.7300,,,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,AT Serial,5.8000,,,,,,,,379.0000,2.8856,27.4096,0.0036,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,44.7911,9.3315,,1177.6120,245.3358,,40.8256,50.3483,5.3006,0.3386,0.0000,0.4738,0.4738,0.0000,0.3048,5.1676,0.1289,0.0000,0.0000,0.0963,2.6367,-0.0001,0.2436,1.0118,0.0002,-0.0004,0.6313,-0.8532,32.7177,24.0106,23.2190,20.0528,60.3000,1.1111,1.6111,954.9245,1538.8058,106.0000,0.0000,0.0000,33.7731,26.3852,20.3166,11.6095,41.6887 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%] +27-0,MeasuredSpeedGearAT-PS,MeasuredSpeedGear_AT-PS.vdri,Success,N/A,,N.A.,0,17000.0000,4800.0000,21800.0000,N/A,Generic Engine,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2500,0.00590364808199548,0.00590364808199548,0.4700,3,0,0,N/A,AT Serial,ATPowerSplit,1.3500,0.7300,,,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,AT Serial,5.8000,,,,,,,,379.0000,2.8856,27.4096,0.0036,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,10214.5287,372.6620,44.5768,9.2868,,1166.4322,243.0067,,40.8256,50.3483,5.3006,0.3386,0.0000,0.4738,0.4738,0.0000,0.3048,5.1676,0.1289,0.0000,0.0000,0.0963,2.6367,-0.0001,0.2436,1.0118,0.0002,-0.0004,0.6313,-0.8532,32.7177,24.0106,23.2190,60.3000,1.1111,1.6111,954.9245,1538.8058,106.0000,20.0528,0.0000,0.0000,33.7731,26.3852,20.3166,11.6095,41.6887 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-Ser.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-Ser.vsum index f38f36b15c4397c524ef348630b49ff44462e0ef..780f0298a000e45b32a666fc52ac563979309673 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-Ser.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAT-Ser.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -24-0,MeasuredSpeedGearAT-Ser,MeasuredSpeedGear_AT-Ser.vdri,Success,N/A,,N.A.,0,17000.0000,4800.0000,21800.0000,N/A,Generic Engine,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2500,0.00590364808199548,0.00590364808199548,0.4700,N/A,AT Serial,ATSerial,3.4000,0.6200,,,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,AT Serial,6.2000,,,,,,,,272.0000,1.0225,13.5328,-0.0054,7376.1702,545.0599,7376.1702,545.0599,7376.1702,545.0599,7376.1702,545.0599,7376.1702,545.0599,65.5120,13.6483,,1722.3894,358.8311,,23.4097,33.1204,2.5024,0.3511,0.0000,0.3400,0.3400,0.0000,0.0420,20.9532,0.1462,0.0000,0.0000,0.0453,0.9515,0.0000,0.0338,0.3586,0.0000,-0.0002,0.8827,-0.7816,22.4265,25.0000,18.7500,33.8235,40.6000,1.6935,1.3056,979.1068,1857.4892,138.0000,1.8382,0.0000,33.4559,33.8235,24.6324,8.0882,14.7059,13.6029,5.1471,0.0000 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +28-0,MeasuredSpeedGearAT-Ser,MeasuredSpeedGear_AT-Ser.vdri,Success,N/A,,N.A.,0,17000.0000,4800.0000,21800.0000,N/A,Generic Engine,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2500,0.00590364808199548,0.00590364808199548,0.4700,3,0,0,N/A,AT Serial,ATSerial,3.4000,0.6200,,,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,AT Serial,6.2000,,,,,,,,272.0000,1.0225,13.5328,-0.0054,7376.1701,545.0599,7376.1701,545.0599,7376.1701,545.0599,7376.1701,545.0599,7376.1701,545.0599,65.1986,13.5830,,1706.0376,355.4245,,23.4097,33.1204,2.5024,0.3511,0.0000,0.3400,0.3400,0.0000,0.0420,20.9532,0.1462,0.0000,0.0000,0.0453,0.9515,0.0000,0.0338,0.3586,0.0000,-0.0002,0.8827,-0.7816,22.4265,25.0000,18.7500,40.6000,1.6935,1.3056,979.1068,1857.4892,140.0000,33.8235,1.8382,0.0000,33.4559,33.8235,24.6324,8.0882,14.7059,13.6029,5.1471,0.0000 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAux.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAux.vsum index 6230cccc6f5c9cdaf985db886d6072f2b25aa2bb..a45adaf5a12dd2152b4c1a4c3a4abb575d74139f 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAux.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearAux.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -20-0,MeasuredSpeedGearAux,MeasuredSpeed_Gear_Rural_Aux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8692,46.7506,15.8669,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,20.4449,,,537.5221,,,27.2199,38.7271,13.9740,0.1710,0.0000,1.9829,0.3775,2.3604,0.0227,0.0000,0.0000,0.3048,0.0000,0.0000,1.8503,0.4150,0.0000,5.3532,3.1153,0.3598,0.0000,0.3034,-0.3378,23.4796,21.4781,40.6467,14.3957,80.5095,1.1306,1.6261,1087.0085,1962.3354,212.0000,3.4642,0.0000,40.1848,14.8576,1.6166,7.5443,1.2317,2.1555,49.2687,23.3256 +# VECTO 3.1.2.810 - 04.07.2017 09:13 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +16-0,MeasuredSpeedGearAux,MeasuredSpeed_Gear_Rural_Aux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8692,46.7506,15.8669,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,7952.3686,170.1019,20.3471,,,532.4190,,,27.2199,38.7271,13.9740,0.1710,0.0000,1.9829,0.3775,2.3604,0.0227,0.0000,0.0000,0.3048,0.0000,0.0000,1.8503,0.4150,0.0000,5.3532,3.1153,0.3598,0.0000,0.3034,-0.3378,23.4796,21.4781,40.6467,80.5095,1.1306,1.6261,1087.0085,1962.3354,212.0000,14.3957,3.4642,0.0000,40.1848,14.8576,1.6166,7.5443,1.2317,2.1555,49.2687,23.3256 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVair.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVair.vsum index 08f2b1168b43ee5aeb9000951d8fef80351e9d10..82ba9b7672577f8c79e10cc49bd0f21fd7925471 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVair.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVair.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -21-0,MeasuredSpeedGearVair,MeasuredSpeed_Gear_Rural_Vair.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8711,46.7558,15.8669,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,16.1990,,,425.8899,,,20.1036,29.8660,10.7767,0.2894,0.0000,1.9832,1.9832,0.0268,0.0000,0.0000,0.2684,0.0000,0.0000,1.8468,0.6441,0.0000,2.2252,3.1156,0.3598,0.0000,0.3035,-0.3378,23.4796,21.4781,40.6467,14.3957,80.5095,1.1306,1.6261,1084.6394,1962.3354,210.0000,1.4627,0.0000,40.1848,14.7036,1.6166,7.3903,1.3857,2.0015,49.5766,23.3256 +# VECTO 3.1.2.810 - 04.07.2017 09:14 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +22-0,MeasuredSpeedGearVair,MeasuredSpeed_Gear_Rural_Vair.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8711,46.7558,15.8669,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,6301.5302,134.7753,16.1214,,,421.8467,,,20.1036,29.8660,10.7767,0.2894,0.0000,1.9832,1.9832,0.0268,0.0000,0.0000,0.2684,0.0000,0.0000,1.8468,0.6441,0.0000,2.2252,3.1156,0.3598,0.0000,0.3035,-0.3378,23.4796,21.4781,40.6467,80.5095,1.1306,1.6261,1084.6394,1962.3354,211.0000,14.3957,1.4627,0.0000,40.1848,14.7036,1.6166,7.3903,1.3857,2.0015,49.5766,23.3256 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVairAux.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVairAux.vsum index 43bbeaaf1be0e4e51821be134e3b3e4195b7ce17..dbdf41526324bce5aaa0974efbab2ef7ab0fb0a7 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVairAux.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGearVairAux.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -22-0,MeasuredSpeedGearVairAux,MeasuredSpeed_Gear_Rural_VairAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8711,46.7559,15.8669,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,16.5995,,,436.4219,,,20.1038,30.7899,11.1100,0.2750,0.0000,1.9824,0.3775,2.3598,0.0268,0.0000,0.0000,0.2692,0.0000,0.0000,1.8468,0.6124,0.0000,2.2253,3.1156,0.3598,0.0000,0.3035,-0.3378,23.4796,21.4781,40.6467,14.3957,80.5095,1.1306,1.6261,1087.1418,1962.3354,212.0000,1.6166,0.0000,40.1848,14.9346,1.5396,7.5443,1.2317,2.1555,49.2687,23.3256 +# VECTO 3.1.2.810 - 04.07.2017 09:11 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +7-0,MeasuredSpeedGearVairAux,MeasuredSpeed_Gear_Rural_VairAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8711,46.7559,15.8669,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,6457.3752,138.1082,16.5201,,,432.2786,,,20.1038,30.7899,11.1100,0.2750,0.0000,1.9824,0.3775,2.3598,0.0268,0.0000,0.0000,0.2692,0.0000,0.0000,1.8468,0.6124,0.0000,2.2253,3.1156,0.3598,0.0000,0.3035,-0.3378,23.4796,21.4781,40.6467,80.5095,1.1306,1.6261,1087.1418,1962.3354,212.0000,14.3957,1.6166,0.0000,40.1848,14.9346,1.5396,7.5443,1.2317,2.1555,49.2687,23.3256 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear_TractionInterruption.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear_TractionInterruption.vsum index 9285413178b1e3bb9145fdb55936a11c395c6242..1365e2eb6ad8cad4495cd12dedfd7365974bcea9 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear_TractionInterruption.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedGear_TractionInterruption.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -19-0,MeasuredSpeedGear_TractionInterruption,MeasuredSpeed_Gear_Rural_TractionInterruption.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8351,46.6562,15.8669,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,20.0931,,,528.2716,,,27.1915,37.6343,13.5797,0.1687,0.0000,1.9832,1.9832,0.0052,0.0000,0.0000,0.2986,0.0000,0.0000,1.8478,0.4698,0.0000,5.3378,3.1090,0.3598,0.0000,0.3200,-0.3323,22.7868,22.1709,40.6467,14.3957,80.5095,1.8083,1.6261,1073.4169,1701.8773,209.0000,4.3880,0.0000,39.5689,17.4750,1.3087,6.2356,1.3857,1.4627,48.9607,23.1717 +# VECTO 3.1.2.810 - 04.07.2017 09:12 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +12-0,MeasuredSpeedGear_TractionInterruption,MeasuredSpeed_Gear_Rural_TractionInterruption.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8351,46.6562,15.8669,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,7799.7310,167.1746,19.9970,,,523.2564,,,27.1915,37.6343,13.5797,0.1687,0.0000,1.9832,1.9832,0.0052,0.0000,0.0000,0.2986,0.0000,0.0000,1.8478,0.4698,0.0000,5.3378,3.1090,0.3598,0.0000,0.3200,-0.3323,22.7868,22.1709,40.6467,80.5095,1.8083,1.6261,1073.4169,1701.8773,210.0000,14.3957,4.3880,0.0000,39.5689,17.4750,1.3087,6.2356,1.3857,1.4627,48.9607,23.1717 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVair.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVair.vsum index 89acc0f94e07f1e86c8eb7259403c0867a51fa39..19ba118e299400980a74b041512dae2437490a97 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVair.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVair.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -13-0,MeasuredSpeedVair,MeasuredSpeedVair.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8461,46.6867,15.8669,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,16.2579,,,427.4391,,,20.1448,29.9358,10.8018,0.3334,0.0000,1.9832,1.9832,0.0059,0.0000,0.0000,0.2828,0.0000,0.0000,1.8455,0.6560,0.0000,2.2245,3.1110,0.3596,0.0000,0.3170,-0.3301,23.0177,22.4018,40.1848,14.3957,80.5095,1.1306,1.6261,1121.6641,1962.5826,214.0000,2.6174,0.0000,39.8768,17.3210,7.0824,0.7698,1.0778,4.3880,48.6528,20.7082 +# VECTO 3.1.2.810 - 04.07.2017 09:14 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +21-0,MeasuredSpeedVair,MeasuredSpeedVair.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8461,46.6867,15.8669,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,6315.1012,135.2655,16.1801,,,423.3811,,,20.1448,29.9358,10.8018,0.3334,0.0000,1.9832,1.9832,0.0059,0.0000,0.0000,0.2828,0.0000,0.0000,1.8455,0.6560,0.0000,2.2245,3.1110,0.3596,0.0000,0.3170,-0.3301,23.0177,22.4018,40.1848,80.5095,1.1306,1.6261,1121.6641,1962.5826,214.0000,14.3957,2.6174,0.0000,39.8768,17.3210,7.0824,0.7698,1.0778,4.3880,48.6528,20.7082 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairAux.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairAux.vsum index 1ad973d87f7ac80733c5e30c8439b59bf4cf9a44..a4498f568c10f863b6c97ecdd45cf27981ddef70 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairAux.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairAux.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -17-0,MeasuredSpeedVairAux,MeasuredSpeedVairAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8454,46.6846,15.8669,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,16.6944,,,438.9161,,,20.1443,30.8711,11.1393,0.3170,0.0000,1.9832,0.3799,2.3631,0.0059,0.0000,0.0000,0.2829,0.0000,0.0000,1.8454,0.6301,0.0000,2.2245,3.1109,0.3596,0.0000,0.3170,-0.3301,23.0177,22.4018,40.1848,14.3957,80.5095,1.1306,1.6261,1121.4187,1962.5826,214.0000,2.7714,0.0000,39.8768,17.3210,7.0824,0.7698,1.0778,4.3880,48.6528,20.7082 +# VECTO 3.1.2.810 - 04.07.2017 09:12 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Auxiliary technology ALT [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_ALT [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +10-0,MeasuredSpeedVairAux,MeasuredSpeedVairAux.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,,1299.0000,16.8454,46.6846,15.8669,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,6484.3707,138.8975,16.6145,,,434.7492,,,20.1443,30.8711,11.1393,0.3170,0.0000,1.9832,0.3799,2.3631,0.0059,0.0000,0.0000,0.2829,0.0000,0.0000,1.8454,0.6301,0.0000,2.2245,3.1109,0.3596,0.0000,0.3170,-0.3301,23.0177,22.4018,40.1848,80.5095,1.1306,1.6261,1121.4187,1962.5826,214.0000,14.3957,2.7714,0.0000,39.8768,17.3210,7.0824,0.7698,1.0778,4.3880,48.6528,20.7082 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairBack.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairBack.vsum index d2800166e6c5b5cb12db5b433c7307149fb42575..72cac5bb4d1a1ee56cedce1b3a5c42e8457d6522 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairBack.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairBack.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -15-0,MeasuredSpeedVairBack,MeasuredSpeedVairBack.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8501,46.6977,15.8669,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,12.5715,,,330.5210,,,13.7605,22.3008,8.0469,0.5134,0.0000,1.9832,1.9832,0.0052,0.0000,0.0000,0.2534,0.0000,0.0000,1.8435,0.8337,0.0000,-0.8568,3.1117,0.3597,0.0000,0.3156,-0.3348,22.9407,21.7860,40.8776,14.3957,80.5095,1.1306,1.6261,1115.4956,1735.6300,211.0000,2.1555,0.0000,40.0308,17.7059,6.5435,0.7698,1.0778,3.6182,49.3457,20.9392 +# VECTO 3.1.2.810 - 04.07.2017 09:11 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +4-0,MeasuredSpeedVairBack,MeasuredSpeedVairBack.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8501,46.6977,15.8669,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,4884.3611,104.5952,12.5114,,,327.3831,,,13.7605,22.3008,8.0469,0.5134,0.0000,1.9832,1.9832,0.0052,0.0000,0.0000,0.2534,0.0000,0.0000,1.8435,0.8337,0.0000,-0.8568,3.1117,0.3597,0.0000,0.3156,-0.3348,22.9407,21.7860,40.8776,80.5095,1.1306,1.6261,1115.4956,1735.6300,211.0000,14.3957,2.1555,0.0000,40.0308,17.7059,6.5435,0.7698,1.0778,3.6182,49.3457,20.9392 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairFront.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairFront.vsum index 79f579b3d188dac89a5f8183f387ed81c1f63924..d8e61608e89b3d9e49dec36bc5f463bdcec356d9 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairFront.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairFront.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -14-0,MeasuredSpeedVairFront,MeasuredSpeedVairFront.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8474,46.6902,15.8669,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,14.1021,,,370.7622,,,16.2819,25.4228,9.1734,0.4011,0.0000,1.9832,1.9832,0.0055,0.0000,0.0000,0.2617,0.0000,0.0000,1.8447,0.6774,0.0000,0.5289,3.1112,0.3596,0.0000,0.3161,-0.3290,23.0177,22.4788,40.1078,14.3957,80.5095,1.1306,1.6261,1116.3935,1735.6300,211.0000,2.6174,0.0000,40.0308,17.2440,7.0054,0.7698,1.0778,3.6182,49.4996,20.7852 +# VECTO 3.1.2.810 - 04.07.2017 09:11 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +3-0,MeasuredSpeedVairFront,MeasuredSpeedVairFront.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8474,46.6902,15.8669,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,5478.1550,117.3298,14.0347,,,367.2423,,,16.2819,25.4228,9.1734,0.4011,0.0000,1.9832,1.9832,0.0055,0.0000,0.0000,0.2617,0.0000,0.0000,1.8447,0.6774,0.0000,0.5289,3.1112,0.3596,0.0000,0.3161,-0.3290,23.0177,22.4788,40.1078,80.5095,1.1306,1.6261,1116.3935,1735.6300,211.0000,14.3957,2.6174,0.0000,40.0308,17.2440,7.0054,0.7698,1.0778,3.6182,49.4996,20.7852 diff --git a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairNoWind.vsum b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairNoWind.vsum index 600f442dd3648d87a7560758a8fa309cec1c3211..765142632c6a35cf939fc1411343eb6b9e12c107 100644 --- a/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairNoWind.vsum +++ b/VectoCore/VectoCoreTest/TestData/MeasuredSpeed/Results/MeasuredSpeedVairNoWind.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -16-0,MeasuredSpeedVairNoWind,MeasuredSpeedVairNoWind.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8481,46.6923,15.8669,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,13.5118,,,355.2414,,,15.2949,24.2055,8.7342,0.4389,0.0000,1.9832,1.9832,0.0054,0.0000,0.0000,0.2587,0.0000,0.0000,1.8442,0.7327,0.0000,0.0000,3.1114,0.3597,0.0000,0.3164,-0.3321,22.9407,22.0939,40.5697,14.3957,80.5095,1.1306,1.6261,1115.8093,1735.6300,211.0000,2.3865,0.0000,40.0308,17.3210,6.9284,0.7698,1.0778,3.6182,49.3457,20.9392 +# VECTO 3.1.2.810 - 04.07.2017 09:14 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +23-0,MeasuredSpeedVairNoWind,MeasuredSpeedVairNoWind.vdri,Success,N/A,,N.A.,0,8862.0000,0.0000,8862.0000,N/A,Demo Engine,Diesel CI,0.0000,600.0000,0.0000,6000.0000,1,1,1,0,1,1,6.1650,0.00764995394918169,0.00764995394918169,0.5200,2,0,0,N/A,Demo,MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,Demo,4.3000,,,,,,,,1299.0000,16.8481,46.6923,15.8669,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,5249.0607,112.4182,13.4471,,,351.8689,,,15.2949,24.2055,8.7342,0.4389,0.0000,1.9832,1.9832,0.0054,0.0000,0.0000,0.2587,0.0000,0.0000,1.8442,0.7327,0.0000,0.0000,3.1114,0.3597,0.0000,0.3164,-0.3321,22.9407,22.0939,40.5697,80.5095,1.1306,1.6261,1115.8093,1735.6300,211.0000,14.3957,2.3865,0.0000,40.0308,17.3210,6.9284,0.7698,1.0778,3.6182,49.3457,20.9392 diff --git a/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel.vsum b/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel.vsum index 14ee0ee472ccfae442a8e186808151f6a74731a3..39fc999c8e5491526b46d4f0261e0496d6fed5bf 100644 --- a/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel.vsum +++ b/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -15-0,Pwheel,Gear2_pt1_rep1_actual.vdri,Success,N/A,,N.A.,0,12000.0000,0.0000,12000.0000,N/A,OM906 175 kW,Diesel CI,0.0000,600.0000,0.0000,6374.0000,1,1,1,0,1,1,4.1500,0.0061139563906202,0.0061139563906202,0.4210,N/A,"G 85-6/6,7-0,73",MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,"G 85-6/6,7-0,73",4.3000,,,,,,,,1.5000,,,,12705.4509,,12705.4509,,12705.4509,,12705.4509,,12705.4509,,,,,,,,59.3466,62.3778,0.0260,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0007,0.0000,0.0000,0.0006,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,66.6667,0.0000,0.0000,0.0000,1165.5495,1748.3243,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,66.6667,0.0000,0.0000,0.0000,0.0000 +# VECTO 3.1.2.810 - 04.07.2017 09:18 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +35-0,Pwheel,Gear2_pt1_rep1_actual.vdri,Success,N/A,,N.A.,0,12000.0000,0.0000,12000.0000,N/A,OM906 175 kW,Diesel CI,0.0000,600.0000,0.0000,6374.0000,1,1,1,0,1,1,4.1500,0.0061139563906202,0.0061139563906202,0.4210,2,0,0,N/A,"G 85-6/6,7-0,73",MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,"G 85-6/6,7-0,73",4.3000,,,,,,,,1.5000,,,,12705.4509,,12705.4509,,12705.4509,,12705.4509,,12705.4509,,,,,,,,59.3466,62.3778,0.0260,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0007,0.0000,0.0000,0.0006,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1165.5495,1748.3243,0.0000,66.6667,0.0000,0.0000,0.0000,0.0000,0.0000,66.6667,0.0000,0.0000,0.0000,0.0000 diff --git a/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel_ultimate.vsum b/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel_ultimate.vsum index 87ce22a4b0c89441d9d5833cd5daa33f2ce1f857..b87357c60a87bafe7f09bb6f8c42cdad04f50d0f 100644 --- a/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel_ultimate.vsum +++ b/VectoCore/VectoCoreTest/TestData/Pwheel/Results/Pwheel_ultimate.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] -16-0,Pwheel_ultimate,RD__1_Pwheel_AuxStd.vdri,Success,N/A,,N.A.,0,12000.0000,0.0000,12000.0000,N/A,OM906 175 kW,Diesel CI,0.0000,600.0000,0.0000,6374.0000,1,1,1,0,1,1,4.1500,0.0061139563906202,0.0061139563906202,0.4210,N/A,"G 85-6/6,7-0,73",MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,"G 85-6/6,7-0,73",4.3000,,,,,,,,1566.4000,,,,10007.5012,,10007.5012,,10007.5012,,10007.5012,,10007.5012,,,,,,,,41.2262,47.3199,20.5894,0.9852,-0.0004,1.5039,1.5039,0.0000,0.0000,0.0000,0.6826,0.0000,0.0000,1.0764,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,100.0000,0.0000,0.0000,0.0000,1394.1646,2421.2271,52.0000,7.1757,0.0000,0.0000,0.2809,0.7150,8.7334,3.4729,10.2145,12.1297,64.4535 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%] +26-0,Pwheel_ultimate,RD__1_Pwheel_AuxStd.vdri,Success,N/A,,N.A.,0,12000.0000,0.0000,12000.0000,N/A,OM906 175 kW,Diesel CI,0.0000,600.0000,0.0000,6374.0000,1,1,1,0,1,1,4.1500,0.0061139563906202,0.0061139563906202,0.4210,2,0,0,N/A,"G 85-6/6,7-0,73",MT,6.6960,0.7280,n.a.,n.a.,n.a.,n.a.,None,n.a.,n.a.,n.a.,N/A,"G 85-6/6,7-0,73",4.3000,,,,,,,,1566.4000,,,,10007.5012,,10007.5012,,10007.5012,,10007.5012,,10007.5012,,,,,,,,41.2262,47.3199,20.5894,0.9852,-0.0004,1.5039,1.5039,0.0000,0.0000,0.0000,0.6826,0.0000,0.0000,1.0764,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1394.1646,2421.2271,52.0000,100.0000,7.1757,0.0000,0.0000,0.2809,0.7150,8.7334,3.4729,10.2145,12.1297,64.4535 diff --git a/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/24t Coach EngineOnly.vsum b/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/24t Coach EngineOnly.vsum index a601208566034a35c0d696026ba0cbe54ab42b3e..51a76a992291a3e26834b61e4b0628f0a8a52dae 100644 --- a/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/24t Coach EngineOnly.vsum +++ b/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/24t Coach EngineOnly.vsum @@ -1,4 +1,5 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_cycle [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%] -4-0,24t Coach EngineOnly,Engine Only1.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,695.0000,,,,8102.2063,,8102.2063,,8102.2063,,8102.2063,,8102.2063,,,,,,,,0.0000,29.7166,5.7370,0.3730,0.0194,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,100.0000,0.0000,0.0000,0.0000,1304.7092,2453.5890,,0.0000,0.0000,0.0000 -4-1,24t Coach EngineOnly,Engine Only2.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1006.0000,,,,8427.7489,,8427.7489,,8427.7489,,8427.7489,,8427.7489,,,,,,,,0.0000,30.5705,8.5428,0.5740,0.0161,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,100.0000,0.0000,0.0000,0.0000,1367.6228,2453.5890,,0.0000,0.0000,0.0000 -4-2,24t Coach EngineOnly,Engine Only3.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,166.0000,,,,6526.0629,,6526.0629,,6526.0629,,6526.0629,,6526.0629,,,,,,,,0.0000,21.5508,0.9937,0.1371,0.0060,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,100.0000,0.0000,0.0000,0.0000,1210.3733,2453.5890,,0.0000,0.0000,0.0000 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_cycle [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%] +30-0,24t Coach EngineOnly,Engine Only1.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,695.0000,,,,8102.2063,,8102.2063,,8102.2063,,8102.2063,,8102.2063,,,,,,,,0.0000,29.7166,5.7370,0.3730,0.0194,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1304.7092,2453.5890,,100.0000,0.0000,0.0000,0.0000 +30-1,24t Coach EngineOnly,Engine Only2.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1006.0000,,,,8427.7489,,8427.7489,,8427.7489,,8427.7489,,8427.7489,,,,,,,,0.0000,30.5705,8.5428,0.5740,0.0161,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1367.6228,2453.5890,,100.0000,0.0000,0.0000,0.0000 +30-2,24t Coach EngineOnly,Engine Only3.vdri,Success,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,166.0000,,,,6526.0629,,6526.0629,,6526.0629,,6526.0629,,6526.0629,,,,,,,,0.0000,21.5508,0.9937,0.1371,0.0060,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1210.3733,2453.5890,,100.0000,0.0000,0.0000,0.0000 diff --git a/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/AuxWriteModFileSumFile.vsum b/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/AuxWriteModFileSumFile.vsum index 9a85ef3a85e29235dbde772effb23c3c37ace0c4..6824e284faf5a3b3cc6936c7d122ac9e6534d5f1 100644 --- a/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/AuxWriteModFileSumFile.vsum +++ b/VectoCore/VectoCoreTest/TestData/Results/EngineOnlyCycles/AuxWriteModFileSumFile.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_FAN [kWh],E_aux_PS [kWh],E_aux_STP [kWh],E_aux_ES [kWh],E_aux_AC [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%] -AuxWriteSumFile,MockJob,MockCycle.vdri,Pending,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11.0000,0.0000,0.0000,0.0000,0.0000,,0.0000,,0.0000,,0.0000,,0.0000,,,,,,,,0.0000,0.0000,0.0000,0.0000,0.0000,0.0037,0.0049,0.0017,0.0052,0.0011,0.0165,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,100.0000,0.0000,0.0000,0.0000,0.0000,0.0000,,100.0000,0.0000,0.0000 +# VECTO 3.1.2.810 - 04.07.2017 10:20 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_FAN [kWh],E_aux_PS [kWh],E_aux_STP [kWh],E_aux_ES [kWh],E_aux_AC [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%] +0-0,MockJob,MockCycle.vdri,Pending,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11.0000,0.0000,0.0000,0.0000,0.0000,,0.0000,,0.0000,,0.0000,,0.0000,,,,,,,,0.0000,0.0000,0.0000,0.0000,0.0000,0.0037,0.0049,0.0017,0.0052,0.0011,0.0165,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,,100.0000,100.0000,0.0000,0.0000 diff --git a/VectoCore/VectoCoreTest/TestData/Results/Integration/job.vsum b/VectoCore/VectoCoreTest/TestData/Results/Integration/job.vsum index 9c5bc61c4efc159d53803a834cdf5d268f19c1b3..a657a4932b2cb33aba83b510f3b6c67d19279c6b 100644 --- a/VectoCore/VectoCoreTest/TestData/Results/Integration/job.vsum +++ b/VectoCore/VectoCoreTest/TestData/Results/Integration/job.vsum @@ -1,2 +1,3 @@ -Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Chassis curb mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],StopTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%],Gear 7 TimeShare [%],Gear 8 TimeShare [%] -17-0,job,1-Gear-Test-dist.vdri,Success,N/A,,N.A.,0,15700.0000,3300.0000,19000.0000,N/A,Generic 24t Coach,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2634,0.00640424928879442,0.00640424928879442,0.5200,N/A,Generic 24t Coach,AMT,6.3800,0.7600,n.a.,n.a.,N/A,N.A.,Secondary Retarder,N/A,N.A.,3.5,N/A,Generic 24t Coach,3.2404,,,,,,,,4117.5211,16.8120,14.6989,-43.9640,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,30.6167,9.2778,,804.9509,243.9245,,9.0652,14.2586,16.3084,2.2015,0.0027,0.0000,0.0000,0.0082,0.0000,0.0000,1.0036,1.2154,4.8399,1.4517,1.9666,0.0835,0.2358,5.5710,-2.2714,0.0013,1.0278,-0.4017,0.2058,0.1818,99.5638,0.0486,20.0000,1.3773,0.6427,715.8760,1661.7867,11.0000,0.0227,0.0000,0.0322,0.2225,0.0000,0.0000,0.0000,0.0000,0.1012,0.2393,47.8636,51.5734 +# VECTO 3.1.2.810 - 04.07.2017 09:16 +Job [-],Input File [-],Cycle [-],Status,Vehicle manufacturer [-],VIN number,Vehicle model [-],HDV CO2 vehicle class [-],Corrected Actual Curb Mass [kg],Loading [kg],Total vehicle mass [kg],Engine manufacturer [-],Engine model [-],Engine fuel type [-],Engine rated power [kW],Engine idling speed [rpm],Engine rated speed [rpm],Engine displacement [ccm],Engine WHTCUrban,Engine WHTCRural,Engine WHTCMotorway,Engine BFColdHot,Engine CFRegPer,Engine actual CF,CdxA [m²],total RRC [-],weighted RRC w/o trailer [-],r_dyn [m],Number axles vehicle driven [-],Number axles vehicle non-driven [-],Number axles trailer [-],Gearbox manufacturer [-],Gearbox model [-],Gearbox type [-],Gear ratio first gear [-],Gear ratio last gear [-],Torque converter manufacturer [-],Torque converter model [-],Retarder manufacturer [-],Retarder model [-],Retarder type [-],Angledrive manufacturer [-],Angledrive model [-],Angledrive ratio [-],Axle manufacturer [-],Axle model [-],Axle gear ratio [-],Auxiliary technology STP [-],Auxiliary technology FAN [-],Auxiliary technology AC [-],Auxiliary technology PS [-],Auxiliary technology ES [-],Auxiliary technology cycle [-],Cargo Volume [m³],time [s],distance [km],speed [km/h],altitudeDelta [m],FC-Map [g/h],FC-Map [g/km],FC-AUXc [g/h],FC-AUXc [g/km],FC-WHTCc [g/h],FC-WHTCc [g/km],FC-AAUX [g/h],FC-AAUX [g/km],FC-Final [g/h],FC-Final [g/km],FC-Final [l/100km],FC-Final [l/100tkm],FC-Final [l/100m³km],CO2 [g/km],CO2 [g/tkm],CO2 [g/m³km],P_wheel_in_pos [kW],P_fcmap_pos [kW],E_fcmap_pos [kWh],E_fcmap_neg [kWh],E_powertrain_inertia [kWh],E_aux_CYCLE [kWh],E_aux_sum [kWh],E_clutch_loss [kWh],E_tc_loss [kWh],E_shift_loss [kWh],E_gbx_loss [kWh],E_ret_loss [kWh],E_angle_loss [kWh],E_axl_loss [kWh],E_brake [kWh],E_vehi_inertia [kWh],E_air [kWh],E_roll [kWh],E_grad [kWh],a [m/s^2],a_pos [m/s^2],a_neg [m/s^2],AccelerationTimeShare [%],DecelerationTimeShare [%],CruiseTimeShare [%],max. speed [km/h,max. acc [m/s²],max. dec [m/s²],n_eng_avg [rpm],n_eng_max [rpm],gear shifts [-],StopTimeShare [%],Engine max. Load time share [%],CoastingTimeShare [%],BrakingTImeShare [%],Gear 0 TimeShare [%],Gear 1 TimeShare [%],Gear 2 TimeShare [%],Gear 3 TimeShare [%],Gear 4 TimeShare [%],Gear 5 TimeShare [%],Gear 6 TimeShare [%],Gear 7 TimeShare [%],Gear 8 TimeShare [%] +32-0,job,1-Gear-Test-dist.vdri,Success,N/A,,N.A.,0,15700.0000,3300.0000,19000.0000,N/A,Generic 24t Coach,Diesel CI,0.0000,560.0000,0.0000,12730.0000,1,1,1,0,1,1,3.2634,0.00640424928879442,0.00640424928879442,0.5200,3,0,0,N/A,Generic 24t Coach,AMT,6.3800,0.7600,n.a.,n.a.,N/A,N.A.,Secondary Retarder,N/A,N.A.,3.5,N/A,Generic 24t Coach,3.2404,,,,,,,,4117.5211,16.8120,14.6989,-43.9640,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,3744.2802,254.7313,30.4702,9.2334,,797.3089,241.6088,,9.0652,14.2586,16.3084,2.2015,0.0027,0.0000,0.0000,0.0082,0.0000,0.0000,1.0036,1.2154,4.8399,1.4517,1.9666,0.0835,0.2358,5.5710,-2.2714,0.0013,1.0278,-0.4017,0.2058,0.1818,99.5638,20.0000,1.3773,0.6427,715.8760,1661.7867,11.0000,0.0486,0.0227,0.0000,0.0322,0.2225,0.0000,0.0000,0.0000,0.0000,0.1012,0.2393,47.8636,51.5734 diff --git a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs index 0531a6625ca38aa9f5da975d5bcec5b9b2a2f68e..675a82b958dfce5b28dde0ecebee4a215dafdce5 100644 --- a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs +++ b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs @@ -29,85 +29,88 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; -using TUGraz.VectoCore.Models.SimulationComponent.Data; - -namespace TUGraz.VectoCore.Tests.Utils -{ - public class MockSimulationDataFactory - { - /// <summary> - /// Create gearboxdata instance directly from a file - /// </summary> - /// <param name="gearBoxFile"></param> - /// <param name="engineFile"></param> - /// <param name="declarationMode"></param> - /// <returns>GearboxData instance</returns> - public static GearboxData CreateGearboxDataFromFile(string gearBoxFile, string engineFile, bool declarationMode = true) - { - var gearboxInput = JSONInputDataFactory.ReadGearbox(gearBoxFile); - var engineInput = JSONInputDataFactory.ReadEngine(engineFile); - if (declarationMode) { - var dao = new DeclarationDataAdapter(); - var engineData = dao.CreateEngineData(engineInput, null, gearboxInput, new List<ITorqueLimitInputData>()); - return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>(), - false); - } else { - var dao = new EngineeringDataAdapter(); - var engineData = dao.CreateEngineData(engineInput, gearboxInput, new List<ITorqueLimitInputData>()); - return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>(), - true); - } - } - - public static AxleGearData CreateAxleGearDataFromFile(string axleGearFile) - { - var dao = new DeclarationDataAdapter(); - var axleGearInput = JSONInputDataFactory.ReadGearbox(axleGearFile); - return dao.CreateAxleGearData((IAxleGearInputData)axleGearInput, false); - } - - public static CombustionEngineData CreateEngineDataFromFile(string engineFile, int numGears) - { - var dao = new EngineeringDataAdapter(); - var engineInput = JSONInputDataFactory.ReadEngine(engineFile); - var engineData = dao.CreateEngineData(engineInput, null, new List<ITorqueLimitInputData>()); - for (uint i = 1; i <= numGears; i++) { - engineData.FullLoadCurves[i] = engineData.FullLoadCurves[0]; - } - return engineData; - } - - public static VehicleData CreateVehicleDataFromFile(string vehicleDataFile) - { - var dao = new EngineeringDataAdapter(); - var vehicleInput = JSONInputDataFactory.ReadJsonVehicle(vehicleDataFile); - var airdragData = vehicleInput as IAirdragEngineeringInputData; - return dao.CreateVehicleData(vehicleInput); - } - - public static AirdragData CreateAirdragDataFromFile(string vehicleDataFile) - { - var dao = new EngineeringDataAdapter(); - var vehicleInput = JSONInputDataFactory.ReadJsonVehicle(vehicleDataFile); - var airdragData = vehicleInput as IAirdragEngineeringInputData; - return dao.CreateAirdragData(airdragData, vehicleInput); - } - - public static DriverData CreateDriverDataFromFile(string driverDataFile) - { - var jobInput = JSONInputDataFactory.ReadJsonJob(driverDataFile); - var engineeringJob = jobInput as IEngineeringInputDataProvider; - if (engineeringJob == null) { - throw new VectoException("Failed to cas to Engineering InputDataProvider"); - } - var dao = new EngineeringDataAdapter(); - return dao.CreateDriverData(engineeringJob.DriverInputData); - } - } +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.SimulationComponent.Data; + +namespace TUGraz.VectoCore.Tests.Utils +{ + public class MockSimulationDataFactory + { + /// <summary> + /// Create gearboxdata instance directly from a file + /// </summary> + /// <param name="gearBoxFile"></param> + /// <param name="engineFile"></param> + /// <param name="declarationMode"></param> + /// <returns>GearboxData instance</returns> + public static GearboxData CreateGearboxDataFromFile(string gearBoxFile, string engineFile, bool declarationMode = true) + { + var gearboxInput = JSONInputDataFactory.ReadGearbox(gearBoxFile); + var engineInput = JSONInputDataFactory.ReadEngine(engineFile); + if (declarationMode) { + var dao = new DeclarationDataAdapter(); + var engineData = dao.CreateEngineData(engineInput, null, gearboxInput, new List<ITorqueLimitInputData>()); + return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>(), + VehicleCategory.RigidTruck, + false); + } else { + var dao = new EngineeringDataAdapter(); + var engineData = dao.CreateEngineData(engineInput, gearboxInput, new List<ITorqueLimitInputData>()); + return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>(), + VehicleCategory.RigidTruck, + true); + } + } + + public static AxleGearData CreateAxleGearDataFromFile(string axleGearFile) + { + var dao = new DeclarationDataAdapter(); + var axleGearInput = JSONInputDataFactory.ReadGearbox(axleGearFile); + return dao.CreateAxleGearData((IAxleGearInputData)axleGearInput, false); + } + + public static CombustionEngineData CreateEngineDataFromFile(string engineFile, int numGears) + { + var dao = new EngineeringDataAdapter(); + var engineInput = JSONInputDataFactory.ReadEngine(engineFile); + var engineData = dao.CreateEngineData(engineInput, null, new List<ITorqueLimitInputData>()); + for (uint i = 1; i <= numGears; i++) { + engineData.FullLoadCurves[i] = engineData.FullLoadCurves[0]; + } + return engineData; + } + + public static VehicleData CreateVehicleDataFromFile(string vehicleDataFile) + { + var dao = new EngineeringDataAdapter(); + var vehicleInput = JSONInputDataFactory.ReadJsonVehicle(vehicleDataFile); + var airdragData = vehicleInput as IAirdragEngineeringInputData; + return dao.CreateVehicleData(vehicleInput); + } + + public static AirdragData CreateAirdragDataFromFile(string vehicleDataFile) + { + var dao = new EngineeringDataAdapter(); + var vehicleInput = JSONInputDataFactory.ReadJsonVehicle(vehicleDataFile); + var airdragData = vehicleInput as IAirdragEngineeringInputData; + return dao.CreateAirdragData(airdragData, vehicleInput); + } + + public static DriverData CreateDriverDataFromFile(string driverDataFile) + { + var jobInput = JSONInputDataFactory.ReadJsonJob(driverDataFile); + var engineeringJob = jobInput as IEngineeringInputDataProvider; + if (engineeringJob == null) { + throw new VectoException("Failed to cas to Engineering InputDataProvider"); + } + var dao = new EngineeringDataAdapter(); + return dao.CreateDriverData(engineeringJob.DriverInputData); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj index 11a4c5a1abdaf69bdc8a960b7bf3c5e063e42dab..9d5741aa3cfee88d1b0fa57d535c768f5c0d8c17 100644 --- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj @@ -36,10 +36,6 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="itextsharp, Version=5.5.7.0, Culture=neutral, PublicKeyToken=8354ae6d2174ddca, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\packages\iTextSharp.5.5.9\lib\itextsharp.dll</HintPath> - </Reference> <Reference Include="Microsoft.CSharp" /> <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> @@ -261,6 +257,9 @@ <None Include="TestData\Components\AT_GBX\GearboxSerial.vgbx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <None Include="TestData\Components\AT_GBX\GearboxSerialDualTCBus.vgbx"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> <None Include="TestData\Components\AT_GBX\GearboxSerialDualTC.vgbx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> diff --git a/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs b/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs index 25f0dc1d1985a3d49bc1c3f4a22d3cabc1b9eca9..ddd426858d7126ca1e641666b4e51043b656dc06 100644 --- a/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs +++ b/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs @@ -29,778 +29,778 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Windows.Forms; -using System.Xml; -using System.Xml.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; -using TUGraz.VectoCore.InputData.Reader; -using TUGraz.VectoCore.InputData.Reader.ComponentData; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using TUGraz.VectoCore.Tests.Utils; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Tests.XML -{ - [TestClass] - public class XMLDeclarationInputTest - { - const string SampleVehicleDecl = "TestData/XML/XMLReaderDeclaration/vecto_vehicle-sample.xml"; - const string SampleVehicleFullDecl = "TestData/XML/XMLReaderDeclaration/vecto_vehicle-sample_FULL.xml"; - - [TestMethod] - public void TestXMLInputEng() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - - var engineDataProvider = inputDataProvider.EngineInputData; - - Assert.IsTrue(engineDataProvider.SavedInDeclarationMode); - - Assert.AreEqual("Generic 40t Long Haul Truck Engine", engineDataProvider.Model); - Assert.AreEqual(0.012730, engineDataProvider.Displacement.Value()); - Assert.AreEqual(1.0097, engineDataProvider.WHTCUrban); - //AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.Inertia; }); - - var fcMapTable = engineDataProvider.FuelConsumptionMap; - Assert.AreEqual(112, fcMapTable.Rows.Count); - Assert.AreEqual("engine speed", fcMapTable.Columns[0].Caption); - Assert.AreEqual("torque", fcMapTable.Columns[1].Caption); - Assert.AreEqual("fuel consumption", fcMapTable.Columns[2].Caption); - - Assert.AreEqual("560.00", fcMapTable.Rows[0][0]); - var fcMap = FuelConsumptionMapReader.Create(fcMapTable); - Assert.AreEqual(1256.SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Value(), - fcMap.GetFuelConsumption(0.SI<NewtonMeter>(), 560.RPMtoRad()).Value.Value()); - - var fldTable = engineDataProvider.FullLoadCurve; - Assert.AreEqual(10, fldTable.Rows.Count); - Assert.AreEqual("engine speed", fldTable.Columns[0].Caption); - Assert.AreEqual("full load torque", fldTable.Columns[1].Caption); - Assert.AreEqual("motoring torque", fldTable.Columns[2].Caption); - var fldMap = FullLoadCurveReader.Create(fldTable, true); - } - - [TestMethod] - public void TestXMLInputGbx() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var gearboxDataProvider = inputDataProvider.GearboxInputData; - - Assert.AreEqual("Generic 40t Long Haul Truck Gearbox", gearboxDataProvider.Model); - Assert.AreEqual(GearboxType.AMT, gearboxDataProvider.Type); - var gears = gearboxDataProvider.Gears; - Assert.AreEqual(12, gears.Count); - - Assert.AreEqual(1, gears.First().Gear); - Assert.AreEqual(14.93, gears.First().Ratio); - Assert.AreEqual("0.00", gears.First().LossMap.Rows[0][0]); - Assert.AreEqual("-350.00", gears.First().LossMap.Rows[0][1]); - Assert.AreEqual("12.06", gears.First().LossMap.Rows[0][2]); - - var lossMap = TransmissionLossMapReader.Create(gears.First().LossMap, gears.First().Ratio, - gears.First().Gear.ToString()); - - Assert.AreEqual(5000, gears.First().MaxTorque.Value()); - } - - [TestMethod] - public void TestXMLInputAxlG() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var axlegearDataProvider = inputDataProvider.AxleGearInputData; - - Assert.AreEqual("Generic 40t Long Haul Truck AxleGear", axlegearDataProvider.Model); - - var lossMapData = axlegearDataProvider.LossMap; - Assert.AreEqual(2.59, axlegearDataProvider.Ratio); - Assert.AreEqual("0.00", lossMapData.Rows[0][0]); - Assert.AreEqual("-5000.00", lossMapData.Rows[0][1]); - Assert.AreEqual("115.00", lossMapData.Rows[0][2]); - - var lossMap = TransmissionLossMapReader.Create(lossMapData, axlegearDataProvider.Ratio, "AxleGear"); - Assert.IsNotNull(lossMap); - - AssertHelper.Exception<VectoException>(() => { var tmp = axlegearDataProvider.Efficiency; }); - } - - [TestMethod] - public void TestXMLInputRetarder() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var retarderDataProvider = inputDataProvider.RetarderInputData; - - Assert.AreEqual("Generic Retarder", retarderDataProvider.Model); - - var lossMapData = retarderDataProvider.LossMap; - - Assert.AreEqual(RetarderType.TransmissionOutputRetarder, retarderDataProvider.Type); - - Assert.AreEqual("0.00", lossMapData.Rows[0][0]); - Assert.AreEqual("10.00", lossMapData.Rows[0][1]); - - var lossMap = RetarderLossMapReader.Create(lossMapData); - Assert.IsNotNull(lossMap); - } - - [TestMethod] - public void TestXMLInputAxleWheels() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var vehicleDataProvider = inputDataProvider.VehicleInputData; - - var axles = vehicleDataProvider.Axles; - - Assert.AreEqual("315/70 R22.5", axles[0].Wheels); - Assert.AreEqual(0.0055, axles[0].RollResistanceCoefficient); - Assert.AreEqual(31300, axles[0].TyreTestLoad.Value()); - - Assert.AreEqual("315/70 R22.5", axles[1].Wheels); - Assert.AreEqual(0.0063, axles[1].RollResistanceCoefficient); - Assert.AreEqual(31300, axles[1].TyreTestLoad.Value()); - } - - [TestMethod] - public void TestXMLInputAxleWheelsDuplicates() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var firstAxle = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_Components, - XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, - XMLNames.AxleWheels_Axles, - helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) - ), manager); - firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); - firstAxle.SetTypedValue(2); - - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - var vehicleDataProvider = inputDataProvider.VehicleInputData; - - AssertHelper.Exception<VectoException>(() => { var axles = vehicleDataProvider.Axles; }); - } - - [TestMethod] - public void TestXMLInputAxleWheelsAxleNumTooLow() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var firstAxle = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_Components, - XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, - XMLNames.AxleWheels_Axles, - helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) - ), manager); - firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); - firstAxle.SetTypedValue(0); - - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - AssertHelper.Exception<VectoException>( - () => { var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); }); - } - - [TestMethod] - public void TestXMLInputAxleWheelsAxleNumTooHigh() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var firstAxle = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_Components, - XMLNames.Component_AxleWheels, - XMLNames.ComponentDataWrapper, - XMLNames.AxleWheels_Axles, - helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) - ), manager); - firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); - firstAxle.SetTypedValue(3); - - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - var vehicleDataProvider = inputDataProvider.VehicleInputData; - - AssertHelper.Exception<VectoException>(() => { var axles = vehicleDataProvider.Axles; }); - } - - [TestMethod] - public void TestXMLInputAuxiliaries() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var auxDataProvider = inputDataProvider.AuxiliaryInputData(); - - var aux = auxDataProvider.Auxiliaries; - var aux1 = aux[0]; - - Assert.AreEqual(AuxiliaryType.Fan, aux1.Type); - Assert.AreEqual("Hydraulic driven - Constant displacement pump", aux1.Technology.First()); - - var aux3 = aux[2]; - Assert.AreEqual(AuxiliaryType.ElectricSystem, aux3.Type); - Assert.AreEqual("Standard technology - LED headlights, all", aux3.Technology.First()); - } - - [TestMethod] - public void TestXMLInputADAS() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - - var adas = inputDataProvider.DriverInputData; - - Assert.AreEqual(DriverMode.Overspeed, adas.OverSpeedEcoRoll.Mode); - } - - [TestMethod] - public void TestVehicleInput() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - - var vehicleDataProvider = inputDataProvider.VehicleInputData; - - Assert.AreEqual(VehicleCategory.Tractor, vehicleDataProvider.VehicleCategory); - Assert.AreEqual(AxleConfiguration.AxleConfig_4x2, vehicleDataProvider.AxleConfiguration); - - Assert.AreEqual(7100.0, vehicleDataProvider.CurbMassChassis.Value()); - Assert.AreEqual(40000.0, vehicleDataProvider.GrossVehicleMassRating.Value()); - Assert.AreEqual(6.34, inputDataProvider.AirdragInputData.AirDragArea.Value()); - - Assert.AreEqual(1.0, inputDataProvider.RetarderInputData.Ratio); - } - - [TestMethod] - public void TestXMLPowertrainGeneration() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var fileWriter = new FileOutputWriter("foo"); - var sumWriter = new FileOutputWriter("vecto_vehicle-sample_xml"); - var sumData = new SummaryDataContainer(sumWriter); - var jobContainer = new JobContainer(sumData); - var dataProvider = new XMLDeclarationInputDataProvider(reader, true); - - var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter); - runsFactory.WriteModalResults = true; - - jobContainer.AddRuns(runsFactory); - - Assert.AreEqual(8, jobContainer.Runs.Count); - } - - [TestMethod] - public void TestFullFeaturedXMEngineering_TorqueConverter() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - - var tcDataProvider = inputDataProvider.TorqueConverterInputData; - - - Assert.AreEqual(3, tcDataProvider.TCData.Rows.Count); - Assert.AreEqual("300.00", tcDataProvider.TCData.Rows[0][2]); - Assert.AreEqual("0.90", tcDataProvider.TCData.Rows[2][1]); - } - - [TestMethod] - public void TestFullFeaturedXMLDeclaration_AngleDrive() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - - - var angledriveDataProvider = inputDataProvider.AngledriveInputData; - - Assert.AreEqual(2.345, angledriveDataProvider.Ratio); - Assert.AreEqual(6, angledriveDataProvider.LossMap.Rows.Count); - Assert.AreEqual("-10000.00", angledriveDataProvider.LossMap.Rows[0][1]); - - AssertHelper.Exception<VectoException>(() => { var tmp = angledriveDataProvider.Efficiency; }); - } - - [TestMethod] - public void TestVehicleInputData() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var vehicleDataProvider = inputDataProvider.JobInputData().Vehicle; - - Assert.AreEqual(VehicleCategory.Tractor, vehicleDataProvider.VehicleCategory); - Assert.AreEqual(AxleConfiguration.AxleConfig_4x2, vehicleDataProvider.AxleConfiguration); - - Assert.AreEqual(7100.0, vehicleDataProvider.CurbMassChassis.Value()); - Assert.AreEqual(40000.0, vehicleDataProvider.GrossVehicleMassRating.Value()); - Assert.AreEqual(6.34, inputDataProvider.AirdragInputData.AirDragArea.Value()); - - Assert.AreEqual(1.0, inputDataProvider.RetarderInputData.Ratio); - } - - [TestMethod] - public void TestFullFeaturedXMLDeclaration_TorqueLimits() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var vehicleDataProvider = inputDataProvider.JobInputData().Vehicle; - - var torqueLimits = vehicleDataProvider.TorqueLimits.OrderBy(x => x.Gear).ToList(); - Assert.AreEqual(3, torqueLimits.Count); - Assert.AreEqual(1, torqueLimits[0].Gear); - Assert.AreEqual(2500, torqueLimits[0].MaxTorque.Value()); - Assert.AreEqual(12, torqueLimits[2].Gear); - } - - [TestMethod] - public void TestFullFeaturedXMLDeclaration_GbxTorqueLimits() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var gearboxDataProvider = inputDataProvider.GearboxInputData; - var gears = gearboxDataProvider.Gears; - - Assert.AreEqual(12, gears.Count); - Assert.AreEqual(1900, gears[0].MaxTorque.Value()); - Assert.AreEqual(1900, gears[1].MaxTorque.Value()); - Assert.IsNull(gears[11].MaxTorque); - } - - [TestMethod] - public void TestFullFeaturedXMLDeclaration_GbxSpeedLimits() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var gearboxDataProvider = inputDataProvider.GearboxInputData; - var gears = gearboxDataProvider.Gears; - - Assert.AreEqual(12, gears.Count); - Assert.AreEqual(2000, gears[0].MaxInputSpeed.AsRPM, 1e-6); - Assert.AreEqual(2000, gears[1].MaxInputSpeed.AsRPM, 1e-6); - Assert.IsNull(gears[11].MaxInputSpeed); - } - - [TestMethod] - public void TestElementNotAvailable() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var retarderRatio = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_RetarderRatio), manager); - retarderRatio.DeleteSelf(); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - - AssertHelper.Exception<VectoException>(() => { var tmp = inputDataProvider.RetarderInputData.Ratio; }); - } - - [TestMethod] - public void TestRetarderTypeNone() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var retarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_RetarderType), manager); - retarderType.SetValue("None"); - - var retarder = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_Components, - XMLNames.Component_Retarder), manager); - retarder.DeleteSelf(); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - - var factory = new SimulatorFactory(ExecutionMode.Declaration, inputDataProvider, new FileOutputWriter("dummy")); - var jobContainer = new JobContainer(null); - jobContainer.AddRuns(factory); - jobContainer.Execute(); - } - - [TestMethod] - public void TestRetarderTypes() - { - var retarderTypes = new Dictionary<string, RetarderType>() { - { "None", RetarderType.None }, - { "Losses included in Gearbox", RetarderType.LossesIncludedInTransmission }, - { "Engine Retarder", RetarderType.EngineRetarder }, - { "Transmission Input Retarder", RetarderType.TransmissionInputRetarder }, - { "Transmission Output Retarder", RetarderType.TransmissionOutputRetarder } - } - ; - foreach (var retarderType in retarderTypes) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_RetarderType), manager); - xmlRetarderType.SetValue(retarderType.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - - Assert.AreEqual(retarderType.Value, inputDataProvider.RetarderInputData.Type); - } - } - - [TestMethod] - public void TestAxleConfigurationTypes() - { - var axleConfigurations = new Dictionary<string, AxleConfiguration>() { - { "4x2", AxleConfiguration.AxleConfig_4x2 }, - //{ "4x4", AxleConfiguration.AxleConfig_4x4 }, - { "6x2", AxleConfiguration.AxleConfig_6x2 }, - { "6x4", AxleConfiguration.AxleConfig_6x4 }, - //{ "6x6", AxleConfiguration.AxleConfig_6x6 }, - //{ "8x2", AxleConfiguration.AxleConfig_8x2 }, - { "8x4", AxleConfiguration.AxleConfig_8x4 }, - //{ "8x6", AxleConfiguration.AxleConfig_8x6 }, - //{ "8x8", AxleConfiguration.AxleConfig_8x8 } - }; - foreach (var axleConfiguration in axleConfigurations) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_AxleConfiguration), manager); - xmlRetarderType.SetValue(axleConfiguration.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - - Assert.AreEqual(axleConfiguration.Value, inputDataProvider.VehicleInputData.AxleConfiguration); - } - } - - [TestMethod] - public void TestVehicleCategoryTypes() - { - var vehicleCategories = new Dictionary<string, VehicleCategory>() { - { "Rigid Truck", VehicleCategory.RigidTruck }, - { "Tractor", VehicleCategory.Tractor }, - //{ "City Bus", VehicleCategory.CityBus }, - //{ "Interurban Bus", VehicleCategory.InterurbanBus }, - //{ "Coach", VehicleCategory.Coach } - }; - foreach (var vehicleCategory in vehicleCategories) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_VehicleCategory), manager); - xmlRetarderType.SetValue(vehicleCategory.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); - - Assert.AreEqual(vehicleCategory.Value, inputDataProvider.VehicleInputData.VehicleCategory); - } - } - - - [TestMethod] - public void TestWheelsTypes() - { - var retarderTypes = new Dictionary<string, RetarderType>() { }; - foreach (var retarderType in retarderTypes) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, - Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_RetarderType), - manager); - xmlRetarderType.SetValue(retarderType.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, - true); - - Assert.AreEqual(retarderType.Value, - inputDataProvider.RetarderInputData.Type); - } - } - - [TestMethod] - public void TestPTOTypeTypes() - { - var ptoTypes = new string[][] { - new[] { "none", "none" }, - new[] { "only one engaged gearwheel above oil level", "none" }, - new[] { "only the drive shaft of the PTO", "shift claw, synchronizer, sliding gearwheel" }, - new[] { "only the drive shaft of the PTO", "multi-disc clutch" }, - new[] { "only the drive shaft of the PTO", "multi-disc clutch, oil pump" }, - new[] { "drive shaft and/or up to 2 gear wheels", "shift claw, synchronizer, sliding gearwheel" }, - new[] { "drive shaft and/or up to 2 gear wheels", "multi-disc clutch" }, - new[] { "drive shaft and/or up to 2 gear wheels", "multi-disc clutch, oil pump" }, - new[] { "drive shaft and/or more than 2 gear wheels", "shift claw, synchronizer, sliding gearwheel" }, - new[] { "drive shaft and/or more than 2 gear wheels", "multi-disc clutch" }, - new[] { "drive shaft and/or more than 2 gear wheels", "multi-disc clutch, oil pump" }, - }; - foreach (var ptoType in ptoTypes) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var ptoGearWheels = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, - Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_PTO, - XMLNames.Vehicle_PTO_ShaftsGearWheels), - manager); - ptoGearWheels.SetValue(ptoType[0]); - var ptoOther = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, - Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_PTO, - XMLNames.Vehicle_PTO_OtherElements), - manager); - ptoOther.SetValue(ptoType[1]); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, - true); - - if (ptoType[0] == "none") { - Assert.AreEqual("None", - inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); - } else if (ptoType[0] == "only one engaged gearwheel above oil level") { - Assert.AreEqual(ptoType[0], - inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); - } else { - Assert.AreEqual(string.Format("{0} - {1}", ptoType[0], ptoType[1]), - inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); - } - DeclarationData.PTOTransmission.Lookup(inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); - } - } - - [TestMethod] - public void TestAngledriveTypes() - { - var angledriveTypes = new Dictionary<string, AngledriveType>() { - { "None", AngledriveType.None }, - { "Losses included in Gearbox", AngledriveType.LossesIncludedInGearbox }, - { "Separate Angledrive", AngledriveType.SeparateAngledrive } - }; - foreach (var angleDrive in angledriveTypes) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, - Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_AngledriveType), - manager); - xmlRetarderType.SetValue(angleDrive.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, - true); - - Assert.AreEqual(angleDrive.Value, inputDataProvider.AngledriveInputData.Type); - } - } - - [TestMethod] - public void TestGearboxTypes() - { - var gearboxTypes = new Dictionary<string, GearboxType>() { - { "SMT", GearboxType.MT }, - { "AMT", GearboxType.AMT }, - { "APT-S", GearboxType.ATSerial }, - { "APT-P", GearboxType.ATPowerSplit } - }; - foreach (var gearboxType in gearboxTypes) { - var reader = XmlReader.Create(SampleVehicleDecl); - - var doc = new XmlDocument(); - doc.Load(reader); - var nav = doc.CreateNavigator(); - var manager = new XmlNamespaceManager(nav.NameTable); - var helper = new XPathHelper(ExecutionMode.Declaration); - helper.AddNamespaces(manager); - - var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( - helper.NSPrefix(XMLNames.VectoInputDeclaration, - Constants.XML.RootNSPrefix), - XMLNames.Component_Vehicle, - XMLNames.Vehicle_Components, - XMLNames.Component_Gearbox, - XMLNames.ComponentDataWrapper, - XMLNames.Gearbox_TransmissionType), - manager); - xmlRetarderType.SetValue(gearboxType.Key); - - var modified = XmlReader.Create(new StringReader(nav.OuterXml)); - - var inputDataProvider = new XMLDeclarationInputDataProvider(modified, - true); - - Assert.AreEqual(gearboxType.Value, inputDataProvider.GearboxInputData.Type); - } - } - - [TestMethod] - public void TestPTOInputNone() - { - var reader = XmlReader.Create(SampleVehicleDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var ptoDataProvider = inputDataProvider.PTOTransmissionInputData; - - Assert.AreEqual("None", ptoDataProvider.PTOTransmissionType); - } - - [TestMethod] - public void TestPTOInput() - { - var reader = XmlReader.Create(SampleVehicleFullDecl); - - var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); - var ptoDataProvider = inputDataProvider.PTOTransmissionInputData; - var ptoLosses = DeclarationData.PTOTransmission.Lookup(ptoDataProvider.PTOTransmissionType); - - Assert.AreEqual("only the drive shaft of the PTO - multi-disc clutch", ptoDataProvider.PTOTransmissionType); - Assert.AreEqual(1000, ptoLosses.Value()); - } - } +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using System.Xml; +using System.Xml.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; +using TUGraz.VectoCore.InputData.Reader; +using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.XML +{ + [TestClass] + public class XMLDeclarationInputTest + { + const string SampleVehicleDecl = "TestData/XML/XMLReaderDeclaration/vecto_vehicle-sample.xml"; + const string SampleVehicleFullDecl = "TestData/XML/XMLReaderDeclaration/vecto_vehicle-sample_FULL.xml"; + + [TestMethod] + public void TestXMLInputEng() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + + var engineDataProvider = inputDataProvider.EngineInputData; + + Assert.IsTrue(engineDataProvider.SavedInDeclarationMode); + + Assert.AreEqual("Generic 40t Long Haul Truck Engine", engineDataProvider.Model); + Assert.AreEqual(0.012730, engineDataProvider.Displacement.Value()); + Assert.AreEqual(1.0097, engineDataProvider.WHTCUrban); + //AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.Inertia; }); + + var fcMapTable = engineDataProvider.FuelConsumptionMap; + Assert.AreEqual(112, fcMapTable.Rows.Count); + Assert.AreEqual("engine speed", fcMapTable.Columns[0].Caption); + Assert.AreEqual("torque", fcMapTable.Columns[1].Caption); + Assert.AreEqual("fuel consumption", fcMapTable.Columns[2].Caption); + + Assert.AreEqual("560.00", fcMapTable.Rows[0][0]); + var fcMap = FuelConsumptionMapReader.Create(fcMapTable); + Assert.AreEqual(1256.SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Value(), + fcMap.GetFuelConsumption(0.SI<NewtonMeter>(), 560.RPMtoRad()).Value.Value()); + + var fldTable = engineDataProvider.FullLoadCurve; + Assert.AreEqual(10, fldTable.Rows.Count); + Assert.AreEqual("engine speed", fldTable.Columns[0].Caption); + Assert.AreEqual("full load torque", fldTable.Columns[1].Caption); + Assert.AreEqual("motoring torque", fldTable.Columns[2].Caption); + var fldMap = FullLoadCurveReader.Create(fldTable, true); + } + + [TestMethod] + public void TestXMLInputGbx() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var gearboxDataProvider = inputDataProvider.GearboxInputData; + + Assert.AreEqual("Generic 40t Long Haul Truck Gearbox", gearboxDataProvider.Model); + Assert.AreEqual(GearboxType.AMT, gearboxDataProvider.Type); + var gears = gearboxDataProvider.Gears; + Assert.AreEqual(12, gears.Count); + + Assert.AreEqual(1, gears.First().Gear); + Assert.AreEqual(14.93, gears.First().Ratio); + Assert.AreEqual("0.00", gears.First().LossMap.Rows[0][0]); + Assert.AreEqual("-350.00", gears.First().LossMap.Rows[0][1]); + Assert.AreEqual("12.06", gears.First().LossMap.Rows[0][2]); + + var lossMap = TransmissionLossMapReader.Create(gears.First().LossMap, gears.First().Ratio, + gears.First().Gear.ToString()); + + Assert.AreEqual(5000, gears.First().MaxTorque.Value()); + } + + [TestMethod] + public void TestXMLInputAxlG() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var axlegearDataProvider = inputDataProvider.AxleGearInputData; + + Assert.AreEqual("Generic 40t Long Haul Truck AxleGear", axlegearDataProvider.Model); + + var lossMapData = axlegearDataProvider.LossMap; + Assert.AreEqual(2.59, axlegearDataProvider.Ratio); + Assert.AreEqual("0.00", lossMapData.Rows[0][0]); + Assert.AreEqual("-5000.00", lossMapData.Rows[0][1]); + Assert.AreEqual("115.00", lossMapData.Rows[0][2]); + + var lossMap = TransmissionLossMapReader.Create(lossMapData, axlegearDataProvider.Ratio, "AxleGear"); + Assert.IsNotNull(lossMap); + + AssertHelper.Exception<VectoException>(() => { var tmp = axlegearDataProvider.Efficiency; }); + } + + [TestMethod] + public void TestXMLInputRetarder() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var retarderDataProvider = inputDataProvider.RetarderInputData; + + Assert.AreEqual("Generic Retarder", retarderDataProvider.Model); + + var lossMapData = retarderDataProvider.LossMap; + + Assert.AreEqual(RetarderType.TransmissionOutputRetarder, retarderDataProvider.Type); + + Assert.AreEqual("0.00", lossMapData.Rows[0][0]); + Assert.AreEqual("10.00", lossMapData.Rows[0][1]); + + var lossMap = RetarderLossMapReader.Create(lossMapData); + Assert.IsNotNull(lossMap); + } + + [TestMethod] + public void TestXMLInputAxleWheels() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var vehicleDataProvider = inputDataProvider.VehicleInputData; + + var axles = vehicleDataProvider.Axles; + + Assert.AreEqual("315/70 R22.5", axles[0].Wheels); + Assert.AreEqual(0.0055, axles[0].RollResistanceCoefficient); + Assert.AreEqual(31300, axles[0].TyreTestLoad.Value()); + + Assert.AreEqual("315/70 R22.5", axles[1].Wheels); + Assert.AreEqual(0.0063, axles[1].RollResistanceCoefficient); + Assert.AreEqual(31300, axles[1].TyreTestLoad.Value()); + } + + [TestMethod] + public void TestXMLInputAxleWheelsDuplicates() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var firstAxle = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_Components, + XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, + XMLNames.AxleWheels_Axles, + helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) + ), manager); + firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); + firstAxle.SetTypedValue(2); + + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + var vehicleDataProvider = inputDataProvider.VehicleInputData; + + AssertHelper.Exception<VectoException>(() => { var axles = vehicleDataProvider.Axles; }); + } + + [TestMethod] + public void TestXMLInputAxleWheelsAxleNumTooLow() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var firstAxle = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_Components, + XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, + XMLNames.AxleWheels_Axles, + helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) + ), manager); + firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); + firstAxle.SetTypedValue(0); + + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + AssertHelper.Exception<VectoException>( + () => { var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); }); + } + + [TestMethod] + public void TestXMLInputAxleWheelsAxleNumTooHigh() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var firstAxle = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_Components, + XMLNames.Component_AxleWheels, + XMLNames.ComponentDataWrapper, + XMLNames.AxleWheels_Axles, + helper.QueryConstraint(XMLNames.AxleWheels_Axles_Axle, "1", null, string.Empty) + ), manager); + firstAxle.MoveToAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, string.Empty); + firstAxle.SetTypedValue(3); + + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + var vehicleDataProvider = inputDataProvider.VehicleInputData; + + AssertHelper.Exception<VectoException>(() => { var axles = vehicleDataProvider.Axles; }); + } + + [TestMethod] + public void TestXMLInputAuxiliaries() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var auxDataProvider = inputDataProvider.AuxiliaryInputData(); + + var aux = auxDataProvider.Auxiliaries; + var aux1 = aux[0]; + + Assert.AreEqual(AuxiliaryType.Fan, aux1.Type); + Assert.AreEqual("Hydraulic driven - Constant displacement pump", aux1.Technology.First()); + + var aux3 = aux[2]; + Assert.AreEqual(AuxiliaryType.ElectricSystem, aux3.Type); + Assert.AreEqual("Standard technology - LED headlights, all", aux3.Technology.First()); + } + + [TestMethod] + public void TestXMLInputADAS() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + + var adas = inputDataProvider.DriverInputData; + + Assert.AreEqual(DriverMode.Overspeed, adas.OverSpeedEcoRoll.Mode); + } + + [TestMethod] + public void TestVehicleInput() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + + var vehicleDataProvider = inputDataProvider.VehicleInputData; + + Assert.AreEqual(VehicleCategory.Tractor, vehicleDataProvider.VehicleCategory); + Assert.AreEqual(AxleConfiguration.AxleConfig_4x2, vehicleDataProvider.AxleConfiguration); + + Assert.AreEqual(7100.0, vehicleDataProvider.CurbMassChassis.Value()); + Assert.AreEqual(40000.0, vehicleDataProvider.GrossVehicleMassRating.Value()); + Assert.AreEqual(6.34, inputDataProvider.AirdragInputData.AirDragArea.Value()); + + Assert.AreEqual(1.0, inputDataProvider.RetarderInputData.Ratio); + } + + [TestMethod] + public void TestXMLPowertrainGeneration() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var fileWriter = new FileOutputWriter("foo"); + var sumWriter = new FileOutputWriter("vecto_vehicle-sample_xml"); + var sumData = new SummaryDataContainer(sumWriter); + var jobContainer = new JobContainer(sumData); + var dataProvider = new XMLDeclarationInputDataProvider(reader, true); + + var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter); + runsFactory.WriteModalResults = true; + + jobContainer.AddRuns(runsFactory); + + Assert.AreEqual(8, jobContainer.Runs.Count); + } + + [TestMethod] + public void TestFullFeaturedXMEngineering_TorqueConverter() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + + var tcDataProvider = inputDataProvider.TorqueConverterInputData; + + + Assert.AreEqual(3, tcDataProvider.TCData.Rows.Count); + Assert.AreEqual("300.00", tcDataProvider.TCData.Rows[0][2]); + Assert.AreEqual("0.90", tcDataProvider.TCData.Rows[2][1]); + } + + [TestMethod] + public void TestFullFeaturedXMLDeclaration_AngleDrive() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + + + var angledriveDataProvider = inputDataProvider.AngledriveInputData; + + Assert.AreEqual(2.345, angledriveDataProvider.Ratio); + Assert.AreEqual(6, angledriveDataProvider.LossMap.Rows.Count); + Assert.AreEqual("-10000.00", angledriveDataProvider.LossMap.Rows[0][1]); + + AssertHelper.Exception<VectoException>(() => { var tmp = angledriveDataProvider.Efficiency; }); + } + + [TestMethod] + public void TestVehicleInputData() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var vehicleDataProvider = inputDataProvider.JobInputData().Vehicle; + + Assert.AreEqual(VehicleCategory.Tractor, vehicleDataProvider.VehicleCategory); + Assert.AreEqual(AxleConfiguration.AxleConfig_4x2, vehicleDataProvider.AxleConfiguration); + + Assert.AreEqual(7100.0, vehicleDataProvider.CurbMassChassis.Value()); + Assert.AreEqual(40000.0, vehicleDataProvider.GrossVehicleMassRating.Value()); + Assert.AreEqual(6.34, inputDataProvider.AirdragInputData.AirDragArea.Value()); + + Assert.AreEqual(1.0, inputDataProvider.RetarderInputData.Ratio); + } + + [TestMethod] + public void TestFullFeaturedXMLDeclaration_TorqueLimits() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var vehicleDataProvider = inputDataProvider.JobInputData().Vehicle; + + var torqueLimits = vehicleDataProvider.TorqueLimits.OrderBy(x => x.Gear).ToList(); + Assert.AreEqual(3, torqueLimits.Count); + Assert.AreEqual(1, torqueLimits[0].Gear); + Assert.AreEqual(2500, torqueLimits[0].MaxTorque.Value()); + Assert.AreEqual(12, torqueLimits[2].Gear); + } + + [TestMethod] + public void TestFullFeaturedXMLDeclaration_GbxTorqueLimits() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var gearboxDataProvider = inputDataProvider.GearboxInputData; + var gears = gearboxDataProvider.Gears; + + Assert.AreEqual(12, gears.Count); + Assert.AreEqual(1900, gears[0].MaxTorque.Value()); + Assert.AreEqual(1900, gears[1].MaxTorque.Value()); + Assert.IsNull(gears[11].MaxTorque); + } + + [TestMethod] + public void TestFullFeaturedXMLDeclaration_GbxSpeedLimits() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var gearboxDataProvider = inputDataProvider.GearboxInputData; + var gears = gearboxDataProvider.Gears; + + Assert.AreEqual(12, gears.Count); + Assert.AreEqual(2000, gears[0].MaxInputSpeed.AsRPM, 1e-6); + Assert.AreEqual(2000, gears[1].MaxInputSpeed.AsRPM, 1e-6); + Assert.IsNull(gears[11].MaxInputSpeed); + } + + [TestMethod] + public void TestElementNotAvailable() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var retarderRatio = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_RetarderRatio), manager); + retarderRatio.DeleteSelf(); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + + AssertHelper.Exception<VectoException>(() => { var tmp = inputDataProvider.RetarderInputData.Ratio; }); + } + + [TestMethod] + public void TestRetarderTypeNone() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var retarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_RetarderType), manager); + retarderType.SetValue("None"); + + var retarder = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_Components, + XMLNames.Component_Retarder), manager); + retarder.DeleteSelf(); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + + var factory = new SimulatorFactory(ExecutionMode.Declaration, inputDataProvider, new FileOutputWriter("dummy")); + var jobContainer = new JobContainer(null); + jobContainer.AddRuns(factory); + jobContainer.Execute(); + } + + [TestMethod] + public void TestRetarderTypes() + { + var retarderTypes = new Dictionary<string, RetarderType>() { + { "None", RetarderType.None }, + { "Losses included in Gearbox", RetarderType.LossesIncludedInTransmission }, + { "Engine Retarder", RetarderType.EngineRetarder }, + { "Transmission Input Retarder", RetarderType.TransmissionInputRetarder }, + { "Transmission Output Retarder", RetarderType.TransmissionOutputRetarder } + } + ; + foreach (var retarderType in retarderTypes) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_RetarderType), manager); + xmlRetarderType.SetValue(retarderType.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + + Assert.AreEqual(retarderType.Value, inputDataProvider.RetarderInputData.Type); + } + } + + [TestMethod] + public void TestAxleConfigurationTypes() + { + var axleConfigurations = new Dictionary<string, AxleConfiguration>() { + { "4x2", AxleConfiguration.AxleConfig_4x2 }, + //{ "4x4", AxleConfiguration.AxleConfig_4x4 }, + { "6x2", AxleConfiguration.AxleConfig_6x2 }, + { "6x4", AxleConfiguration.AxleConfig_6x4 }, + //{ "6x6", AxleConfiguration.AxleConfig_6x6 }, + //{ "8x2", AxleConfiguration.AxleConfig_8x2 }, + { "8x4", AxleConfiguration.AxleConfig_8x4 }, + //{ "8x6", AxleConfiguration.AxleConfig_8x6 }, + //{ "8x8", AxleConfiguration.AxleConfig_8x8 } + }; + foreach (var axleConfiguration in axleConfigurations) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_AxleConfiguration), manager); + xmlRetarderType.SetValue(axleConfiguration.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + + Assert.AreEqual(axleConfiguration.Value, inputDataProvider.VehicleInputData.AxleConfiguration); + } + } + + [TestMethod] + public void TestVehicleCategoryTypes() + { + var vehicleCategories = new Dictionary<string, VehicleCategory>() { + { "Rigid Truck", VehicleCategory.RigidTruck }, + { "Tractor", VehicleCategory.Tractor }, + //{ "City Bus", VehicleCategory.CityBus }, + //{ "Interurban Bus", VehicleCategory.InterurbanBus }, + //{ "Coach", VehicleCategory.Coach } + }; + foreach (var vehicleCategory in vehicleCategories) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_VehicleCategory), manager); + xmlRetarderType.SetValue(vehicleCategory.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, true); + + Assert.AreEqual(vehicleCategory.Value, inputDataProvider.VehicleInputData.VehicleCategory); + } + } + + + [TestMethod] + public void TestWheelsTypes() + { + var retarderTypes = new Dictionary<string, RetarderType>() { }; + foreach (var retarderType in retarderTypes) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, + Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_RetarderType), + manager); + xmlRetarderType.SetValue(retarderType.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, + true); + + Assert.AreEqual(retarderType.Value, + inputDataProvider.RetarderInputData.Type); + } + } + + [TestMethod] + public void TestPTOTypeTypes() + { + var ptoTypes = new string[][] { + new[] { "none", "none" }, + new[] { "only one engaged gearwheel above oil level", "none" }, + new[] { "only the drive shaft of the PTO", "shift claw, synchronizer, sliding gearwheel" }, + new[] { "only the drive shaft of the PTO", "multi-disc clutch" }, + new[] { "only the drive shaft of the PTO", "multi-disc clutch, oil pump" }, + new[] { "drive shaft and/or up to 2 gear wheels", "shift claw, synchronizer, sliding gearwheel" }, + new[] { "drive shaft and/or up to 2 gear wheels", "multi-disc clutch" }, + new[] { "drive shaft and/or up to 2 gear wheels", "multi-disc clutch, oil pump" }, + new[] { "drive shaft and/or more than 2 gear wheels", "shift claw, synchronizer, sliding gearwheel" }, + new[] { "drive shaft and/or more than 2 gear wheels", "multi-disc clutch" }, + new[] { "drive shaft and/or more than 2 gear wheels", "multi-disc clutch, oil pump" }, + }; + foreach (var ptoType in ptoTypes) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var ptoGearWheels = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, + Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_PTO, + XMLNames.Vehicle_PTO_ShaftsGearWheels), + manager); + ptoGearWheels.SetValue(ptoType[0]); + var ptoOther = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, + Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_PTO, + XMLNames.Vehicle_PTO_OtherElements), + manager); + ptoOther.SetValue(ptoType[1]); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, + true); + + if (ptoType[0] == "none") { + Assert.AreEqual("None", + inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); + } else if (ptoType[0] == "only one engaged gearwheel above oil level") { + Assert.AreEqual(ptoType[0], + inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); + } else { + Assert.AreEqual(string.Format("{0} - {1}", ptoType[0], ptoType[1]), + inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); + } + DeclarationData.PTOTransmission.Lookup(inputDataProvider.PTOTransmissionInputData.PTOTransmissionType); + } + } + + [TestMethod] + public void TestAngledriveTypes() + { + var angledriveTypes = new Dictionary<string, AngledriveType>() { + { "None", AngledriveType.None }, + { "Losses included in Gearbox", AngledriveType.LossesIncludedInGearbox }, + { "Separate Angledrive", AngledriveType.SeparateAngledrive } + }; + foreach (var angleDrive in angledriveTypes) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, + Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_AngledriveType), + manager); + xmlRetarderType.SetValue(angleDrive.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, + true); + + Assert.AreEqual(angleDrive.Value, inputDataProvider.AngledriveInputData.Type); + } + } + + [TestMethod] + public void TestGearboxTypes() + { + var gearboxTypes = new Dictionary<string, GearboxType>() { + { "SMT", GearboxType.MT }, + { "AMT", GearboxType.AMT }, + { "APT-S", GearboxType.ATSerial }, + { "APT-P", GearboxType.ATPowerSplit } + }; + foreach (var gearboxType in gearboxTypes) { + var reader = XmlReader.Create(SampleVehicleDecl); + + var doc = new XmlDocument(); + doc.Load(reader); + var nav = doc.CreateNavigator(); + var manager = new XmlNamespaceManager(nav.NameTable); + var helper = new XPathHelper(ExecutionMode.Declaration); + helper.AddNamespaces(manager); + + var xmlRetarderType = nav.SelectSingleNode(helper.QueryAbs( + helper.NSPrefix(XMLNames.VectoInputDeclaration, + Constants.XML.RootNSPrefix), + XMLNames.Component_Vehicle, + XMLNames.Vehicle_Components, + XMLNames.Component_Gearbox, + XMLNames.ComponentDataWrapper, + XMLNames.Gearbox_TransmissionType), + manager); + xmlRetarderType.SetValue(gearboxType.Key); + + var modified = XmlReader.Create(new StringReader(nav.OuterXml)); + + var inputDataProvider = new XMLDeclarationInputDataProvider(modified, + true); + + Assert.AreEqual(gearboxType.Value, inputDataProvider.GearboxInputData.Type); + } + } + + [TestMethod] + public void TestPTOInputNone() + { + var reader = XmlReader.Create(SampleVehicleDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var ptoDataProvider = inputDataProvider.PTOTransmissionInputData; + + Assert.AreEqual("None", ptoDataProvider.PTOTransmissionType); + } + + [TestMethod] + public void TestPTOInput() + { + var reader = XmlReader.Create(SampleVehicleFullDecl); + + var inputDataProvider = new XMLDeclarationInputDataProvider(reader, true); + var ptoDataProvider = inputDataProvider.PTOTransmissionInputData; + var lookup = DeclarationData.PTOTransmission.Lookup(ptoDataProvider.PTOTransmissionType); + + Assert.AreEqual("only the drive shaft of the PTO - multi-disc clutch", ptoDataProvider.PTOTransmissionType); + Assert.AreEqual(1000, lookup.PowerDemand.Value()); + } + } } \ No newline at end of file diff --git a/packages/repositories.config b/packages/repositories.config index 4602b99be1aafb216e83dfc07a5271d8caf8017c..96750bd818fd83effc632b7bb600d511c3f3c3a6 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <repositories> + <repository path="..\..\VECTO_API\Excel2XML\packages.config" /> + <repository path="..\..\VECTO_API\VectoDB\packages.config" /> + <repository path="..\..\VECTO-Bugreports\BugReportTests\packages.config" /> <repository path="..\VECTO\packages.config" /> <repository path="..\VECTOAux\VectoAuxiliaries\packages.config" /> <repository path="..\VECTOAux\VectoAuxiliariesTests\packages.config" />