Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Vehicle.vb 15.9 KiB
Newer Older
' Copyright 2014 European Union.
' Licensed under the EUPL (the 'Licence');
'
' * You may not use this work except in compliance with the Licence.
' * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
' * Unless required by applicable law or agreed to in writing,
'   software distributed under the Licence is distributed on an "AS IS" basis,
'   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
'
' See the LICENSE.txt for the specific language governing permissions and limitations.
Option Infer On

Imports System.Collections.Generic
Imports System.ComponentModel.DataAnnotations
Imports System.IO
Imports System.Linq
Imports TUGraz.VECTO.Input_Files
Imports TUGraz.VectoCommon.InputData
Imports TUGraz.VectoCommon.Models
Imports TUGraz.VectoCommon.Utils
Imports TUGraz.VectoCore.InputData.FileIO.JSON
Imports TUGraz.VectoCore.InputData.Impl
Imports TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
Imports TUGraz.VectoCore.Models.Declaration
Imports TUGraz.VectoCore.Models.SimulationComponent.Data
Imports TUGraz.VectoCore.Utils
<CustomValidation(GetType(Vehicle), "ValidateVehicle")>
	Implements IVehicleEngineeringInputData, IVehicleDeclarationInputData
	'V2 MassMax is now saved in [t] instead of [kg]
	Private Const FormatVersion As Short = 7
	Private _filePath As String
	Private _path As String
	Public Mass As Double
	Public Loading As Double
	Public CrossWindCorrectionMode As CrossWindCorrectionMode
	Public ReadOnly CrossWindCorrectionFile As SubPath
	<ValidateObject()> Public RetarderType As RetarderType
	Public RetarderRatio As Double = 0
	Public ReadOnly RetarderLossMapFile As SubPath
	Public DynamicTyreRadius As Double
	Public ReadOnly Axles As List(Of Axle)


	Public VehicleCategory As VehicleCategory
	Public MassExtra As Double
	Public MassMax As Double
	Public AxleConfiguration As AxleConfiguration

	Public SavedInDeclMode As Boolean
	Public AngularGearType As AngularGearType
	Public AngularGearRatio As Double
	Public ReadOnly AngularGearLossMapFile As SubPath

	Public ReadOnly PTOLossMap As SubPath
	Public ReadOnly PTOCycle As SubPath
		Public RRC As Double
		Public Share As Double
		Public TwinTire As Boolean
		_path = ""
		_filePath = ""
		CrossWindCorrectionFile = New SubPath

		RetarderLossMapFile = New SubPath
		AngularGearLossMapFile = New SubPath()
		PTOLossMap = New SubPath()
		PTOCycle = New SubPath()

	Public Shared Function ValidateVehicle(vehicle As Vehicle, validationContext As ValidationContext) As ValidationResult

		Dim vehicleData As VehicleData

		Dim modeService As ExecutionModeServiceContainer = TryCast(validationContext.GetService(GetType(ExecutionMode)), 
																	ExecutionModeServiceContainer)
		Dim mode = If(modeService Is Nothing, ExecutionMode.Declaration, modeService.Mode)

		Try
			If mode = ExecutionMode.Declaration Then
				Dim doa = New DeclarationDataAdapter()
				Dim segment = DeclarationData.Segments.Lookup(vehicle.VehicleCategory, vehicle.AxleConfiguration,
															vehicle.GrossVehicleMassRating, vehicle.CurbWeightChassis)
				vehicleData = doa.CreateVehicleData(vehicle, segment.Missions.First(),
													segment.Missions.First().Loadings.First().Value)
			Else
				Dim doa = New EngineeringDataAdapter()
				vehicleData = doa.CreateVehicleData(vehicle)
			End If

			Dim result = vehicleData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))

			If Not result.Any() Then Return ValidationResult.Success

			Return New ValidationResult("Vehicle Configuration is invalid. ", result.Select(Function(r) r.ErrorMessage).ToList())
		Catch ex As Exception
			Return New ValidationResult(ex.Message)
		End Try
	Private Sub SetDefault()
		Mass = 0
		MassExtra = 0
		Loading = 0
		CdA0 = 0
		'		CdA0Act = CdA0
		'		CdA02 = 0
		CrossWindCorrectionFile.Clear()
		CrossWindCorrectionMode = CrossWindCorrectionMode.NoCorrection

		DynamicTyreRadius = 0

		RetarderType = RetarderType.None
		RetarderRatio = 1
		RetarderLossMapFile.Clear()
		AngularGearLossMapFile.Clear()

		AngularGearType = AngularGearType.None
		AngularGearLossMapFile.Clear()
		AngularGearRatio = 1

		PTOType = PTOTransmission.NoPTO
		PTOLossMap.Clear()
		PTOCycle.Clear()

		VehicleCategory = VehicleCategory.RigidTruck	'tVehCat.Undef
		AxleConfiguration = AxleConfiguration.AxleConfig_4x2	 'tAxleConf.Undef

		SavedInDeclMode = False
	End Sub

	Public Function ReadFile(Optional showMsg As Boolean = True) As Boolean
		Const msgSrc = "VEH/ReadFile"
		SetDefault()

		Dim json As New JSONParser
		If Not json.ReadFile(_filePath) Then Return False
			Dim header As JToken = json.Content.GetEx("Header")
			Dim body As JToken = json.Content.GetEx("Body")
			_fileVersion = header.GetEx(Of Integer)("FileVersion")
				SavedInDeclMode = body.GetEx(Of Boolean)("SavedInDeclMode")
			Else
				SavedInDeclMode = Cfg.DeclMode
			End If

			Mass = body.GetEx(Of Double)("CurbWeight")
			MassExtra = body.GetEx(Of Double)("CurbWeightExtra")
			Loading = body.GetEx(Of Double)("Loading")
			VehicleCategory = body("VehCat").ToString.ParseEnum(Of VehicleCategory)() 'ConvVehCat(body("VehCat").ToString)
			AxleConfiguration = AxleConfigurationHelper.Parse(body("AxleConfig")("Type").ToString)
			If _fileVersion < 2 Then
				'convert kg to ton
				MassMax /= 1000
			Else
				MassMax = body.GetEx(Of Double)("MassMax")
				'calc CdA from Cd and area value
				CdA0 = (body.GetEx(Of Double)("Cd")) * (body.GetEx(Of Double)("CrossSecArea"))
				CdA0 = body.GetEx(Of Double)("CdA")
			CrossWindCorrectionMode = CrossWindCorrectionModeHelper.Parse(body("CdCorrMode").ToString)
			If Not body("CdCorrFile") Is Nothing Then
				CrossWindCorrectionFile.Init(_path, body.GetEx(Of String)("CdCorrFile"))
			End If

			If body("Retarder") Is Nothing Then
				RetarderType = RetarderTypeHelper.Parse(body("Retarder")("Type").ToString)
				Dim retarder As JToken = body.GetEx("Retarder")
				If Not retarder("Ratio") Is Nothing Then
					RetarderRatio = retarder.GetEx(Of Double)("Ratio")
				If Not retarder("File") Is Nothing Then
					RetarderLossMapFile.Init(_path, retarder.GetEx(Of String)("File"))
				End If
			End If

			If body("AngularGear") Is Nothing Then
				AngularGearType = AngularGearType.None
			Else
				AngularGearType = body("AngularGear")("Type").ToString.ParseEnum(Of AngularGearType)()
				Dim angleDrive As JToken = body("AngularGear")
				If Not angleDrive("Ratio") Is Nothing Then
					AngularGearRatio = angleDrive.GetEx(Of Double)("Ratio")
				End If
				If Not body("AngularGear")("LossMap") Is Nothing Then
					AngularGearLossMapFile.Init(_path, angleDrive.GetEx(Of String)("LossMap"))
				inertiaTemp = body.GetEx(Of Double)("WheelsInertia")
				DynamicTyreRadius = 1000 * body.GetEx(Of Double)("WheelsDiaEff") / 2
				DynamicTyreRadius = body.GetEx(Of Double)("rdyn")
			Dim axleCount As Integer = body("AxleConfig")("Axles").Count()
			For Each axleEntry In body.GetEx("AxleConfig").GetEx("Axles")
				Dim axle = New Axle With {
						.Share = (axleEntry.GetEx(Of Double)("AxleWeightShare")),
						.TwinTire = (axleEntry.GetEx(Of Boolean)("TwinTyres")),
						.RRC = (axleEntry.GetEx(Of Double)("RRCISO")),
						.FzISO = (axleEntry.GetEx(Of Double)("FzISO"))}
					Dim numWheels As Integer = 2
					If axle.TwinTire Then numWheels = 4
					axle.Inertia = inertiaTemp / (numWheels * axleCount)
					axle.Wheels = (axleEntry.GetEx(Of String)("Wheels")).Replace("R ", "R")
					axle.Inertia = (axleEntry.GetEx(Of Double)("Inertia"))
			PTOType = PTOTransmission.NoPTO
			If Not body("PTO") Is Nothing Then
				Dim ptoTypeToken = body.GetEx("PTO")("Type")
				If String.IsNullOrWhiteSpace(ptoTypeToken.Value(Of String)) Then
					PTOType = PTOTransmission.NoPTO
					WorkerMsg(MessageType.Normal, "PTO automatically updated to '" + ptoTypeToken.Value(Of String)() + "'", msgSrc)
						DeclarationData.PTOTransmission.Lookup(ptoTypeToken.Value(Of String))
						PTOType = ptoTypeToken.Value(Of String)()
						WorkerMsg(MessageType.Normal,
								"PTO '" + ptoTypeToken.Value(Of String)() + "' not found, automatically updated to '" + PTOTransmission.NoPTO +
								"'", msgSrc)
						PTOType = PTOTransmission.NoPTO
					End Try
				End If

			End If

			If Not PTOType.Equals(PTOTransmission.NoPTO) Then
				PTOLossMap.Init(_path, body.GetEx("PTO").GetEx(Of String)("LossMap"))
				PTOCycle.Init(_path, body.GetEx("PTO").GetEx(Of String)("Cycle"))
		Catch ex As Exception
			If showMsg Then WorkerMsg(MessageType.Err, "Failed to read Vehicle file! " & ex.Message, msgSrc)
			Return False
		End Try

		Return True
	End Function

	Public Function SaveFile() As Boolean
		SavedInDeclMode = Cfg.DeclMode

		Dim validationResults = Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))

		If validationResults.Count > 0 Then
			Dim messages = validationResults.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct()))
			MsgBox("Invalid input." + Environment.NewLine + String.Join("; ", messages), MsgBoxStyle.OkOnly,
					"Failed to save vehicle")
		Dim json As New JSONParser
		'Header
		Dim header As Dictionary(Of String, Object) = New Dictionary(Of String, Object) From {
				{"CreatedBy", Lic.LicString & " (" & Lic.GUID & ")"},
				{"Date", Now.ToUniversalTime().ToString("o")},
				{"AppVersion", VECTOvers},
				{"FileVersion", FormatVersion}}
		Dim body As Dictionary(Of String, Object) = New Dictionary(Of String, Object) From {
				{"SavedInDeclMode", Cfg.DeclMode},
				{"VehCat", VehicleCategory.ToString()},
				{"CurbWeight", Mass},
				{"CurbWeightExtra", MassExtra},
				{"Loading", Loading},
				{"MassMax", MassMax},
				{"CdA", CdA0},
				{"rdyn", DynamicTyreRadius},
				{"CdCorrMode", CrossWindCorrectionMode.GetName()},
				{"CdCorrFile", CrossWindCorrectionFile.PathOrDummy},
				{"Retarder", New Dictionary(Of String, Object) From {
				{"Type", RetarderType.GetName()},
				{"Ratio", RetarderRatio},
				{"File", RetarderLossMapFile.PathOrDummy}}},
				{"AngularGear", New Dictionary(Of String, Object) From {
				{"Type", AngularGearType.ToString()},
				{"Ratio", AngularGearRatio},
				{"LossMap", AngularGearLossMapFile.PathOrDummy}}},
				{"PTO", New Dictionary(Of String, Object) From {
				{"Type", PTOType},
				{"LossMap", PTOLossMap.PathOrDummy},
				{"Cycle", PTOCycle.PathOrDummy}}},
				{"AxleConfig", New Dictionary(Of String, Object) From {
				{"Type", AxleConfiguration.GetName()},
				{"Axles", (From axle In Axles Select New Dictionary(Of String, Object) From {
				{"Inertia", axle.Inertia},
				{"Wheels", axle.Wheels},
				{"AxleWeightShare", axle.Share},
				{"TwinTyres", axle.TwinTire},
				{"RRCISO", axle.RRC},
				}

		json.Content = JToken.FromObject(New Dictionary(Of String, Object) From {{"Header", header}, {"Body", body}})
	End Function


#Region "Properties"


	Public Property FilePath() As String
		Get
			_filePath = value
			If _filePath = "" Then
				_path = ""
				_path = Path.GetDirectoryName(_filePath) & "\"
#End Region

#Region "IInputData"

	Public ReadOnly Property SavedInDeclarationMode As Boolean Implements IComponentInputData.SavedInDeclarationMode
		Get
			Return Cfg.DeclMode
		End Get
	End Property

	Public ReadOnly Property Vendor As String Implements IComponentInputData.Vendor
		Get
			Return "N.A."  ' TODO: MQ  20160908
		End Get
	End Property

	Public ReadOnly Property ModelName As String Implements IComponentInputData.ModelName
		Get
			Return "N.A."  ' Todo: MQ 20160908
		End Get
	End Property

	Public ReadOnly Property Creator As String Implements IComponentInputData.Creator
		Get
			Return Lic.LicString
		End Get
	End Property

	Public ReadOnly Property [Date] As String Implements IComponentInputData.[Date]
		Get
			Return Now.ToUniversalTime().ToString("o")
		End Get
	End Property

	Public ReadOnly Property TypeId As String Implements IComponentInputData.TypeId
		Get
			Return "N.A."	' ToDo: MQ 20160908
		End Get
	End Property

	Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue
		Get
			Return ""
		End Get
	End Property

	Public ReadOnly Property IntegrityStatus As IntegrityStatus Implements IComponentInputData.IntegrityStatus
		Get
			Return IntegrityStatus.NotChecked
		End Get
	End Property

	Public ReadOnly Property IVehicleDeclarationInputData_VehicleCategory As VehicleCategory _
		Implements IVehicleDeclarationInputData.VehicleCategory
		Get
			Return VehicleCategory
		End Get
	End Property

	Public ReadOnly Property IVehicleDeclarationInputData_AxleConfiguration As AxleConfiguration _
		Implements IVehicleDeclarationInputData.AxleConfiguration
		Get
			Return AxleConfiguration
		End Get
	End Property

	Public ReadOnly Property CurbWeightChassis As Kilogram Implements IVehicleDeclarationInputData.CurbWeightChassis
		Get
			Return MassExtra.SI(Of Kilogram)()
		End Get
	End Property

	Public ReadOnly Property GrossVehicleMassRating As Kilogram _
		Implements IVehicleDeclarationInputData.GrossVehicleMassRating
		Get
			Return MassMax.SI().Ton.Cast(Of Kilogram)()
		End Get
	End Property

	Public ReadOnly Property AirDragArea As SquareMeter Implements IVehicleDeclarationInputData.AirDragArea
		Get
			Return CdA0.SI(Of SquareMeter)()
		End Get
	End Property

	Public ReadOnly Property IVehicleEngineeringInputData_Axles As IList(Of IAxleEngineeringInputData) _
		Implements IVehicleEngineeringInputData.Axles
		Get
			Return AxleWheels().Cast(Of IAxleEngineeringInputData)().ToList()
		End Get
	End Property

	Public ReadOnly Property IVehicleDeclarationInputData_Axles As IList(Of IAxleDeclarationInputData) _
		Implements IVehicleDeclarationInputData.Axles
		Get
			Return AxleWheels().Cast(Of IAxleDeclarationInputData)().ToList()
		End Get
	End Property

	Private Function AxleWheels() As IEnumerable(Of AxleInputData)
		Return Axles.Select(Function(axle) New AxleInputData With {
								.Inertia = axle.Inertia.SI(Of KilogramSquareMeter)(),
								.Wheels = axle.Wheels,
								.AxleWeightShare = axle.Share,
								.TwinTyres = axle.TwinTire,
								.RollResistanceCoefficient = axle.RRC,
								.TyreTestLoad = axle.FzISO.SI(Of Newton)()
								})
	End Function

	Public ReadOnly Property CurbWeightExtra As Kilogram Implements IVehicleEngineeringInputData.CurbWeightExtra
		Get
			Return Mass.SI(Of Kilogram)()
		End Get
	End Property

	Public ReadOnly Property CrosswindCorrectionMap As DataTable _
		Implements IVehicleEngineeringInputData.CrosswindCorrectionMap
		Get
			Return VectoCSVFile.Read(CrossWindCorrectionFile.FullPath)
		End Get
	End Property

	Public ReadOnly Property IVehicleEngineeringInputData_CrossWindCorrectionMode As CrossWindCorrectionMode _
		Implements IVehicleEngineeringInputData.CrossWindCorrectionMode
		Get
			Return CrossWindCorrectionMode.DeclarationModeCorrection
		End Get
	End Property

	Public ReadOnly Property IVehicleEngineeringInputData_DynamicTyreRadius As Meter _
		Implements IVehicleEngineeringInputData.DynamicTyreRadius
		Get
			Return DynamicTyreRadius.SI().Milli.Meter.Cast(Of Meter)()
		End Get
	End Property

	Public ReadOnly Property IVehicleEngineeringInputData_Loading As Kilogram _
		Implements IVehicleEngineeringInputData.Loading
		Get
			Return Loading.SI(Of Kilogram)()
		End Get
	End Property

Michael KRISPER's avatar
Michael KRISPER committed
End Class