OpenPBS.VehicleModels

Information

VehicleModels contains models which defines vehicle models in terms of equations, such as equations of motion. A registry from the previously described package is included in each vehicle model, so that the equations can use the vehicle parameters defined there and the vehicle parameters can be set for instances of the vehicle model. Note that no manoeuvre is defined so far.

Package Content

Name Description
OpenPBS.VehicleModels.Functions Functions  
OpenPBS.VehicleModels.SingleTrack SingleTrack Single-track model for lateral dynamics of articulated vehicles
OpenPBS.VehicleModels.SingleTrack_SaturatedTyre SingleTrack_SaturatedTyre Single-track model for lateral dynamics of articulated vehicles
OpenPBS.VehicleModels.SingleTrackRollDynamics SingleTrackRollDynamics Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation
OpenPBS.VehicleModels.SingleTrackRollDynamicsNonLinTyre SingleTrackRollDynamicsNonLinTyre Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation
OpenPBS.VehicleModels.DirectionInput DirectionInput Single track model with direction of travel at front axle as input
OpenPBS.VehicleModels.DirectionInput_SaturatedTyre DirectionInput_SaturatedTyre Single track model with direction of travel at front axle as input
OpenPBS.VehicleModels.CurvatureInput CurvatureInput Steady-state curve
OpenPBS.VehicleModels.VerticalForces VerticalForces  
OpenPBS.VehicleModels.VerticalForcesRollDynamics VerticalForcesRollDynamics  
OpenPBS.VehicleModels.VerticalForcesRollDynamicsNonLinTyre VerticalForcesRollDynamicsNonLinTyre  
OpenPBS.VehicleModels.Roll Roll  
OpenPBS.VehicleModels.Longitudinal Longitudinal  
OpenPBS.VehicleModels.LongitudinalAccelerationQS LongitudinalAccelerationQS Use max thrust force distributed on driving axles and solve for the highest inclination angle where the desired acceleration can be achieved
OpenPBS.VehicleModels.LongitudinalAcceleration LongitudinalAcceleration Use max thrust force distributed on driving axles for dynamic simulation

OpenPBS.VehicleModels.SingleTrack OpenPBS.VehicleModels.SingleTrack

Single-track model for lateral dynamics of articulated vehicles

OpenPBS.VehicleModels.SingleTrack

Parameters

TypeNameDefaultDescription
VehicleModelparamSet  
Integermode11: Normal, 2: Non-inertial mode, no mass or inertia is considered, 3: Quasistatic, all derivatives are zero
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
ForceFz[nu, na]paramSet.Fz[N]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
LengthFOH[nu]paramSet.FOHFront overhang relative first axle of each unit [m]
LengthROH[nu]paramSet.ROHFront overhang relative first axle of each unit [m]
Angleinclination0Lateral road inclination [rad]
Booleandriven[nu, na]paramSet.driven 
InertiaIz[nu]paramSet.IzInertias [kg.m2]
Positionrx0[nu, na]TM*[0; matrix(B[1:nu - 1] - ...[m]
IntegerTM[nu, nu]Functions.tril(nu) 
Lengthrx0_oh[nu, 2]cat(2, matrix(rx0[:, 1] + FO...Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle [m]

Connectors

TypeNameDescription
input RealInputdelta_inSteering angle at tractor front axle
input RealInputvx_inFirst unit velocity input
output RealOutputvx_out[nu] 
output RealOutputvy_out[nu] 
output RealOutputwz_out[nu] 
output RealOutputay_out[nu, na] 
output RealOutputax_out[nu, na] 
output RealOutputry_out[nu, na] 
output RealOutputtheta_out[nu - 1] 

Modelica definition

model SingleTrack "Single-track model for lateral dynamics of articulated vehicles" /* All length parameters positive forward */ parameter VehicleParameters.Base.VehicleModel paramSet; OpenPBS.VehicleModels.VerticalForces verticalForces(nu=nu,na=na,paramSet=paramSet); parameter Integer mode=1 "1: Normal, 2: Non-inertial mode, no mass or inertia is considered, 3: Quasistatic, all derivatives are zero"; // parameter Boolean steadystate=false // "True if all derivatives should be set to zero"; // /* Dimensions */ // parameter Boolean noninertial=false // "True if inertial effects should be ignored"; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; Modelica.SIunits.Length[nu] X=verticalForces.X "C.g. position relative first axle"; parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] FOH=paramSet.FOH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] ROH=paramSet.ROH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Angle inclination=0 "Lateral road inclination"; parameter Boolean[nu,na] driven=paramSet.driven; /* Cornering stiffnesses */ Real[nu,na] C=paramSet.CCy0.*Fz "Linear cornering stiffness per axle"; /* Masses and inertias */ Modelica.SIunits.Mass[nu] m=verticalForces.m; parameter Modelica.SIunits.Inertia[nu] Iz = paramSet.Iz "Inertias"; /* Inputs */ // input Modelica.SIunits.Angle[nu,na] delta_in input Modelica.Blocks.Interfaces.RealInput delta_in "Steering angle at tractor front axle"; input Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; /* Outputs */ Modelica.Blocks.Interfaces.RealOutput vx_out[nu]=vx; Modelica.Blocks.Interfaces.RealOutput vy_out[nu]=vy; Modelica.Blocks.Interfaces.RealOutput wz_out[nu]=wz; Modelica.Blocks.Interfaces.RealOutput ay_out[nu,na] = matrix(d_vy)*ones(1,na)+Lcog.*(matrix(d_wz)*ones(1,na))+(matrix(wz)*ones(1,na)).*(matrix(vx)*ones(1,na)); Modelica.Blocks.Interfaces.RealOutput ax_out[nu,na] = matrix(d_vx)*ones(1,na)-(matrix(wz)*ones(1,na)).*((matrix(vy)*ones(1,na))+Lcog.*(matrix(wz)*ones(1,na))); Modelica.Blocks.Interfaces.RealOutput ry_out[nu,na]=ry; Modelica.Blocks.Interfaces.RealOutput theta_out[nu-1]=theta; // Modelica.Blocks.Interfaces.RealOutput front_direction = atan2(vy[1]+Lcog[1,1]*wz[1],vx[1])+pz[1] // "Direction of travel at front axle" annotation (Placement(transformation(extent={{100,-70},{120,-50}}))); /* Steering angles */ Modelica.SIunits.Angle[nu,na] delta "Steering angles per axle"; /* Accelerations */ Modelica.SIunits.Acceleration ax[nu] = d_vx-vy.*wz; Modelica.SIunits.Acceleration ay[nu] = d_vy+vx.*wz; /* States */ Modelica.SIunits.AngularVelocity wz[nu](start=zeros(nu)) "Yaw rates"; Modelica.SIunits.Velocity[nu] vy(start=zeros(nu)) "Lateral velocities at c.g."; Modelica.SIunits.Velocity[nu] vx "Longitudinal velocities"; Modelica.SIunits.Angle theta[nu-1] "Articulation angles"; /* ---------- Auxiliary variables ---------- */ /* Slip angles */ Modelica.SIunits.Angle alpha[nu,na] "Slip angle per axle"; /* Tire forces */ Modelica.SIunits.Force Fxd "Drive force (applied to each driven axle)"; Modelica.SIunits.Force Fxw[nu,na] "Wheel longitudinal force"; Modelica.SIunits.Force Fyw[nu,na] "Wheel lateral force"; Modelica.SIunits.Force Fx[nu,na] "Vehicle longitudinal force per axle"; Modelica.SIunits.Force Fy[nu,na] "Vehicle lateral force per axle"; /* Coupling forces */ Modelica.SIunits.Force Fcx[nu-1] "Longitudinal coupling forces"; Modelica.SIunits.Force Fcy[nu-1] "Lateral coupling forces"; /* Computed c.g. distances, positive length should give positive c.g. torque for positive (leftward) lateral force*/ /* Derivative variables */ Modelica.SIunits.Acceleration[nu] d_vx; Modelica.SIunits.Acceleration[nu] d_vy; Modelica.SIunits.AngularAcceleration[nu] d_wz; Modelica.SIunits.AngularVelocity[nu-1] d_theta; Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X; Modelica.SIunits.Length[nu] Acog = A-X; parameter Modelica.SIunits.Position[nu,na] rx0=TM*[0;matrix(B[1:nu-1]-A[2:nu])]*ones(1,na)+L; parameter Integer TM[nu,nu]=Functions.tril(nu); /*Initial coordinates for the over hang. Assume straight starting position. */ //Modelica.SIunits.Length[nu] rx01=rx0[:,1]; parameter Modelica.SIunits.Length[nu,2] rx0_oh=cat(2,matrix(rx0[:,1]+FOH),matrix(rx0[:,1]+ROH)) "Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle"; Modelica.SIunits.Length[nu,2] Lcog_oh=cat(2,matrix(FOH-X),matrix(ROH-X)) "Position of overhang in x-dir from cog, one row for each unit"; Modelica.SIunits.Position[nu,na] rx(start=rx0); Modelica.SIunits.Position[nu,na] ry(start=zeros(nu,na)); Modelica.SIunits.Angle[nu] pz; /*Friction usage. One element for each axle*/ output Real[nu,na] friction_usage=sqrt(Fx.^2+Fy.^2)./verticalForces.Fz; equation if mode==1 then d_vx=der(vx); d_vy=der(vy); d_wz=der(wz); d_theta=der(theta); elseif mode==2 then d_vx=zeros(nu); d_vy=zeros(nu); d_wz=zeros(nu); d_theta=der(theta); else d_vx=zeros(nu); d_vy=zeros(nu); d_wz=zeros(nu); d_theta=zeros(nu-1); end if; /* Input equations */ vx[1] = max(0.1,vx_in); for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then delta[i,j]=delta_in; else delta[i,j]=0; end if; end for; end for; /* Slip angles */ alpha = ((matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na)))./(matrix(vx)*ones(1,na))-delta); /* Tire force */ for i in 1:nu loop for j in 1:na loop if driven[i,j] then Fxw[i,j]=Fxd; else Fxw[i,j]=0; end if; end for; end for; Fyw = -C.*alpha; Fx = Fxw.*cos(delta)-Fyw.*sin(delta); Fy =Fxw .* sin(delta) + Fyw .* cos(delta) - sin(inclination)*verticalForces.Fz; /* Kinematic constraints in couplings */ for i in 1:nu-1 loop vx[i+1] = vx[i]*cos(theta[i])-(vy[i]+Bcog[i]*wz[i])*sin(theta[i]); vy[i+1]+Acog[i+1]*wz[i+1]=(vy[i]+Bcog[i]*wz[i])*cos(theta[i])+vx[i]*sin(theta[i]); end for; (if mode==2 then zeros(nu) else m).*(d_vx-vy.*wz)=vector(Fx*ones(na,1)-[matrix(Fcx);0]+[0;matrix(Fcx)].*cos([0;matrix(theta)])-[0;matrix(Fcy)].*sin([0;matrix(theta)])); (if mode==2 then zeros(nu) else m).*(d_vy+vx.*wz)=vector(Fy*ones(na,1)-[matrix(Fcy);0]+[0;matrix(Fcx)].*sin([0;matrix(theta)])+[0;matrix(Fcy)].*cos([0;matrix(theta)])); (if mode==2 then zeros(nu) else Iz).*d_wz = vector(Lcog.*Fy*ones(na,1)-matrix(Bcog).*[matrix(Fcy);0]+matrix(Acog).*([0;matrix(Fcx)].*sin([0;matrix(theta)])+[0;matrix(Fcy)].*cos([0;matrix(theta)]))); d_theta = wz[1:(nu-1)]-wz[2:nu]; /* Axle global positions */ der(pz)=wz; der(rx)=matrix(vx)*ones(1,na).*(cos(matrix(pz))*ones(1,na))-(matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na))).*(sin(matrix(pz))*ones(1,na)); der(ry)=matrix(vx)*ones(1,na).*(sin(matrix(pz))*ones(1,na))+(matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na))).*(cos(matrix(pz))*ones(1,na)); end SingleTrack;

OpenPBS.VehicleModels.SingleTrack_SaturatedTyre OpenPBS.VehicleModels.SingleTrack_SaturatedTyre

Single-track model for lateral dynamics of articulated vehicles

OpenPBS.VehicleModels.SingleTrack_SaturatedTyre

Parameters

TypeNameDefaultDescription
VehicleModelparamSet  
Integermode11: Normal, 2: Non-inertial mode, no mass or inertia is considered, 3: Quasistatic, all derivatives are zero
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthX[nu]paramSet.XC.g. position relative first axle [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
LengthFOH[nu]paramSet.FOHFront overhang relative first axle of each unit [m]
LengthROH[nu]paramSet.ROHFront overhang relative first axle of each unit [m]
Angleinclination0Lateral road inclination [rad]
Booleandriven[nu, na]paramSet.driven 
Massm[nu]paramSet.mMasses [kg]
InertiaIz[nu]paramSet.IzInertias [kg.m2]
LengthLcog[nu, na]L - matrix(X)*ones(1, na)Axle positions relative c.g. [m]
LengthBcog[nu]B - X[m]
LengthAcog[nu]A - X[m]
Positionrx0[nu, na]TM*[0; matrix(B[1:nu - 1] - ...[m]
IntegerTM[nu, nu]Functions.tril(nu) 
Lengthrx0_oh[nu, 2]cat(2, matrix(rx0[:, 1] + FO...Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle [m]
LengthLcog_oh[nu, 2]cat(2, matrix(FOH - X), matr...Position of overhang in x-dir from cog, one row for each unit [m]
Realmu Friction coefficient

Connectors

TypeNameDescription
input RealInputdelta_inSteering angle at tractor front axle
input RealInputvx_inFirst unit velocity input
output RealOutputvx_out[nu] 
output RealOutputvy_out[nu] 
output RealOutputwz_out[nu] 
output RealOutputay_out[nu, na] 
output RealOutputax_out[nu, na] 
output RealOutputry_out[nu, na] 

Modelica definition

model SingleTrack_SaturatedTyre "Single-track model for lateral dynamics of articulated vehicles" /* All length parameters positive forward */ parameter VehicleParameters.Base.VehicleModel paramSet; OpenPBS.VehicleModels.VerticalForces verticalForces(nu=nu,na=na,paramSet=paramSet); parameter Integer mode=1 "1: Normal, 2: Non-inertial mode, no mass or inertia is considered, 3: Quasistatic, all derivatives are zero"; // parameter Boolean steadystate=false // "True if all derivatives should be set to zero"; // /* Dimensions */ // parameter Boolean noninertial=false // "True if inertial effects should be ignored"; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] X=paramSet.X "C.g. position relative first axle"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] FOH=paramSet.FOH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] ROH=paramSet.ROH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Angle inclination=0 "Lateral road inclination"; parameter Boolean[nu,na] driven=paramSet.driven; /* Cornering stiffnesses */ Real[nu,na] C=paramSet.Cc.*verticalForces.Fz "Linear cornering stiffness per axle"; /* Masses and inertias */ parameter Modelica.SIunits.Mass[nu] m = paramSet.m "Masses"; parameter Modelica.SIunits.Inertia[nu] Iz = paramSet.Iz "Inertias"; /* Inputs */ // input Modelica.SIunits.Angle[nu,na] delta_in input Modelica.Blocks.Interfaces.RealInput delta_in "Steering angle at tractor front axle"; input Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; /* Outputs */ Modelica.Blocks.Interfaces.RealOutput vx_out[nu]=vx; Modelica.Blocks.Interfaces.RealOutput vy_out[nu]=vy; Modelica.Blocks.Interfaces.RealOutput wz_out[nu]=wz; Modelica.Blocks.Interfaces.RealOutput ay_out[nu,na] = matrix(d_vy)*ones(1,na)+Lcog.*(matrix(d_wz)*ones(1,na))+(matrix(wz)*ones(1,na)).*(matrix(vx)*ones(1,na)); Modelica.Blocks.Interfaces.RealOutput ax_out[nu,na] = matrix(d_vx)*ones(1,na)-(matrix(wz)*ones(1,na)).*((matrix(vy)*ones(1,na))+Lcog.*(matrix(wz)*ones(1,na))); Modelica.Blocks.Interfaces.RealOutput ry_out[nu,na]=ry; // Modelica.Blocks.Interfaces.RealOutput front_direction = atan2(vy[1]+Lcog[1,1]*wz[1],vx[1])+pz[1] // "Direction of travel at front axle" annotation (Placement(transformation(extent={{100,-70},{120,-50}}))); /* Steering angles */ Modelica.SIunits.Angle[nu,na] delta "Steering angles per axle"; /* Accelerations */ Modelica.SIunits.Acceleration ax[nu] = d_vx-vy.*wz; Modelica.SIunits.Acceleration ay[nu] = d_vy+vx.*wz; /* States */ Modelica.SIunits.AngularVelocity wz[nu](start=zeros(nu)) "Yaw rates"; Modelica.SIunits.Velocity[nu] vy(start=zeros(nu)) "Lateral velocities at c.g."; Modelica.SIunits.Velocity[nu] vx "Longitudinal velocities"; Modelica.SIunits.Angle theta[nu-1] "Articulation angles"; /* ---------- Auxiliary variables ---------- */ /* Slip angles */ Modelica.SIunits.Angle alpha[nu,na] "Slip angle per axle"; /* Tire forces */ Modelica.SIunits.Force Fxd "Drive force (applied to each driven axle)"; Modelica.SIunits.Force Fxw[nu,na] "Wheel longitudinal force"; Modelica.SIunits.Force Fyw[nu,na] "Wheel lateral force"; Modelica.SIunits.Force Fx[nu,na] "Vehicle longitudinal force per axle"; Modelica.SIunits.Force Fy[nu,na] "Vehicle lateral force per axle"; /* Coupling forces */ Modelica.SIunits.Force Fcx[nu-1] "Longitudinal coupling forces"; Modelica.SIunits.Force Fcy[nu-1] "Lateral coupling forces"; /* Computed c.g. distances, positive length should give positive c.g. torque for positive (leftward) lateral force*/ /* Derivative variables */ Modelica.SIunits.Acceleration[nu] d_vx; Modelica.SIunits.Acceleration[nu] d_vy; Modelica.SIunits.AngularAcceleration[nu] d_wz; Modelica.SIunits.AngularVelocity[nu-1] d_theta; parameter Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; parameter Modelica.SIunits.Length[nu] Bcog = B-X; parameter Modelica.SIunits.Length[nu] Acog = A-X; parameter Modelica.SIunits.Position[nu,na] rx0=TM*[0;matrix(B[1:nu-1]-A[2:nu])]*ones(1,na)+L; parameter Integer TM[nu,nu]=Functions.tril(nu); /*Initial coordinates for the over hang. Assume straight starting position. */ //Modelica.SIunits.Length[nu] rx01=rx0[:,1]; parameter Modelica.SIunits.Length[nu,2] rx0_oh=cat(2,matrix(rx0[:,1]+FOH),matrix(rx0[:,1]+ROH)) "Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle"; parameter Modelica.SIunits.Length[nu,2] Lcog_oh=cat(2,matrix(FOH-X),matrix(ROH-X)) "Position of overhang in x-dir from cog, one row for each unit"; Modelica.SIunits.Position[nu,na] rx(start=rx0); Modelica.SIunits.Position[nu,na] ry(start=zeros(nu,na)); Modelica.SIunits.Angle[nu] pz; /*Friction usage. One element for each axle*/ output Real[nu,na] friction_usage=sqrt(Fx.^2+Fy.^2)./verticalForces.Fz; parameter Real mu "Friction coefficient"; equation if mode==1 then d_vx=der(vx); d_vy=der(vy); d_wz=der(wz); d_theta=der(theta); elseif mode==2 then d_vx=zeros(nu); d_vy=zeros(nu); d_wz=zeros(nu); d_theta=der(theta); else d_vx=zeros(nu); d_vy=zeros(nu); d_wz=zeros(nu); d_theta=zeros(nu-1); end if; /* Input equations */ vx[1] = max(0.1,vx_in); for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then delta[i,j]=delta_in; else delta[i,j]=0; end if; end for; end for; /* Slip angles */ alpha = ((matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na)))./(matrix(vx)*ones(1,na))-delta); /* Tire force */ //Tyre-Longitudinal for i in 1:nu loop for j in 1:na loop if driven[i, j] then Fxw[i, j] = Fxd; else Fxw[i, j] = 0; end if; end for; end for; //Tyre-Lateral for i in 1:nu loop for j in 1:na loop // //Change step 2: if driven[i, j] then Fyw[i, j] = -sign(alpha[i, j])*min(C[i, j]*abs(alpha[i, j]), mu*verticalForces.Fz[i, j])*sqrt(1-((Fyw[i, j]/(mu*verticalForces.Fz[i, j]))^2)); else Fyw[i, j] = -sign(alpha[i, j])*min(C[i, j]*abs(alpha[i, j]), mu*verticalForces.Fz[i, j]); end if; // //Change step 1: // if driven[i, j] then // Fyw[i, j] = -C[i, j]*alpha[i, j]; // else // Fyw[i, j] = -sign(alpha[i, j])*min(C[i, j]*abs(alpha[i, j]), mu*verticalForces.Fz[i, j]); // end if; // //No change: // Fyw[i, j] = -C[i, j]*alpha[i, j]; end for; end for; //Transfromation between tyre and vehicle units coordinate systems Fx = Fxw .* cos(delta) - Fyw .* sin(delta); Fy = Fxw .* sin(delta) + Fyw .* cos(delta) - sin(inclination)*verticalForces.Fz; /* Kinematic constraints in couplings */ for i in 1:nu-1 loop vx[i+1] = vx[i]*cos(theta[i])-(vy[i]+Bcog[i]*wz[i])*sin(theta[i]); vy[i+1]+Acog[i+1]*wz[i+1]=(vy[i]+Bcog[i]*wz[i])*cos(theta[i])+vx[i]*sin(theta[i]); end for; (if mode==2 then zeros(nu) else m).*(d_vx-vy.*wz)=vector(Fx*ones(na,1)-[matrix(Fcx);0]+[0;matrix(Fcx)].*cos([0;matrix(theta)])-[0;matrix(Fcy)].*sin([0;matrix(theta)])); (if mode==2 then zeros(nu) else m).*(d_vy+vx.*wz)=vector(Fy*ones(na,1)-[matrix(Fcy);0]+[0;matrix(Fcx)].*sin([0;matrix(theta)])+[0;matrix(Fcy)].*cos([0;matrix(theta)])); (if mode==2 then zeros(nu) else I).*d_wz = vector(Lcog.*Fy*ones(na,1)-matrix(Bcog).*[matrix(Fcy);0]+matrix(Acog).*([0;matrix(Fcx)].*sin([0;matrix(theta)])+[0;matrix(Fcy)].*cos([0;matrix(theta)]))); d_theta = wz[1:(nu-1)]-wz[2:nu]; /* Axle global positions */ der(pz)=wz; der(rx)=matrix(vx)*ones(1,na).*(cos(matrix(pz))*ones(1,na))-(matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na))).*(sin(matrix(pz))*ones(1,na)); der(ry)=matrix(vx)*ones(1,na).*(sin(matrix(pz))*ones(1,na))+(matrix(vy)*ones(1,na)+Lcog.*(matrix(wz)*ones(1,na))).*(cos(matrix(pz))*ones(1,na)); end SingleTrack_SaturatedTyre;

OpenPBS.VehicleModels.SingleTrackRollDynamics OpenPBS.VehicleModels.SingleTrackRollDynamics

Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation

OpenPBS.VehicleModels.SingleTrackRollDynamics

Parameters

TypeNameDefaultDescription
VehicleModelRollDynamicsparamSet  
Angleinclination0Lateral road inclination [rad]
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthW[nu, na]paramSet.WAxle track width [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
LengthFOH[nu]paramSet.FOHFront overhang relative first axle of each unit [m]
LengthROH[nu]paramSet.ROHFront overhang relative first axle of each unit [m]
Positionh[nu]paramSet.hUnits centre of gravity height [m]
PositionhRC[nu]paramSet.hRCUnits Roll Centre height [m]
PositionhC[nu - 1]paramSet.hCCoupling height between units [m]
Realks[nu, na]paramSet.ksSuspension roll stiffness
Realcs[nu, na]paramSet.csSuspension roll dampening
Booleandriven[nu, na]paramSet.drivenDriven axles in vehicle combination
LengthLr[nu, na]paramSet.LrRelaxation length [m]
InertiaIz[nu]paramSet.IzInertias in yaw plane [kg.m2]
InertiaIx[nu]paramSet.IxInertias in roll plane [kg.m2]
Positionrx0[nu, na]TM*[0; matrix(B[1:nu - 1] - ...[m]
IntegerTM[nu, nu]Functions.tril(nu) 
Lengthrx0_oh[nu, 2]cat(2, matrix(rx0[:, 1] + FO...Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle [m]
ForceFz[nu, na]paramSet.Fz[N]
RealKcr[nu - 1]paramSet.KcrCoupling roll stiffness
RealCcr[nu - 1]paramSet.CcrCoupling roll damping

Connectors

TypeNameDescription
input RealInputdelta_inSteering angle at tractor front axle
input RealInputvx_inFirst unit velocity input
output RealOutputvx_out[nu] 
output RealOutputvys_out[nu] 
output RealOutputwz_out[nu] 
output RealOutputay_out[nu, na] 
output RealOutputax_out[nu, na] 
output RealOutputry_out[nu, na] 
output RealOutputLLT_out 
output RealOutputtheta_out[nu - 1] 

Modelica definition

model SingleTrackRollDynamics "Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation" /* All length parameters positive forward */ parameter VehicleParameters.Base.VehicleModelRollDynamics paramSet; // Calculating static axle loads OpenPBS.VehicleModels.VerticalForcesRollDynamics verticalForcesRollDynamics(nu=nu,na=na,paramSet=paramSet); // Simulation parameters parameter Modelica.SIunits.Angle inclination=0 "Lateral road inclination"; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu,na] W=paramSet.W "Axle track width"; Modelica.SIunits.Length[nu] X=verticalForcesRollDynamics.X "C.g. position relative first axle"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] FOH=paramSet.FOH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] ROH=paramSet.ROH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Position[nu] h = paramSet.h "Units centre of gravity height"; parameter Modelica.SIunits.Position[nu] hRC = paramSet.hRC "Units Roll Centre height"; parameter Modelica.SIunits.Position[nu-1] hC = paramSet.hC "Coupling height between units"; parameter Real[nu,na] ks = paramSet.ks "Suspension roll stiffness"; parameter Real[nu,na] cs = paramSet.cs "Suspension roll dampening"; parameter Boolean[nu,na] driven=paramSet.driven "Driven axles in vehicle combination"; /* Cornering stiffnesses and tyre relaxation length */ Real[nu,na] C=paramSet.CCy0.*Fz "Linear cornering stiffness per axle"; parameter Modelica.SIunits.Length[nu,na] Lr=paramSet.Lr "Relaxation length"; /* Masses and inertias */ Modelica.SIunits.Mass[nu] m = verticalForcesRollDynamics.m "Masses of units"; parameter Modelica.SIunits.Inertia[nu] Iz = paramSet.Iz "Inertias in yaw plane"; parameter Modelica.SIunits.Inertia[nu] Ix = paramSet.Ix "Inertias in roll plane"; /* Inputs */ // input Modelica.SIunits.Angle[nu,na] delta_in input Modelica.Blocks.Interfaces.RealInput delta_in "Steering angle at tractor front axle"; input Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; /* Outputs */ Modelica.Blocks.Interfaces.RealOutput vx_out[nu]=vx; Modelica.Blocks.Interfaces.RealOutput vys_out[nu]=vys; Modelica.Blocks.Interfaces.RealOutput wz_out[nu]=wz; Modelica.Blocks.Interfaces.RealOutput ay_out[nu,na] = matrix(d_vys)*ones(1,na)+Lcog.*(matrix(d_wz)*ones(1,na))+(matrix(wz)*ones(1,na)).*(matrix(vx)*ones(1,na)); Modelica.Blocks.Interfaces.RealOutput ax_out[nu,na] = matrix(d_vx)*ones(1,na)-(matrix(wz)*ones(1,na)).*((matrix(vys)*ones(1,na))+Lcog.*(matrix(wz)*ones(1,na))); Modelica.Blocks.Interfaces.RealOutput ry_out[nu,na]=ry; Modelica.Blocks.Interfaces.RealOutput LLT_out=LoadTransferRatio[end]; Modelica.Blocks.Interfaces.RealOutput theta_out[nu-1]=theta; // Modelica.Blocks.Interfaces.RealOutput front_direction = atan2(vys[1]+Lcog[1,1]*wz[1],vx[1])+pz[1] // "Direction of travel at front axle" annotation (Placement(transformation(extent={{100,-70},{120,-50}}))); /* Steering angles */ Modelica.SIunits.Angle[nu,na] delta "Steering angles per axle"; /* Accelerations */ Modelica.SIunits.Acceleration ax[nu] = d_vx-vys.*wz; Modelica.SIunits.Acceleration ay[nu] = d_vys+vx.*wz; /* States */ Modelica.SIunits.AngularVelocity wz[nu](start=zeros(nu)) "Yaw rates"; Modelica.SIunits.Velocity[nu] vys(start=zeros(nu)) "Lateral velocities at c.g."; Modelica.SIunits.Velocity[nu] vx "Longitudinal velocities"; Modelica.SIunits.Angle theta[nu-1] "Articulation angles"; /* ---------- Auxiliary variables ---------- */ /* Slip angles */ Modelica.SIunits.Angle alpha[nu,na] "Slip angle per axle"; /* Tire forces */ Modelica.SIunits.Force Fxd "Drive force (applied to each driven axle)"; Modelica.SIunits.Force Fxw[nu,na] "Wheel longitudinal force"; Modelica.SIunits.Force Fyw[nu,na] "Wheel lateral force"; Modelica.SIunits.Force Fx[nu,na] "Vehicle longitudinal force per axle"; Modelica.SIunits.Force Fy[nu,na] "Vehicle lateral force per axle"; /* Coupling forces */ Modelica.SIunits.Force Fcx[nu-1] "Longitudinal coupling forces"; Modelica.SIunits.Force Fcy[nu-1] "Lateral coupling forces"; /* Computed c.g. distances, positive length should give positive c.g. torque for positive (leftward) lateral force*/ Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X "Rear coupling positions relative c.g."; Modelica.SIunits.Length[nu] Acog = A-X "Front coupling positions relative c.g."; parameter Modelica.SIunits.Position[nu,na] rx0=TM*[0;matrix(B[1:nu-1]-A[2:nu])]*ones(1,na)+L; parameter Integer TM[nu,nu]=Functions.tril(nu); /* Derivative variables */ Modelica.SIunits.Acceleration[nu] d_vx; Modelica.SIunits.Acceleration[nu] d_vys; Modelica.SIunits.AngularAcceleration[nu] d_wz; Modelica.SIunits.AngularVelocity[nu-1] d_theta; /*Initial coordinates for the over hang. Assume straight starting position. */ //Modelica.SIunits.Length[nu] rx01=rx0[:,1]; parameter Modelica.SIunits.Length[nu,2] rx0_oh=cat(2,matrix(rx0[:,1]+FOH),matrix(rx0[:,1]+ROH)) "Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle"; Modelica.SIunits.Length[nu,2] Lcog_oh=cat(2,matrix(FOH-X),matrix(ROH-X)) "Position of overhang in x-dir from cog, one row for each unit"; Modelica.SIunits.Position[nu,na] rx(start=rx0); Modelica.SIunits.Position[nu,na] ry(start=zeros(nu,na)); Modelica.SIunits.Angle[nu] pz; /*Friction usage. One element for each axle*/ output Real[nu,na] friction_usage=sqrt(Fx.^2+Fy.^2)./Fz; /* ---------- Variables related to Tyre relaxation and Roll dynamics ---------- */ /* Positions */ Modelica.SIunits.Position[nu] xs "x-coordinate of sprung mass"; Modelica.SIunits.Position[nu] xu "x-coordinate of unsprung mass"; Modelica.SIunits.Position[nu] ys "y-coordinate of sprung mass"; Modelica.SIunits.Position[nu] yu "y-coordinate of unsprung mass"; /* Velocity and roll rate */ Modelica.SIunits.Velocity[nu] vyu "Lateral velocity of unsprung mass"; Modelica.SIunits.AngularVelocity[nu] wx "Roll rate of sprung mass"; /* Suspension torque */ Modelica.SIunits.Torque[nu] Mxs "Torque created by roll stiffness"; Modelica.SIunits.Torque[nu] Mxd "Torque created by roll damping"; Modelica.SIunits.Torque[nu] Mx "Torque at RC from suspension"; /* Tyreloads */ Modelica.SIunits.Force[nu] FzUnitRight "Load on the right side tyres on vehicle units"; Modelica.SIunits.Force[nu] FzUnitLeft "Load on the left side tyres on vehicle units"; Modelica.SIunits.Force[nu,na] FzAxleRight "Load on the right side tyres on vehicle axles"; Modelica.SIunits.Force[nu,na] FzAxleLeft "Load on the left side tyres on vehicle axles"; /* Other */ Modelica.SIunits.Angle[nu] px "Roll angle"; Real[nu,na] ALR "vx/Lr"; Real[nu] LoadTransferRatio "LLT"; /* Derivatives */ Real[nu] d_px; Real[nu] d_wx; Real[nu] d_Mxs; /* Lateral load transfer */ Real[nu,na] delta_z; /* Axle loads */ parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; /* Suspension parameters */ final parameter Real[nu] ksSum=vector(ks*ones(na,1)); final parameter Real[nu] csSum=vector(cs*ones(na,1)); /* Roll stiff Couplings */ Modelica.SIunits.Torque[nu-1] Mxc "Roll moment in coupling"; Modelica.SIunits.Angle[nu+1,1] Delta_px1; Modelica.SIunits.Angle[nu-1,1] Delta_px2; parameter Real[nu-1] Kcr=paramSet.Kcr "Coupling roll stiffness"; parameter Real[nu-1] Ccr=paramSet.Ccr "Coupling roll damping"; equation // Path der(xs) = vx .* cos(pz) - vys .* sin(pz); der(ys) = vys .* cos(pz) + vx .* sin(pz); der(xu) = vx .* cos(pz) - vyu .* sin(pz); der(yu) = vyu .* cos(pz) + vx .* sin(pz); /* Single track model */ // Derivatives d_vx = der(vx); d_vys = der(vys); d_wz = der(wz); d_theta = der(theta); // Input equations vx[1] = max(0.1,vx_in); // Steer input axle definitions for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then delta[i,j]=delta_in; else delta[i,j]=0; end if; end for; end for; // Slip angles alpha + delta = (matrix(vyu) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) ./ (matrix(vx) * ones(1,na)); // Tire force for i in 1:nu loop for j in 1:na loop if driven[i,j] then Fxw[i,j]=Fxd; else Fxw[i,j]=0; end if; end for; end for; // Tyre Relaxation for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then Fyw[i,j] = -C[i,j] .* alpha[i,j]; else der(Fyw[i,j])= ALR[i,j] * ((-C[i,j] * alpha[i,j])-Fyw[i,j]); end if; end for; end for; ALR=matrix(abs(vx))*ones(1,na)./ Lr; Fx = Fxw .* cos(delta) - Fyw .* sin(delta); Fy = Fxw .* sin(delta) + Fyw .* cos(delta) - sin(inclination) * Fz; // Kinematic constraints in couplings for i in 1:nu-1 loop vx[i+1] = vx[i] * cos(theta[i]) - (vys[i] + Bcog[i] * wz[i] + (hC[i] - hRC[i]) * wx[i]) * sin(theta[i]); vys[i+1] + Acog[i+1] * wz[i+1] + (hC[i] - hRC[i+1]) * wx[i+1] = (vys[i] + Bcog[i] * wz[i] + (hC[i] - hRC[i]) * wx[i]) * cos(theta[i]) + vx[i] * sin(theta[i]); end for; // Equilibrium, Longitudinal, Lateral and Yaw m .* (d_vx - vys .* wz) = vector(Fx * ones(na,1) - [matrix(Fcx);0] + [0;matrix(Fcx)] .* cos([0;matrix(theta)]) - [0;matrix(Fcy)] .* sin([0;matrix(theta)])); m .* (d_vys + vx .* wz) = vector(Fy * ones(na,1) - [matrix(Fcy);0] + [0;matrix(Fcx)] .* sin([0;matrix(theta)]) + [0;matrix(Fcy)] .* cos([0;matrix(theta)])); Iz .* d_wz = vector(Lcog .* Fy * ones(na,1) - matrix(Bcog) .* [matrix(Fcy);0] + matrix(Acog) .* ([0;matrix(Fcx)] .* sin([0;matrix(theta)]) + [0;matrix(Fcy)] .* cos([0;matrix(theta)]))); d_theta = wz[1:(nu-1)] - wz[2:nu]; // Axle global positions der(pz) = wz; der(rx) = matrix(vx) * ones(1,na) .* (cos(matrix(pz)) * ones(1,na)) - (matrix(vys) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) .* (sin(matrix(pz)) * ones(1,na)); der(ry) = matrix(vx) * ones(1,na) .* (sin(matrix(pz)) * ones(1,na)) + (matrix(vys) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) .* (cos(matrix(pz)) * ones(1,na)); /* Roll dynamics */ // Derivatives d_px = der(px); d_wx = der(wx); d_Mxs = der(Mxs); // Roll dynamics Mxs + Mxd = vector(matrix(Mx) + Fy * ones(na,1) .* matrix(hRC)); d_px = wx; vyu = vector(matrix(vys) + matrix(wx) .* (matrix(h) - matrix(hRC))); Ix .* d_wx = vector(matrix(Mx) + Fy * ones(na,1) .* matrix(h) + matrix(m) .* matrix(fill(9.81, nu, 1)) .* matrix(h - hRC) .* matrix(px) + matrix([Fcy;0]) .* (matrix(h) - matrix([hC;0])) + matrix([0; sin(theta) .* Fcy + cos(theta) .* Fcx]) .* (matrix(h) - matrix([0;hC]))+matrix([Mxc;0])-matrix([0;Mxc])); d_Mxs = -ksSum .* wx; Mxd = -csSum .* wx; // Roll stiff couplings Delta_px1=[0;matrix(px)]-[matrix(px);0]; Delta_px2=matrix(Delta_px1[2:end-1,1]); Mxc=-Ccr.*vector(der(Delta_px2))-Kcr.*vector(Delta_px2); // Load transfer der(delta_z) + W .* delta_z =ks .* (matrix(px) * ones(1,na)) + cs .* (matrix(d_px) * ones(1,na)) + Fy .* (matrix(h)*ones(1,na)); FzAxleRight=(Fz./2).+delta_z; FzAxleLeft=(Fz./2).-delta_z; FzUnitRight=vector(FzAxleRight*ones(na,1)); FzUnitLeft=vector(FzAxleLeft*ones(na,1)); LoadTransferRatio=(FzUnitRight-FzUnitLeft)./(FzUnitRight+FzUnitLeft); end SingleTrackRollDynamics;

OpenPBS.VehicleModels.SingleTrackRollDynamicsNonLinTyre OpenPBS.VehicleModels.SingleTrackRollDynamicsNonLinTyre

Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation

OpenPBS.VehicleModels.SingleTrackRollDynamicsNonLinTyre

Parameters

TypeNameDefaultDescription
VehicleModelRollDynamicsNonLinTyreparamSet  
Angleinclination0Lateral road inclination [rad]
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthW[nu, na]paramSet.WAxle track width [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
LengthFOH[nu]paramSet.FOHFront overhang relative first axle of each unit [m]
LengthROH[nu]paramSet.ROHFront overhang relative first axle of each unit [m]
Positionh[nu]paramSet.hUnits centre of gravity height [m]
PositionhRC[nu]paramSet.hRCUnits Roll Centre height [m]
PositionhC[nu - 1]paramSet.hCCoupling height between units [m]
Realks[nu, na]paramSet.ksSuspension roll stiffness
Realcs[nu, na]paramSet.csSuspension roll dampening
Booleandriven[nu, na]paramSet.drivenDriven axles in vehicle combination
InertiaIz[nu]paramSet.IzInertias in yaw plane [kg.m2]
InertiaIx[nu]paramSet.IxInertias in roll plane [kg.m2]
Positionrx0[nu, na]TM*[0; matrix(B[1:nu - 1] - ...[m]
IntegerTM[nu, nu]Functions.tril(nu) 
Lengthrx0_oh[nu, 2]cat(2, matrix(rx0[:, 1] + FO...Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle [m]
ForceFz[nu, na]paramSet.Fz[N]
RealKcr[nu - 1]paramSet.KcrCoupling roll stiffness
RealCcr[nu - 1]paramSet.CcrCoupling roll damping
LengthLr[nu, na]paramSet.LrRelaxation length [m]
ForceFZT0[nu, na]paramSet.FZT0Tyre static load on each indicidual axle [N]
Realuy0[nu, na]paramSet.uy0Maximum lateral force coefficient at nominal vertical tyre force
Realugy[nu, na]paramSet.ugyMaximum lateral force gradient
Realu2[nu, na]paramSet.u2Slide friction ratio
RealCCy0[nu, na]paramSet.CCy0Tyre cornering coefficient on each individual axle at nominal tyre force
Realccgy[nu, na]paramSet.ccgyMaximum cornering coefficient gradient

Connectors

TypeNameDescription
input RealInputdelta_inSteering angle at tractor front axle
input RealInputvx_inFirst unit velocity input
output RealOutputvx_out[nu] 
output RealOutputvys_out[nu] 
output RealOutputwz_out[nu] 
output RealOutputay_out[nu, na] 
output RealOutputax_out[nu, na] 
output RealOutputry_out[nu, na] 
output RealOutputLLT_out 
output RealOutputtheta_out[nu - 1] 

Modelica definition

model SingleTrackRollDynamicsNonLinTyre "Single-track model for lateral dynamics of articulated vehicles with roll dynamics and tyre relaxation" /* All length parameters positive forward */ parameter VehicleParameters.Base.VehicleModelRollDynamicsNonLinTyre paramSet; // Calculating static axle loads OpenPBS.VehicleModels.VerticalForcesRollDynamicsNonLinTyre verticalForcesRollDynamicsNonLinTyre(nu=nu,na=na,paramSet=paramSet); // Simulation parameters parameter Modelica.SIunits.Angle inclination=0 "Lateral road inclination"; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu,na] W=paramSet.W "Axle track width"; Modelica.SIunits.Length[nu] X=verticalForcesRollDynamicsNonLinTyre.X "C.g. position relative first axle"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] FOH=paramSet.FOH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] ROH=paramSet.ROH "Front overhang relative first axle of each unit"; parameter Modelica.SIunits.Position[nu] h = paramSet.h "Units centre of gravity height"; parameter Modelica.SIunits.Position[nu] hRC = paramSet.hRC "Units Roll Centre height"; parameter Modelica.SIunits.Position[nu-1] hC = paramSet.hC "Coupling height between units"; parameter Real[nu,na] ks = paramSet.ks "Suspension roll stiffness"; parameter Real[nu,na] cs = paramSet.cs "Suspension roll dampening"; parameter Boolean[nu,na] driven=paramSet.driven "Driven axles in vehicle combination"; /* Masses and inertias */ Modelica.SIunits.Mass[nu] m = verticalForcesRollDynamicsNonLinTyre.m "Masses of units"; parameter Modelica.SIunits.Inertia[nu] Iz = paramSet.Iz "Inertias in yaw plane"; parameter Modelica.SIunits.Inertia[nu] Ix = paramSet.Ix "Inertias in roll plane"; /* Inputs */ // input Modelica.SIunits.Angle[nu,na] delta_in input Modelica.Blocks.Interfaces.RealInput delta_in "Steering angle at tractor front axle"; input Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; /* Outputs */ Modelica.Blocks.Interfaces.RealOutput vx_out[nu]=vx; Modelica.Blocks.Interfaces.RealOutput vys_out[nu]=vys; Modelica.Blocks.Interfaces.RealOutput wz_out[nu]=wz; Modelica.Blocks.Interfaces.RealOutput ay_out[nu,na] = matrix(d_vys)*ones(1,na)+Lcog.*(matrix(d_wz)*ones(1,na))+(matrix(wz)*ones(1,na)).*(matrix(vx)*ones(1,na)); Modelica.Blocks.Interfaces.RealOutput ax_out[nu,na] = matrix(d_vx)*ones(1,na)-(matrix(wz)*ones(1,na)).*((matrix(vys)*ones(1,na))+Lcog.*(matrix(wz)*ones(1,na))); Modelica.Blocks.Interfaces.RealOutput ry_out[nu,na]=ry; Modelica.Blocks.Interfaces.RealOutput LLT_out=LoadTransferRatio[end]; Modelica.Blocks.Interfaces.RealOutput theta_out[nu-1]=theta; // Modelica.Blocks.Interfaces.RealOutput front_direction = atan2(vys[1]+Lcog[1,1]*wz[1],vx[1])+pz[1] // "Direction of travel at front axle" annotation (Placement(transformation(extent={{100,-70},{120,-50}}))); /* Steering angles */ Modelica.SIunits.Angle[nu,na] delta "Steering angles per axle"; /* Accelerations */ Modelica.SIunits.Acceleration ax[nu] = d_vx-vys.*wz; Modelica.SIunits.Acceleration ay[nu] = d_vys+vx.*wz; /* States */ Modelica.SIunits.AngularVelocity wz[nu](start=zeros(nu)) "Yaw rates"; Modelica.SIunits.Velocity[nu] vys(start=zeros(nu)) "Lateral velocities at c.g."; Modelica.SIunits.Velocity[nu] vx "Longitudinal velocities"; Modelica.SIunits.Angle theta[nu-1] "Articulation angles"; /* ---------- Auxiliary variables ---------- */ /* Slip angles */ Modelica.SIunits.Angle alpha[nu,na] "Slip angle per axle"; /* Tire forces */ Modelica.SIunits.Force Fxd "Drive force (applied to each driven axle)"; Modelica.SIunits.Force Fxw[nu,na] "Wheel longitudinal force"; Modelica.SIunits.Force Fyw[nu,na] "Wheel lateral force"; Modelica.SIunits.Force Fx[nu,na] "Vehicle longitudinal force per axle"; Modelica.SIunits.Force Fy[nu,na] "Vehicle lateral force per axle"; /* Coupling forces */ Modelica.SIunits.Force Fcx[nu-1] "Longitudinal coupling forces"; Modelica.SIunits.Force Fcy[nu-1] "Lateral coupling forces"; /* Computed c.g. distances, positive length should give positive c.g. torque for positive (leftward) lateral force*/ Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X "Rear coupling positions relative c.g."; Modelica.SIunits.Length[nu] Acog = A-X "Front coupling positions relative c.g."; parameter Modelica.SIunits.Position[nu,na] rx0=TM*[0;matrix(B[1:nu-1]-A[2:nu])]*ones(1,na)+L; parameter Integer TM[nu,nu]=Functions.tril(nu); /* Derivative variables */ Modelica.SIunits.Acceleration[nu] d_vx; Modelica.SIunits.Acceleration[nu] d_vys; Modelica.SIunits.AngularAcceleration[nu] d_wz; Modelica.SIunits.AngularVelocity[nu-1] d_theta; /*Initial coordinates for the over hang. Assume straight starting position. */ //Modelica.SIunits.Length[nu] rx01=rx0[:,1]; parameter Modelica.SIunits.Length[nu,2] rx0_oh=cat(2,matrix(rx0[:,1]+FOH),matrix(rx0[:,1]+ROH)) "Initial position in x-dir of overhang. Front in first colume rear in second. Resolved from first units first axle"; Modelica.SIunits.Length[nu,2] Lcog_oh=cat(2,matrix(FOH-X),matrix(ROH-X)) "Position of overhang in x-dir from cog, one row for each unit"; Modelica.SIunits.Position[nu,na] rx(start=rx0); Modelica.SIunits.Position[nu,na] ry(start=zeros(nu,na)); Modelica.SIunits.Angle[nu] pz; // /*Friction usage. One element for each axle*/ constant Modelica.SIunits.Force F_eps=Modelica.Constants.eps "Used to avoid division by zero"; output Real[nu,na] friction_usage; /* ---------- Variables related to Tyre relaxation and Roll dynamics ---------- */ /* Positions */ Modelica.SIunits.Position[nu] xs "x-coordinate of sprung mass"; Modelica.SIunits.Position[nu] xu "x-coordinate of unsprung mass"; Modelica.SIunits.Position[nu] ys "y-coordinate of sprung mass"; Modelica.SIunits.Position[nu] yu "y-coordinate of unsprung mass"; /* Velocity and roll rate */ Modelica.SIunits.Velocity[nu] vyu "Lateral velocity of unsprung mass"; Modelica.SIunits.AngularVelocity[nu] wx "Roll rate of sprung mass"; /* Suspension torque */ Modelica.SIunits.Torque[nu] Mxs "Torque created by roll stiffness"; Modelica.SIunits.Torque[nu] Mxd "Torque created by roll damping"; Modelica.SIunits.Torque[nu] Mx "Torque at RC from suspension"; /* Tyreloads */ Modelica.SIunits.Force[nu] FzUnitRight "Load on the right side tyres on vehicle units"; Modelica.SIunits.Force[nu] FzUnitLeft "Load on the left side tyres on vehicle units"; Modelica.SIunits.Force[nu,na] FzAxleRight "Load on the right side tyres on vehicle axles"; Modelica.SIunits.Force[nu,na] FzAxleLeft "Load on the left side tyres on vehicle axles"; /* Other */ Modelica.SIunits.Angle[nu] px "Roll angle"; Real[nu] LoadTransferRatio "LLT"; /* Derivatives */ Real[nu] d_px; Real[nu] d_wx; Real[nu] d_Mxs; /* Lateral load transfer */ Real[nu,na] delta_z; /* Axle loads */ parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; /* Suspension parameters */ final parameter Real[nu] ksSum=vector(ks*ones(na,1)); final parameter Real[nu] csSum=vector(cs*ones(na,1)); /* Roll stiff Couplings */ Modelica.SIunits.Torque[nu-1] Mxc "Roll moment in coupling"; Modelica.SIunits.Angle[nu+1,1] Delta_px1; Modelica.SIunits.Angle[nu-1,1] Delta_px2; parameter Real[nu-1] Kcr=paramSet.Kcr "Coupling roll stiffness"; parameter Real[nu-1] Ccr=paramSet.Ccr "Coupling roll damping"; /* Tyre model */ // Parameters parameter Modelica.SIunits.Length[nu,na] Lr=paramSet.Lr "Relaxation length"; parameter Modelica.SIunits.Force[nu,na] FZT0=paramSet.FZT0 "Tyre static load on each indicidual axle"; parameter Real[nu,na] uy0=paramSet.uy0 "Maximum lateral force coefficient at nominal vertical tyre force"; parameter Real[nu,na] ugy=paramSet.ugy "Maximum lateral force gradient"; parameter Real[nu,na] u2=paramSet.u2 "Slide friction ratio"; parameter Real[nu,na] CCy0=paramSet.CCy0 "Tyre cornering coefficient on each individual axle at nominal tyre force"; parameter Real[nu,na] ccgy=paramSet.ccgy "Maximum cornering coefficient gradient "; // Variables Modelica.SIunits.Force[nu,na] FZT_l "Vertical tyre force, left side tyres"; Modelica.SIunits.Force[nu,na] FZT_r "Vertical tyre force, right side tyres"; Modelica.SIunits.Force[nu,na] FYT_l "Lateral tyre force, left side tyres"; Modelica.SIunits.Force[nu,na] FYT_r "Lateral tyre force, right side tyres"; Modelica.SIunits.Angle[nu,na] alpha_dot "Slip angle with tyre relaxation"; Real[nu,na] CCy_l "Cornering coefficient, left side tyres"; Real[nu,na] CCy_r "Cornering coefficient, right side tyres"; Real[nu,na] uy_l "Maximum lateral force coefficient, left side tyres"; Real[nu,na] uy_r "Maximum lateral force coefficient, right side tyres"; Real[nu,na] C "Shape factor"; equation // Friction usage for i in 1:nu loop for j in 1:na loop friction_usage[i,j]=sqrt(Fy[i,j]^2+Fx[i,j]^2)./(max(Fz[i,j],F_eps)); end for; end for; // Path der(xs) = vx .* cos(pz) - vys .* sin(pz); der(ys) = vys .* cos(pz) + vx .* sin(pz); der(xu) = vx .* cos(pz) - vyu .* sin(pz); der(yu) = vyu .* cos(pz) + vx .* sin(pz); /* Single track model */ // Derivatives d_vx = der(vx); d_vys = der(vys); d_wz = der(wz); d_theta = der(theta); // Input equations vx[1] = max(0.1,vx_in); // Steer input axle definitions for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then delta[i,j]=delta_in; else delta[i,j]=0; end if; end for; end for; // Slip angles alpha + delta = (matrix(vyu) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) ./ (matrix(vx) * ones(1,na)); // Tire force for i in 1:nu loop for j in 1:na loop if driven[i,j] then Fxw[i,j]=Fxd; else Fxw[i,j]=0; end if; end for; end for; /* Tyre model */ // If tyre is in the air --> tyre force = 0 for i in 1:nu loop for j in 1:na loop if FzAxleRight[i,j] >= 0 then FZT_r[i,j] = FzAxleRight[i,j]; else FZT_r[i,j] = 0; end if; end for; end for; // If tyre is in the air --> tyre force = 0 for i in 1:nu loop for j in 1:na loop if FzAxleLeft[i,j] >= 0 then FZT_l[i,j] = FzAxleLeft[i,j]; else FZT_l[i,j] = 0; end if; end for; end for; // Tyre relaxation der(alpha_dot)=((matrix(vx)*ones(1,na))./Lr) .* (alpha - alpha_dot); for i in 1:nu loop for j in 1:na loop if i==1 and j==1 then FYT_l[i,j]=FZT_l[i,j] .* uy_l[i,j] .* sin( C[i,j] .* atan(CCy_l[i,j] ./ (C[i,j] .* uy_l[i,j]) .* alpha[i,j])); FYT_r[i,j]=FZT_r[i,j] .* uy_r[i,j] .* sin( C[i,j] .* atan(CCy_r[i,j] ./ (C[i,j] .* uy_r[i,j]) .* alpha[i,j])); else FYT_l[i,j]=FZT_l[i,j] .* uy_l[i,j] .* sin( C[i,j] .* atan(CCy_l[i,j] ./ (C[i,j] .* uy_l[i,j]) .* alpha_dot[i,j])); FYT_r[i,j]=FZT_r[i,j] .* uy_r[i,j] .* sin( C[i,j] .* atan(CCy_r[i,j] ./ (C[i,j] .* uy_r[i,j]) .* alpha_dot[i,j])); end if; end for; end for; // Tyre model variables C = 2.*(1 .+ asin(u2)./Modelica.Constants.pi); uy_l = uy0 .* ((ones(nu,na) + ugy .* ((FZT_l-FZT0)./(FZT0)))); uy_r = uy0 .* ((ones(nu,na) + ugy .* ((FZT_r-FZT0)./(FZT0)))); CCy_l = CCy0 .* ((ones(nu,na) + ccgy .* ((FZT_l-FZT0)./(FZT0)))); CCy_r = CCy0 .* ((ones(nu,na) + ccgy .* ((FZT_r-FZT0)./(FZT0)))); Fyw=-(FYT_l+FYT_r); Fx = Fxw .* cos(delta) - Fyw .* sin(delta); Fy = Fxw .* sin(delta) + Fyw .* cos(delta) - sin(inclination) * Fz; // Kinematic constraints in couplings for i in 1:nu-1 loop vx[i+1] = vx[i] * cos(theta[i]) - (vys[i] + Bcog[i] * wz[i] + (hC[i] - hRC[i]) * wx[i]) * sin(theta[i]); vys[i+1] + Acog[i+1] * wz[i+1] + (hC[i] - hRC[i+1]) * wx[i+1] = (vys[i] + Bcog[i] * wz[i] + (hC[i] - hRC[i]) * wx[i]) * cos(theta[i]) + vx[i] * sin(theta[i]); end for; // Equilibrium, Longitudinal, Lateral and Yaw m .* (d_vx - vys .* wz) = vector(Fx * ones(na,1) - [matrix(Fcx);0] + [0;matrix(Fcx)] .* cos([0;matrix(theta)]) - [0;matrix(Fcy)] .* sin([0;matrix(theta)])); m .* (d_vys + vx .* wz) = vector(Fy * ones(na,1) - [matrix(Fcy);0] + [0;matrix(Fcx)] .* sin([0;matrix(theta)]) + [0;matrix(Fcy)] .* cos([0;matrix(theta)])); Iz .* d_wz = vector(Lcog .* Fy * ones(na,1) - matrix(Bcog) .* [matrix(Fcy);0] + matrix(Acog) .* ([0;matrix(Fcx)] .* sin([0;matrix(theta)]) + [0;matrix(Fcy)] .* cos([0;matrix(theta)]))); d_theta = wz[1:(nu-1)] - wz[2:nu]; // Axle global positions der(pz) = wz; der(rx) = matrix(vx) * ones(1,na) .* (cos(matrix(pz)) * ones(1,na)) - (matrix(vys) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) .* (sin(matrix(pz)) * ones(1,na)); der(ry) = matrix(vx) * ones(1,na) .* (sin(matrix(pz)) * ones(1,na)) + (matrix(vys) * ones(1,na) + Lcog .* (matrix(wz) * ones(1,na))) .* (cos(matrix(pz)) * ones(1,na)); /* Roll dynamics */ // Derivatives d_px = der(px); d_wx = der(wx); d_Mxs = der(Mxs); // Roll dynamics Mxs + Mxd = vector(matrix(Mx) + Fy * ones(na,1) .* matrix(hRC)); d_px = wx; vyu = vector(matrix(vys) + matrix(wx) .* (matrix(h) - matrix(hRC))); Ix .* d_wx = vector(matrix(Mx) + Fy * ones(na,1) .* matrix(h) + matrix(m) .* matrix(fill(9.81, nu, 1)) .* matrix(h - hRC) .* matrix(px) + matrix([Fcy;0]) .* (matrix(h) - matrix([hC;0])) + matrix([0; sin(theta) .* Fcy + cos(theta) .* Fcx]) .* (matrix(h) - matrix([0;hC]))+matrix([Mxc;0])-matrix([0;Mxc])); d_Mxs = -ksSum .* wx; Mxd = -csSum .* wx; // Roll stiff couplings Delta_px1=[0;matrix(px)]-[matrix(px);0]; Delta_px2=matrix(Delta_px1[2:end-1,1]); Mxc=-Ccr.*vector(der(Delta_px2))-Kcr.*vector(Delta_px2); // Load transfer der(delta_z) + W .* delta_z =ks .* (matrix(px) * ones(1,na)) + cs .* (matrix(d_px) * ones(1,na)) + Fy .* (matrix(h)*ones(1,na)); FzAxleRight=(Fz./2).+delta_z; FzAxleLeft=(Fz./2).-delta_z; FzUnitRight=vector(FzAxleRight*ones(na,1)); FzUnitLeft=vector(FzAxleLeft*ones(na,1)); LoadTransferRatio=(FzUnitRight-FzUnitLeft)./(FzUnitRight+FzUnitLeft); end SingleTrackRollDynamicsNonLinTyre;

OpenPBS.VehicleModels.DirectionInput OpenPBS.VehicleModels.DirectionInput

Single track model with direction of travel at front axle as input

OpenPBS.VehicleModels.DirectionInput

Parameters

TypeNameDefaultDescription
Integernu2 
Integerna3 
VehicleModelparamSet  

Connectors

TypeNameDescription
output RealOutputdelta_out 
input RealInputfront_direction_inDirection of travel at first axle
input RealInputvx_inFirst unit velocity input

Modelica definition

model DirectionInput "Single track model with direction of travel at front axle as input" parameter Integer nu=2; parameter Integer na=3; VehicleModels.SingleTrack vehicle( mode=2, paramSet=paramSet, nu=nu, na=na); Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints; Modelica.Blocks.Interfaces.RealOutput delta_out; Modelica.Blocks.Interfaces.RealInput front_direction_in "Direction of travel at first axle"; Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; Modelica.Blocks.Math.Atan2 headingAngle; Components.MotionOffset motionOffset(y_offset=-paramSet.W[1, 1]/2, x_offset=vehicle.Lcog[1, 1]); parameter VehicleParameters.Base.VehicleModel paramSet; Modelica.Blocks.Sources.RealExpression realExpression2(y=vehicle.pz[1]); Modelica.Blocks.Math.Add add; equation connect(vehicle.delta_in, inverseBlockConstraints.y2); connect(inverseBlockConstraints.u1, front_direction_in); connect(vehicle.vx_in, vx_in); connect(inverseBlockConstraints.y1, delta_out); connect(vehicle.vx_out[1], motionOffset.vx); connect(vehicle.vy_out[1], motionOffset.vy); connect(vehicle.wz_out[1], motionOffset.wz); connect(motionOffset.vy_offset, headingAngle.u1); connect(motionOffset.vx_offset, headingAngle.u2); connect(add.u1, headingAngle.y); connect(add.u2, realExpression2.y); connect(add.y, inverseBlockConstraints.u2); end DirectionInput;

OpenPBS.VehicleModels.DirectionInput_SaturatedTyre OpenPBS.VehicleModels.DirectionInput_SaturatedTyre

Single track model with direction of travel at front axle as input

OpenPBS.VehicleModels.DirectionInput_SaturatedTyre

Parameters

TypeNameDefaultDescription
Integernu2 
Integerna3 
Realmu Friction coefficient
VehicleModelparamSet  

Connectors

TypeNameDescription
output RealOutputdelta_out 
input RealInputfront_direction_inDirection of travel at first axle
input RealInputvx_inFirst unit velocity input

Modelica definition

model DirectionInput_SaturatedTyre "Single track model with direction of travel at front axle as input" parameter Integer nu=2; parameter Integer na=3; parameter Real mu "Friction coefficient"; SingleTrack_SaturatedTyre vehicle( mode=2, paramSet=paramSet, nu=nu, na=na, mu=mu); Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints; Modelica.Blocks.Interfaces.RealOutput delta_out; Modelica.Blocks.Interfaces.RealInput front_direction_in "Direction of travel at first axle"; Modelica.Blocks.Interfaces.RealInput vx_in "First unit velocity input"; Modelica.Blocks.Math.Atan2 headingAngle; Components.MotionOffset motionOffset(y_offset=-paramSet.w[1, 1]/2, x_offset=vehicle.Lcog[1, 1]); parameter VehicleParameters.Base.VehicleModel paramSet; Modelica.Blocks.Sources.RealExpression realExpression2(y=vehicle.pz[1]); Modelica.Blocks.Math.Add add; equation connect(vehicle.delta_in, inverseBlockConstraints.y2); connect(inverseBlockConstraints.u1, front_direction_in); connect(vehicle.vx_in, vx_in); connect(inverseBlockConstraints.y1, delta_out); connect(vehicle.vx_out[1], motionOffset.vx); connect(vehicle.vy_out[1], motionOffset.vy); connect(vehicle.wz_out[1], motionOffset.wz); connect(motionOffset.vy_offset, headingAngle.u1); connect(motionOffset.vx_offset, headingAngle.u2); connect(add.u1, headingAngle.y); connect(add.u2, realExpression2.y); connect(add.y, inverseBlockConstraints.u2); end DirectionInput_SaturatedTyre;

OpenPBS.VehicleModels.CurvatureInput OpenPBS.VehicleModels.CurvatureInput

Steady-state curve

OpenPBS.VehicleModels.CurvatureInput

Parameters

TypeNameDefaultDescription
Integernu2 
Integerna3 
VehicleModelparamSet  

Connectors

TypeNameDescription
input RealInputcurvature_in 
input RealInputvx_in 
output RealOutputcurvature_out[nu, na]Curvature per axle
output RealOutputdelta_outFront steer angle

Modelica definition

model CurvatureInput "Steady-state curve" parameter Integer nu=2; parameter Integer na=3; Modelica.Blocks.Interfaces.RealInput curvature_in; Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints; SingleTrack vehicle(paramSet=paramSet, theta(start=ones(nu - 1)*0.001), wz(start=ones(nu)*0.001), vy(start=ones(nu)*0.001), mode=3, alpha(start=-0.001*ones(nu, na)), Fcx(start=ones(nu - 1)*1000), Fcy(start=ones(nu - 1)*10000)); Modelica.Blocks.Interfaces.RealInput vx_in; Manoeuvres.Blocks.Curvature curvature( nu=paramSet.nu, na=paramSet.na, Lcog=vehicle.Lcog); Modelica.Blocks.Interfaces.RealOutput curvature_out[nu,na] "Curvature per axle"; parameter VehicleParameters.Base.VehicleModel paramSet; Modelica.Blocks.Interfaces.RealOutput delta_out "Front steer angle"; equation connect(vehicle.vx_out,curvature. vx); connect(vehicle.vy_out,curvature. vy); connect(vehicle.wz_out,curvature. wz); connect(curvature.y[1, 1],inverseBlockConstraints. u2); connect(curvature_in, inverseBlockConstraints.u1); connect(vx_in, vehicle.vx_in); connect(curvature.y, curvature_out); connect(inverseBlockConstraints.y1, delta_out); // connect(inverseBlockConstraints.y2, vehicle.delta_in[1, 1]) annotation ( // Line(points={{28.4,40},{22,40},{22,6},{34,6},{34,-1},{28,-1}}, color={0, // 0,127})); connect(inverseBlockConstraints.y2, vehicle.delta_in); end CurvatureInput;

OpenPBS.VehicleModels.VerticalForces

Parameters

TypeNameDefaultDescription
VehicleModelparamSet  
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
ForceFz[nu, na]paramSet.Fz[N]
Booleanrfc[nu - 1]paramSet.rfcDefines roll-free coupling
Massmk[nu]paramSet.mkKerb masses [kg]
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 

Modelica definition

model VerticalForces constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n; parameter OpenPBS.VehicleParameters.Base.VehicleModel paramSet; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; parameter Boolean[nu-1] rfc=paramSet.rfc "Defines roll-free coupling"; parameter Modelica.SIunits.Mass[nu] mk=paramSet.mk "Kerb masses"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Integer[nu,na] axlegroups=paramSet.axlegroups; Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X; Modelica.SIunits.Length[nu] Acog = A-X; Modelica.SIunits.Force[nu-1] Fcz "Vertical force at couplings"; Modelica.SIunits.Mass[nu] ml "Load masses"; Modelica.SIunits.Mass[nu] m; Modelica.SIunits.Length[nu] X; equation // Calculate load masses ml for i in 1:nu loop if i==1 and rfc[i]==true then ml[i]+mk[i]=sum(Fz[i,:])/g "Rigid Truck"; if rfc[i+1]==false then ml[i+1]=0 "Dolly"; ml[i+2]+sum(mk[i+1:i+2])=sum(Fz[i+1:i+2,:])/g "Semitrailer"; // "Nordic combination" elseif rfc[i+1]==true then ml[i+1]+mk[i+1]=sum(Fz[i+1,:])/g "CAT"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "DoubleCAT" else ml[i]=0; end if; elseif i==1 and rfc[i]==false then ml[i]=0 "Tractor"; if rfc[i+1]==false then ml[i+1]+sum(mk)+ml[i+2]=sum(Fz)/g "Link-trailer"; ml[i+2]=(42000-mk[i+2])/(15600-1500)*(Fcz[i+1]/g-1500) "Based on assumptions, that when semi is empty, the coupling force is 1500*g and when fully loaded, coupling force is 15600*g. Max gross weight for 3-axle semitrailer: 42000 kg"; // "B-double" elseif rfc[i+1]==true and nu==3 then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "Tractor-semitrailer-CAT" elseif rfc[i+1]==true and rfc[i+2]==false then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]=0 "Dolly"; ml[i+3]+sum(mk[i+2:i+3])=sum(Fz[i+2:i+3,:])/g "Semitrailer"; // "A-double" elseif nu==2 then ml[2]+sum(mk)=sum(Fz)/g "Semitrailer"; else ml[i]=0; end if; end if; end for; for i in 1:nu loop // Calculate total masses m m[i]=mk[i]+ml[i]; // Solve Fcz and X // if i<nu then // Fcz[i]-sum(Fz[i,:])-Fcz[i-1]=-(ml[i]+mk[i])*Modelica.Constants.g_n; // (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i]-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; // else // (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i])/(m[i]*Modelica.Constants.g_n)=X[i]; // end if; if i ==1 then Fcz[i]-sum(Fz[i,:])=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; elseif i>1 and i<nu then Fcz[i]-sum(Fz[i,:])-Fcz[i-1]=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i]-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; else (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i])/(m[i]*Modelica.Constants.g_n)=X[i]; end if; end for; end VerticalForces;

OpenPBS.VehicleModels.VerticalForcesRollDynamics

Parameters

TypeNameDefaultDescription
VehicleModelRollDynamicsparamSet  
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
ForceFz[nu, na]paramSet.Fz[N]
Booleanrfc[nu - 1]paramSet.rfcDefines roll-free coupling
Massmk[nu]paramSet.mkKerb masses [kg]
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 

Modelica definition

model VerticalForcesRollDynamics constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n; parameter OpenPBS.VehicleParameters.Base.VehicleModelRollDynamics paramSet; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; parameter Boolean[nu-1] rfc=paramSet.rfc "Defines roll-free coupling"; parameter Modelica.SIunits.Mass[nu] mk=paramSet.mk "Kerb masses"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Integer[nu,na] axlegroups=paramSet.axlegroups; Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X; Modelica.SIunits.Length[nu] Acog = A-X; Modelica.SIunits.Force[nu-1] Fcz "Vertical force at couplings"; Modelica.SIunits.Mass[nu] ml "Load masses"; Modelica.SIunits.Mass[nu] m; Modelica.SIunits.Length[nu] X; equation // Calculate load masses ml for i in 1:nu loop if i==1 and rfc[i]==true then ml[i]+mk[i]=sum(Fz[i,:])/g "Rigid Truck"; if rfc[i+1]==false then ml[i+1]=0 "Dolly"; ml[i+2]+sum(mk[i+1:i+2])=sum(Fz[i+1:i+2,:])/g "Semitrailer"; // "Nordic combination" elseif rfc[i+1]==true then ml[i+1]+mk[i+1]=sum(Fz[i+1,:])/g "CAT"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "DoubleCAT" else ml[i]=0; end if; elseif i==1 and rfc[i]==false then ml[i]=0 "Tractor"; if rfc[i+1]==false then ml[i+1]+sum(mk)+ml[i+2]=sum(Fz)/g "Link-trailer"; ml[i+2]=(42000-mk[i+2])/(15600-1500)*(Fcz[i+1]/g-1500) "Based on assumptions, that when semi is empty, the coupling force is 1500*g and when fully loaded, coupling force is 15600*g. Max gross weight for 3-axle semitrailer: 42000 kg"; // "B-double" elseif rfc[i+1]==true and nu==3 then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "Tractor-semitrailer-CAT" elseif rfc[i+1]==true and rfc[i+2]==false then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]=0 "Dolly"; ml[i+3]+sum(mk[i+2:i+3])=sum(Fz[i+2:i+3,:])/g "Semitrailer"; // "A-double" else ml[i]=0; end if; end if; end for; for i in 1:nu loop // Calculate total masses m m[i]=mk[i]+ml[i]; // Solve Fcz and X // if i<nu then // Fcz[i]-sum(Fz[i,:])-Fcz[i-1]=-(ml[i]+mk[i])*Modelica.Constants.g_n; // (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i]-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; // else // (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i])/(m[i]*Modelica.Constants.g_n)=X[i]; // end if; if i ==1 then Fcz[i]-sum(Fz[i,:])=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; elseif i>1 and i<nu then Fcz[i]-sum(Fz[i,:])-Fcz[i-1]=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i]-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; else (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i])/(m[i]*Modelica.Constants.g_n)=X[i]; end if; end for; end VerticalForcesRollDynamics;

OpenPBS.VehicleModels.VerticalForcesRollDynamicsNonLinTyre

Parameters

TypeNameDefaultDescription
VehicleModelRollDynamicsNonLinTyreparamSet  
IntegernuparamSet.nuNumber of units
IntegernaparamSet.naMax number of axles per unit
ForceFz[nu, na]paramSet.Fz[N]
Booleanrfc[nu - 1]paramSet.rfcDefines roll-free coupling
Massmk[nu]paramSet.mkKerb masses [kg]
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 

Modelica definition

model VerticalForcesRollDynamicsNonLinTyre constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n; parameter OpenPBS.VehicleParameters.Base.VehicleModelRollDynamicsNonLinTyre paramSet; parameter Integer nu=paramSet.nu "Number of units"; parameter Integer na=paramSet.na "Max number of axles per unit"; parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; parameter Boolean[nu-1] rfc=paramSet.rfc "Defines roll-free coupling"; parameter Modelica.SIunits.Mass[nu] mk=paramSet.mk "Kerb masses"; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Integer[nu,na] axlegroups=paramSet.axlegroups; Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X; Modelica.SIunits.Length[nu] Acog = A-X; Modelica.SIunits.Force[nu-1] Fcz "Vertical force at couplings"; Modelica.SIunits.Mass[nu] ml "Load masses"; Modelica.SIunits.Mass[nu] m; Modelica.SIunits.Length[nu] X; equation // Calculate load masses ml for i in 1:nu loop if i==1 and rfc[i]==true then ml[i]+mk[i]=sum(Fz[i,:])/g "Rigid Truck"; if rfc[i+1]==false then ml[i+1]=0 "Dolly"; ml[i+2]+sum(mk[i+1:i+2])=sum(Fz[i+1:i+2,:])/g "Semitrailer"; // "Nordic combination" elseif rfc[i+1]==true then ml[i+1]+mk[i+1]=sum(Fz[i+1,:])/g "CAT"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "DoubleCAT" else ml[i]=0; end if; elseif i==1 and rfc[i]==false then ml[i]=0 "Tractor"; if rfc[i+1]==false then ml[i+1]+sum(mk)+ml[i+2]=sum(Fz)/g "Link-trailer"; ml[i+2]=(42000-mk[i+2])/(15600-1500)*(Fcz[i+1]/g-1500) "Based on assumptions, that when semi is empty, the coupling force is 1500*g and when fully loaded, coupling force is 15600*g. Max gross weight for 3-axle semitrailer: 42000 kg"; // "B-double" elseif rfc[i+1]==true and nu==3 then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]+mk[i+2]=sum(Fz[i+2,:])/g "CAT"; // "Tractor-semitrailer-CAT" elseif rfc[i+1]==true and rfc[i+2]==false then ml[i+1]+sum(mk[i:i+1])=sum(Fz[i:i+1,:])/g "Semitrailer"; ml[i+2]=0 "Dolly"; ml[i+3]+sum(mk[i+2:i+3])=sum(Fz[i+2:i+3,:])/g "Semitrailer"; // "A-double" else ml[i]=0; end if; end if; end for; for i in 1:nu loop // Calculate total masses m m[i]=mk[i]+ml[i]; // Solve Fcz and X if i ==1 then Fcz[i]-sum(Fz[i,:])=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; elseif i>1 and i<nu then Fcz[i]-sum(Fz[i,:])-Fcz[i-1]=-(ml[i]+mk[i])*Modelica.Constants.g_n; (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i]-Fcz[i].*B[i])/(m[i]*Modelica.Constants.g_n)=X[i]; else (sum(Fz[i,1:na].*L[i,1:na])+Fcz[i-1].*A[i])/(m[i]*Modelica.Constants.g_n)=X[i]; end if; end for; end VerticalForcesRollDynamicsNonLinTyre;

OpenPBS.VehicleModels.Roll OpenPBS.VehicleModels.Roll


OpenPBS.VehicleModels.Roll

Information

This is a test. a = b/c

Parameters

TypeNameDefaultDescription
Adouble6x4_RollDynamics_NonLinTyreparamSetredeclare parameter VehicleP... 
IntegernuparamSet.nu 
IntegernaparamSet.na 
ForceFz[nu, na]paramSet.Fz[N]
Integeraxlegroups[nu, na]paramSet.axlegroups 
Positionh[nu]paramSet.h[m]
PositionhRC[nu]paramSet.hRC[m]
LengthFOH[nu]paramSet.FOH[m]
LengthROH[nu]paramSet.ROH[m]
TranslationalSpringConstantks[nu, na]paramSet.ks[N/m]
RealKcr[nu - 1]paramSet.Kcr 
Booleandriven[nu, na]paramSet.driven 
TranslationalSpringConstantCZT[nu, na]paramSet.CZT Tyre vertical stiffness [N/m]
TranslationalSpringConstantCYT[nu, na]paramSet.CYT Tyre lateral stiffness [N/m]
LengthWe[nu, na]paramSet.WeEffective track width [m]
Booleanrfc[nu - 1]paramSet.rfcDefines roll-rigid couplings
Integernrc1 + Modelica.Math.BooleanVec...Number of roll-free coupled units

Connectors

TypeNameDescription
output RealOutputSRT_out1 
output RealOutputSRT_out2 
output RealOutputSRT_out3 

Modelica definition

model Roll replaceable parameter VehicleParameters.Vehicles.Adouble6x4_RollDynamics_NonLinTyre paramSet constrainedby VehicleParameters.Base.VehicleModelRollDynamicsNonLinTyre; constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n; OpenPBS.VehicleModels.VerticalForcesRollDynamicsNonLinTyre verticalForcesRollDynamicsNonLinTyre(nu=nu,na=na,paramSet=paramSet); Modelica.Blocks.Interfaces.RealOutput SRT_out1=SRT[1]; Modelica.Blocks.Interfaces.RealOutput SRT_out2=SRT[2]; Modelica.Blocks.Interfaces.RealOutput SRT_out3=SRT[3]; // Parameters parameter Integer nu = paramSet.nu; parameter Integer na = paramSet.na; parameter Modelica.SIunits.Force[nu,na] Fz = paramSet.Fz; parameter Integer[nu,na] axlegroups = paramSet.axlegroups; parameter Modelica.SIunits.Position[nu] h = paramSet.h; parameter Modelica.SIunits.Position[nu] hRC = paramSet.hRC; parameter Modelica.SIunits.Length[nu] FOH = paramSet.FOH; parameter Modelica.SIunits.Length[nu] ROH = paramSet.ROH; parameter Modelica.SIunits.TranslationalSpringConstant[nu, na] ks = paramSet.ks; parameter Real[nu-1] Kcr = paramSet.Kcr; parameter Boolean[nu,na] driven=paramSet.driven; Modelica.SIunits.Force[nu-1] Fcz=verticalForcesRollDynamicsNonLinTyre.Fcz; Modelica.SIunits.Mass[nu] m=verticalForcesRollDynamicsNonLinTyre.m; Modelica.SIunits.Mass[nu] ml=verticalForcesRollDynamicsNonLinTyre.ml; // Added parameters for SRT parameter Modelica.SIunits.TranslationalSpringConstant[nu, na] CZT=paramSet.CZT " Tyre vertical stiffness "; parameter Modelica.SIunits.TranslationalSpringConstant[nu, na] CYT=paramSet.CYT " Tyre lateral stiffness "; parameter Modelica.SIunits.Length[nu,na] We = paramSet.We "Effective track width"; parameter Boolean[nu-1] rfc = paramSet.rfc "Defines roll-rigid couplings"; parameter Integer nrc=1+Modelica.Math.BooleanVectors.countTrue(rfc) "Number of roll-free coupled units"; // Variables Modelica.SIunits.TranslationalSpringConstant[nu, na] kes " Equivalent suspension roll stiffness per axle "; Modelica.SIunits.TranslationalSpringConstant[nu, na] kt " The roll stiffness from the tyre normal stiffness "; Modelica.SIunits.TranslationalSpringConstant[nu, na] k "The roll stiffness of axle "; Modelica.SIunits.TranslationalSpringConstant[nrc] kv "The vehicle roll stiffness"; Modelica.SIunits.TranslationalSpringConstant[nrc] CYTe " The vehicle effective tyre lateral stiffness"; Modelica.SIunits.Position[nrc] Wev "The effective track width"; Modelica.SIunits.TranslationalSpringConstant[nu-1] kfw "The roll stiffness of the 5th wheel "; Modelica.SIunits.Acceleration[nu, na] ayl " Lateral acceleration at which the first wheel lift off happens "; Modelica.SIunits.Acceleration[nrc] aym " Maximum theoretical lateral acceleration "; Modelica.SIunits.Acceleration[nu, na] aSRT " Steady-state rollover threshold "; Modelica.SIunits.Acceleration[nrc] SRT; Real[nu, na] DK "The distribution of the vehicle roll stiffness "; Modelica.SIunits.Position[nrc] hCG "CoG height for roll-free units"; Modelica.SIunits.Position[nrc] hS "Sprung mass CoG height for roll-free units"; Integer[nu, na] axles "Number of axles, used for Wev calculations"; Integer dbl "Defines which coupling is a drawbar coupling"; Modelica.SIunits.Position[nu] hs " Sprung mass CoG height "; Modelica.SIunits.Force[nu] Fu "Unsprung masses*g for each unit"; Modelica.SIunits.Force[nu,na] ma "Unsprung masses for each axle"; equation kfw=4*Fcz; dbl=Modelica.Math.Vectors.find(0.0,Kcr,eps=0.001); hs=(h.*m-Fu./g.*hRC)./(m-Fu./g); // DoubleCAT, each unit calculated separately if nrc==3 then for i in 1:nrc loop SRT[i]=min(aSRT[i,:]); kv[i]=sum(k[i,:]); CYTe[i]=sum(CYT[i,:]); Wev[i]=sum(We[i,:].*Fz[i,:])/sum(Fz[i,:]); hS[i]=hs[i]; hCG[i]=h[i]; Fu[i]=sum(ma[i,:])*g; aym[i]=0.5*sum(Fz[i,:]).*Wev[i]./((sum(Fz[i,:]).*hCG[i])+(((sum(Fz[i,:])-Fu[i]).*hS[i]).^2 ./(kv[i]-(sum(Fz[i,:]).*hS[i])))+sum(Fz[i,:]).^2 ./CYTe[i]); for j in 1:na loop kes[i,j]=ks[i,j].*(hS[i]./(hS[i]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j].^2)/2; k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); DK[i,j]=k[i,j]./kv[i]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[i,:]).*hCG[i])+(((sum(Fz[i,:])-Fu[i]).*DK[i,j].*hS[i]).^2 ./(k[i,j]-(sum(Fz[i,:]).*DK[i,j].*hS[i])))+Fz[i,j].^2 ./(CYT[i,j])); aSRT[i,j]=(aym[i]-(aym[i]-ayl[i,j]).*(Fz[i,j]./sum(Fz[i,:])))*Modelica.Constants.g_n; end for; end for; // Nordic, 5th wheel roll stiffness neglegted elseif nrc==2 and rfc[1]==true then SRT={min(aSRT[1:dbl,:]),min(aSRT[dbl+1:nu,:])}; kv={sum(k[1:dbl,:]),sum(k[dbl+1:nu,:])}; CYTe={sum(CYT[1:dbl,:]),sum(CYT[dbl+1:nu,:])}; Wev={sum(We[1:dbl,:].*Fz[1:dbl,:])./sum(Fz[1:dbl,:]), sum(We[dbl+1:nu,:].*Fz[dbl+1:nu,:])./sum(Fz[dbl+1:nu,:])}; hCG={sum(h[1:dbl].*m[1:dbl])./sum(m[1:dbl]),sum(h[dbl+1:nu].*m[dbl+1:nu])/sum(m[dbl+1:nu])}; hS={sum(hs[1:dbl].*m[1:dbl])./sum(m[1:dbl]),sum(hs[dbl+1:nu].*m[dbl+1:nu])/sum(m[dbl+1:nu])}; aym={0.5*sum(Fz[1:dbl,:]).*Wev[1]./((sum(Fz[1:dbl,:]).*hCG[1])+(((sum(Fz[1:dbl,:])-sum(Fu[1:dbl])).*hS[1])^2/(kv[1]-(sum(Fz[1:dbl,:]).*hS[1])))+sum(Fz[1:dbl,:])^2/CYTe[1]), 0.5*sum(Fz[dbl+1:nu,:]).*Wev[2]./((sum(Fz[dbl+1:nu,:]).*hCG[2])+(((sum(Fz[dbl+1:nu,:])-sum(Fu[dbl+1:nu])).*hS[2])^2/(kv[2]-(sum(Fz[dbl+1:nu,:]).*hS[2])))+sum(Fz[dbl+1:nu,:])^2/CYTe[2])}; for i in 1:nu loop Fu[i]=sum(ma[i,:])*g; for j in 1:na loop if i<=dbl then kes[i,j]=ks[i,j].*(hS[1]./(hS[1]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j].^2)/2; k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); DK[i,j]=k[i,j]./kv[1]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[1:dbl,:]).*hCG[1])+(((sum(Fz[1:dbl,:])-sum(Fu[1:dbl])).*DK[i,j].*hS[1]).^2 ./(k[i,j]-(sum(Fz[1:dbl,:]).*DK[i,j].*hS[1])))+Fz[i,j].^2 ./(CYT[i,j])); aSRT[i,j]=(aym[1]-(aym[1]-ayl[i,j]).*(Fz[i,j]./sum(Fz[1:dbl,:])))*Modelica.Constants.g_n; else kes[i,j]=ks[i,j].*(hS[nrc]./(hS[nrc]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j]^2)/2; k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); DK[i,j]=k[i,j]./kv[nrc]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[dbl+1:nu,:]).*hCG[nrc])+(((sum(Fz[dbl+1:nu,:])-sum(Fu[dbl+1:nu])).*DK[i,j].*hS[nrc]).^2/(k[i,j]-(sum(Fz[dbl+1:nu,:]).*DK[i,j].*hS[nrc])))+Fz[i,j].^2/(CYT[i,j])); aSRT[i,j]=(aym[nrc]-(aym[nrc]-ayl[i,j]).*(Fz[i,j]./sum(Fz[dbl+1:nu,:])))*Modelica.Constants.g_n; end if; end for; end for; // Adouble and Tractor-Semi-CAT elseif nrc==2 and rfc[1]==false then SRT={min(aSRT[2,:]),min(aSRT[dbl+1:nu,:])}; kv={sum(k[2,:])+(kfw[1]),sum(k[dbl+1:nu,:])}; CYTe={sum(CYT[2,:]),sum(CYT[dbl+1:nu,:])}; Wev={(sum(We[2,:].*Fz[2,:])+sum(We[1,:])./sum(axles[1,:]).*(Fcz[1]))./(sum(Fz[2,:])+(Fcz[1])), sum(We[dbl+1:nu,:].*Fz[dbl+1:nu,:])./sum(Fz[dbl+1:nu,:])}; hCG={h[2],sum(h[dbl+1:nu].*m[dbl+1:nu])/sum(m[dbl+1:nu])}; hS={hs[2],sum(hs[dbl+1:nu].*m[dbl+1:nu])/sum(m[dbl+1:nu])}; aym={0.5*sum(Fz[2,:]).*Wev[1]./((sum(Fz[2,:]).*hCG[1])+(((sum(Fz[2,:])-Fu[2]).*hS[1])^2/(kv[1]-(sum(Fz[2,:]).*hS[1])))+sum(Fz[2,:])^2/CYTe[1]), 0.5*sum(Fz[dbl+1:nu,:]).*Wev[2]./((sum(Fz[dbl+1:nu,:]).*hCG[2])+(((sum(Fz[dbl+1:nu,:])-sum(Fu[dbl+1:nu])).*hS[2])^2/(kv[2]-(sum(Fz[dbl+1:nu,:]).*hS[2])))+sum(Fz[dbl+1:nu,:])^2/CYTe[2])}; for i in 1:nu loop Fu[i]=sum(ma[i,:])*g; for j in 1:na loop if i<=dbl then kes[i,j]=ks[i,j].*(hS[1]./(hS[1]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j].^2)/2; DK[i,j]=k[i,j]./kv[1]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[2,:]).*hCG[1])+(((sum(Fz[2,:])-Fu[2]).*DK[i,j].*hS[1]).^2 ./(k[i,j]-(sum(Fz[2,:]).*DK[i,j].*hS[1])))+Fz[i,j].^2 ./(CYT[i,j])); aSRT[i,j]=(aym[1]-(aym[1]-ayl[i,j]).*(Fz[i,j]./sum(Fz[2,:])))*Modelica.Constants.g_n; if i==1 then k[i,j]=kfw[1]/sum(axles[1,:]); else k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); end if; else kes[i,j]=ks[i,j].*(hS[nrc]./(hS[nrc]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j]^2)/2; k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); DK[i,j]=k[i,j]./kv[nrc]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[dbl+1:nu,:]).*hCG[nrc])+(((sum(Fz[dbl+1:nu,:])-sum(Fu[dbl+1:nu])).*DK[i,j].*hS[nrc]).^2/(k[i,j]-(sum(Fz[dbl+1:nu,:]).*DK[i,j].*hS[nrc])))+Fz[i,j].^2/(CYT[i,j])); aSRT[i,j]=(aym[nrc]-(aym[nrc]-ayl[i,j]).*(Fz[i,j]./sum(Fz[dbl+1:nu,:])))*Modelica.Constants.g_n; end if; end for; end for; // B-double, considered link-semi as a one unit and tractor replaced with a 5th wheel roll stiffness, also tractor-semi elseif nrc==1 then SRT[1]=min(aSRT[2:nu]); kv[1]=sum(k[2:nu,:])+kfw[1]; CYTe[1]=sum(CYT[2:nu,:]); aym=0.5*sum(Fz[2:nu,:]).*Wev./((sum(Fz[2:nu,:]).*hCG)+(((sum(Fz[2:nu,:])-sum(Fu[2:nu])).*hS).^2 ./(kv-(sum(Fz[2:nu,:]).*hS)))+sum(Fz[2:nu,:]).^2 ./CYTe); Wev[1]=(sum(We[2:nu,:].*Fz[2:nu,:])+sum(We[1])./sum(axles[1]).*(Fcz[1]))./(sum(Fz[2:nu,:])+Fcz[1]); hCG[1]=sum(h[2:nu].*m[2:nu])/sum(m[2:nu]); hS[1]=sum(hs[2:nu].*m[2:nu])/sum(m[2:nu]); for i in 1:nu loop Fu[i]=sum(ma[i,:])*g; for j in 1:na loop kes[i,j]=ks[i,j].*(hS[1]./(hS[1]-hRC[i]))^2; kt[i,j]=CZT[i,j].*(We[i,j]^2)/2; DK[i,j]=k[i,j]./kv[nrc]; ayl[i,j]=0.5*Fz[i,j].*We[i,j]./((DK[i,j].*sum(Fz[2:nu,:]).*hCG[nrc])+(((sum(Fz[2:nu,:])-sum(Fu[2:nu])).*DK[i,j].*hS[nrc]).^2/(k[i,j]-(sum(Fz[2:nu,:]).*DK[i,j].*hS[nrc])))+Fz[i,j].^2/(CYT[i,j])); aSRT[i,j]=(aym[1]-(aym[1]-ayl[i,j]).*(Fz[i,j]./sum(Fz[2:nu,:])))*Modelica.Constants.g_n; k[i,j]=(kes[i,j].*kt[i,j])./(kes[i,j]+kt[i,j]); end for; end for; end if; for i in 1:nu loop for j in 1:na loop if axlegroups[i,j]==0 then axles[i,j]=0; else axles[i,j]=1; end if; end for; end for; for i in 1:nu loop for j in 1:na loop if driven[i,j]==true then ma[i,j]=1300; elseif i==1 and CZT[i,j]>1300000 and driven[i,j]==false then ma[i,j]=900; else if CZT[i,j]>1300000 then ma[i,j]=800; elseif 0<CZT[i,j] and CZT[i,j]<=1300000 then ma[i,j]=700; else ma[i,j]=0; end if; end if; end for; end for; end Roll;

OpenPBS.VehicleModels.Longitudinal


OpenPBS.VehicleModels.Longitudinal

Parameters

TypeNameDefaultDescription
NordicCombinationparamSetredeclare parameter VehicleP... 
Integermode21: Normal, 2: Quasistatic
Velocityvx070/3.6[m/s]
Angleinclination_angle Inclination angle, positive for uphill driving [rad]
IntegernuparamSet.nu 
IntegernaparamSet.na 
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 
Booleandriven[nu, na]paramSet.driven 
Realdrag_coefficientparamSet.drag_coefficient 
Areafrontal_areaparamSet.frontal_area[m2]
Realrolling_resistance_coefficientparamSet.rolling_resistance_...Rolling resistance force as a function of vertical force
Forcemax_thrust_force_vx0paramSet.max_thrust_force_vx0[N]
Powermax_engine_powerparamSet.max_engine_power[W]
Densityair_density1.3[kg/m3]
Integern_drivenModelica.Math.BooleanVectors... 
ForceFz[nu, na]paramSet.Fz[N]

Modelica definition

partial model Longitudinal replaceable parameter VehicleParameters.Vehicles.NordicCombination paramSet constrainedby VehicleParameters.Base.VehicleModelRollDynamicsNonLinTyre; OpenPBS.VehicleModels.VerticalForcesRollDynamicsNonLinTyre verticalForcesRollDynamicsNonLinTyre(nu=nu,na=na,paramSet=paramSet); parameter Integer mode=2 "1: Normal, 2: Quasistatic"; parameter Modelica.SIunits.Velocity vx0=70/3.6; parameter Modelica.SIunits.Angle inclination_angle "Inclination angle, positive for uphill driving"; parameter Integer nu=paramSet.nu; parameter Integer na=paramSet.na; parameter Modelica.SIunits.Length[nu,na] L=paramSet.L "Axle positions relative first axle of each unit"; parameter Modelica.SIunits.Length[nu] A=paramSet.A "Front coupling position relative first axle"; parameter Modelica.SIunits.Length[nu] B=paramSet.B "Rear coupling position relative first axle"; parameter Integer[nu,na] axlegroups=paramSet.axlegroups; parameter Boolean[nu,na] driven=paramSet.driven; parameter Real drag_coefficient=paramSet.drag_coefficient; parameter Modelica.SIunits.Area frontal_area=paramSet.frontal_area; parameter Real rolling_resistance_coefficient=paramSet.rolling_resistance_coefficient "Rolling resistance force as a function of vertical force"; parameter Modelica.SIunits.Force max_thrust_force_vx0=paramSet.max_thrust_force_vx0; parameter Modelica.SIunits.Power max_engine_power=paramSet.max_engine_power; parameter Modelica.SIunits.Density air_density=1.3; /*1.204*/ Modelica.SIunits.Mass[nu] m=verticalForcesRollDynamicsNonLinTyre.m; Modelica.SIunits.Length[nu] X=verticalForcesRollDynamicsNonLinTyre.X "C.g. position relative first axle"; Modelica.SIunits.Length[nu,na] Lcog = L-matrix(X)*ones(1,na) "Axle positions relative c.g."; Modelica.SIunits.Length[nu] Bcog = B-X; Modelica.SIunits.Length[nu] Acog = A-X; final parameter Modelica.SIunits.Position[nu,na] rx0=TM*[0;matrix(B[1:nu-1]-A[2:nu])]*ones(1,na)+L; final parameter Integer TM[nu,nu]=Functions.tril(nu); parameter Integer n_driven=Modelica.Math.BooleanVectors.countTrue(driven[1,:]); parameter Modelica.SIunits.Force[nu,na] Fz=paramSet.Fz; Modelica.SIunits.Acceleration ax[nu]; Modelica.SIunits.Velocity vx[nu]; /* Tire forces */ Modelica.SIunits.Force Fx[nu,na] "Vehicle longitudinal force per axle"; Modelica.SIunits.Force Fxd "Drive force (applied to each driven axle)"; /* Coupling forces */ Modelica.SIunits.Force Fcx[nu-1] "Longitudinal coupling forces"; /* Chassis forces */ Modelica.SIunits.Force Fxa "Aerodynamic force"; /* Derivative variables */ //Modelica.SIunits.Acceleration[nu] d_vx; //Modelica.SIunits.Velocity[nu] d_rx; Modelica.SIunits.Position[nu,na] rx(start=rx0); constant Modelica.SIunits.Force F_eps=Modelica.Constants.eps "Used to avoid division by zero"; Real[nu,na] friction_usage; /*=Fx./max(Fz,Modelica.Constants.eps*ones(nu,na))*/ initial equation vx=vx0*ones(nu); equation // Friction usage for i in 1:nu loop for j in 1:na loop friction_usage[i,j]=Fx[i,j]./(max(Fz[i,j],F_eps)); end for; end for; if mode==1 then der(vx)=ax; else der(vx)=zeros(nu); end if; // d_vx=ax; Fxa = 0.5*air_density*vx[1]^2*drag_coefficient*frontal_area "Aerodynamic drag"; /* Tire force */ for i in 1:nu loop for j in 1:na loop if driven[i,j]==true then Fx[i,j]=Fxd-Fz[i,j]*sin(inclination_angle)-Fz[i,j]*rolling_resistance_coefficient*cos(inclination_angle); else Fx[i,j]=-Fz[i,j]*sin(inclination_angle)-Fz[i,j]*rolling_resistance_coefficient*cos(inclination_angle); end if; end for; end for; /* Kinematic constraints in couplings */ for i in 1:nu-1 loop ax[i+1] = ax[i]; end for; m.*ax=vector(-[matrix(Fxa);zeros(nu-1,1)]+Fx*ones(na,1)-[matrix(Fcx);0]+[0;matrix(Fcx)]); /* Axle global positions */ der(rx)=if mode==1 then matrix(vx)*ones(1,na) else zeros(nu,na); end Longitudinal;

OpenPBS.VehicleModels.LongitudinalAccelerationQS OpenPBS.VehicleModels.LongitudinalAccelerationQS

Use max thrust force distributed on driving axles and solve for the highest inclination angle where the desired acceleration can be achieved

OpenPBS.VehicleModels.LongitudinalAccelerationQS

Information

Extends from Longitudinal.

Parameters

TypeNameDefaultDescription
NordicCombinationparamSetredeclare parameter VehicleP... 
Integermode21: Normal, 2: Quasistatic
Velocityvx00[m/s]
IntegernuparamSet.nu 
IntegernaparamSet.na 
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 
Booleandriven[nu, na]paramSet.driven 
Realdrag_coefficientparamSet.drag_coefficient 
Areafrontal_areaparamSet.frontal_area[m2]
Realrolling_resistance_coefficientparamSet.rolling_resistance_...Rolling resistance force as a function of vertical force
Forcemax_thrust_force_vx0paramSet.max_thrust_force_vx0[N]
Powermax_engine_powerparamSet.max_engine_power[W]
Densityair_density1.3[kg/m3]
Integern_drivenModelica.Math.BooleanVectors... 
ForceFz[nu, na]paramSet.Fz[N]
Accelerationacceleration_demand0.02Required acceleration [m/s2]
Realfriction0.8 
Realeta0.85 Total efficiency of powertrain

Connectors

TypeNameDescription
output RealOutputinclination_out 

Modelica definition

model LongitudinalAccelerationQS "Use max thrust force distributed on driving axles and solve for the highest inclination angle where the desired acceleration can be achieved" extends Longitudinal(mode=2, inclination_angle(fixed=false,start=0),vx0=0); parameter Modelica.SIunits.Acceleration acceleration_demand=0.02 "Required acceleration"; parameter Real friction=0.8; parameter Real eta=0.85 " Total efficiency of powertrain"; Modelica.SIunits.Force max_force=min(limiting_force)*friction; Modelica.Blocks.Interfaces.RealOutput inclination_out=inclination_angle; protected Real limiting_force[nu,na]; initial equation Fxd=min(max_force,min(max_thrust_force_vx0,max_engine_power/max(0.1,vx[1]))/n_driven)*eta; equation for i in 1:nu loop for j in 1:na loop limiting_force[i,j] = if driven[i,j] then Fz[i,j] else 1e10; end for; end for; ax[1]=acceleration_demand; end LongitudinalAccelerationQS;

OpenPBS.VehicleModels.LongitudinalAcceleration OpenPBS.VehicleModels.LongitudinalAcceleration

Use max thrust force distributed on driving axles for dynamic simulation

OpenPBS.VehicleModels.LongitudinalAcceleration

Information

Extends from Longitudinal.

Parameters

TypeNameDefaultDescription
NordicCombinationparamSetredeclare parameter VehicleP... 
Integermode11: Normal, 2: Quasistatic
Velocityvx070/3.6[m/s]
Angleinclination_angle0Inclination angle, positive for uphill driving [rad]
IntegernuparamSet.nu 
IntegernaparamSet.na 
LengthL[nu, na]paramSet.LAxle positions relative first axle of each unit [m]
LengthA[nu]paramSet.AFront coupling position relative first axle [m]
LengthB[nu]paramSet.BRear coupling position relative first axle [m]
Integeraxlegroups[nu, na]paramSet.axlegroups 
Booleandriven[nu, na]paramSet.driven 
Realdrag_coefficientparamSet.drag_coefficient 
Areafrontal_areaparamSet.frontal_area[m2]
Realrolling_resistance_coefficientparamSet.rolling_resistance_...Rolling resistance force as a function of vertical force
Forcemax_thrust_force_vx0paramSet.max_thrust_force_vx0[N]
Powermax_engine_powerparamSet.max_engine_power[W]
Densityair_density1.3[kg/m3]
Integern_drivenModelica.Math.BooleanVectors... 
ForceFz[nu, na]paramSet.Fz[N]
Realfriction0.8 
Realeta0.85 Total efficiency of powertrain

Connectors

TypeNameDescription
output RealOutputs_out 

Modelica definition

model LongitudinalAcceleration "Use max thrust force distributed on driving axles for dynamic simulation" extends Longitudinal(mode=1, inclination_angle=0); parameter Real friction=0.8; parameter Real eta=0.85 " Total efficiency of powertrain"; Modelica.SIunits.Force max_force=min(limiting_force)*friction; Modelica.Blocks.Interfaces.RealOutput s_out=rx[1,1]; protected Real limiting_force[nu,na]; equation Fxd=min(max_force,min(max_thrust_force_vx0,max_engine_power/max(0.1,vx[1]))/n_driven)*eta; for i in 1:nu loop for j in 1:na loop limiting_force[i,j] = if driven[i,j] then Fz[i,j] else 1e10; end for; end for; end LongitudinalAcceleration;

Automatically generated Tue Feb 23 11:57:20 2021.