19. AGX DriveTrain

agxDriveTrain is a library of AGX PowerLine components designed to model the various parts of a vehicle drive train. It deals exclusively with rotational motion, hence all components inherit either from RotationalUnit or from RotationalConnector.

To use components which are part of the PowerLine API one must first create a PowerLine instance to hold the components:

agxPowerLine::PowerLineRef powerLine = new agxPowerLine::PowerLine();
simulation->add(powerLine);

19.1. Shaft

The Shaft is the most basic drive train Unit. It is simply a rotating body that we can connect Connectors to.

agxDriveTrain::ShaftRef shaft1 = new agxDriveTrain::Shaft();
powerLine->add(shaft1);

19.2. Gear

The Gear is the most basic drive train Connector. It is used to transfer rotational motion between the Unit-based drive train components. A Gear is actually the interaction between two geared wheels, one from each connected Unit, and has therefore a gear ratio. The gear ratio define the number of gear teeth on the output shaft to the number on the input shaft. A gear ratio magnitude higher than 1 will cause the output gear to rotate slower than the input shaft, and a gear ratio magnitude lower than 1 will instead cause the output gear to rotate faster than the input shaft. Negative gear ratios make the output shaft rotate in the opposite direction of the input shaft.

\[\omega_{out} = \frac{\omega_{in}}{g}\]

where \(g\) is the gear ratio.

A pair of shafts are connected using code such as the following:

agxDriveTrain::ShaftRef shaft2 = new agxDriveTrain::Shaft();
agxDriveTrain::GearRef gear = new agxDriveTrain::Gear();

powerLine->add(shaft2);
powerLine->add(gear);

gear->setGearRatio(agx::Real(2.0));

shaft1->connect(gear);
gear->connect(shaft2);

With the system created so far, since shaft1 is the input of the gear and shaft2 is the output, whenever shaft1 is rotating, shaft2 will rotate at half the speed.

In addition to the basic Gear, there are other drive train components which have gear-like behavior.

19.2.1. GearBox

A gear box is a gear-like connector that has a collection of gear ratios that it can switch between. It is created from a vector of gear ratios and provides methods for changing the currently selected gear.

agx::RealVector gearRatios;
gearRatios.push_back(agx::Real(10));
gearRatios.push_back(agx::Real(7));
gearRatios.push_back(agx::Real(5));
gearRatios.push_back(agx::Real(3.5));
gearRatios.push_back(agx::Real(2));
gearRatios.push_back(agx::Real(1));
agxDriveTrain::GearBoxRef gearBox = new agxDriveTrain::GearBox(gearRatios);

gearBox->setGear(0);

The above example creates a gear box with six gears with decreasing gear ratios, i.e., increasing output shaft velocity, and set the current gear to the first one.

19.2.2. SlipGear

A gear with a configurable compliance. Increasing the compliance will cause the gear to slip more under load.

19.2.3. HolonomicGear

A regular Gear uses a nonholonomic constraint to maintain the velocity relationship, which means that small differences in angle may accumulate over time. The HolonomicGear uses a holonomic constraint instead, which ensures that the two connected shafts never slip.

19.2.4. MultiGear

A gear that allows for multiple connected shafts, each with its own gear ratio. Whenever one of the connected shafts rotate a hidden internal shaft will rotate with a velocity corresponding to the gear ratio configured for that connected shaft. All other connected shafts will then rotate along with the internal shaft with the velocity that corresponds to their respective gear ratio.

A MultiGear only support connections on the output side.

../_images/agxDriveTrain_MultiGear.png

19.2.5. TorqueConverter

The torque converter is a viscous coupling between two rotating axes. When there is a velocity ratio between the incoming shaft and the outgoing there will be a torque multiplication. The incoming shaft rotates a pump which accelerates a fluid. The fluid will accelerate a turbine which is connected to the outgoing shaft.

The torque converter is created simply as:

TorqueConverterRef tc = new TorqueConverter();

When the torque converter is created it is set up with default values, for what should be a generic torque converter. This means that after creating it, it can be connected to the drive train and used directly.

The torque converter contains a lock that can be enabled to lock it so it will have the same input and output velocities.

tc->enableLockUp(true);

This lock should be disabled when switching gear, suddenly increasing velocity or when braking.

19.2.5.1. Torque converter characteristics

The multiplication you get from a specific torque converter depends on the internal construction of the pump and the turbine. The torque converter has two important tables that define its behavior; the geometry factor table and the efficiency table.

The torque needed to rotate the pump is calulated using the geometry factor table, \(\xi(\nu)\), which depends on the velocity ratio between the turbine and the pump: \(\nu = \omega_{t} / \omega_{p}\). The pump torque is calculated as

\[M_{p} = \xi(\nu) \rho d_{p}^{5} \omega_{p}^{2},\]

where \(\rho\) is the fluid density and \(d_{p}\) the pump diameter, parameters that can also be modified to change the torque converter behavior. The geometry factor table can bet set with the following method:

TorqueConverter::setGeometryFactorTable(const agx::RealPairVector& velRatio_geometryFactor);

The efficiency table \(\psi(\nu)\) determines the amplification of the output torque on the turbine side. The torque is calculated as

\[M_{t} = \psi(\nu) M_{p}.\]

The efficiency table can be set using this method:

TorqueConverter::setEfficiencyTable(const agx::RealPairVector& velRatio_efficiency);

19.3. Engine

An engine is a Unit that is a source of power in a drive train. There are three types of engines: torque curve based, fixed velocity based and the combustion engine.

19.3.1. Torque curve engines

Torque curve engines uses a torque curve to determine the maximum available torque for the current RPM and a user controlled throttle to select a fraction of that available torque to actually apply. The Engine class is a torque curve engine. It is used as follows:

agxDriveTrain::EngineRef engine = new agxDriveTrain::Engine();
agxPowerLine::PowerTimeIntegralLookupTable* torqueCurve =
    engine->getPowerGenerator()->getPowerTimeIntegralLookupTable();
torqueCurve->insertValue(rpm0, torque0);
torqueCurve->insertValue(rpm1, torque1);
torqueCurve->insertValue(rpmN, torqueN);
engine->setThrottle(throttle);

Every time step the engine does a lookup into the torque table to find the maximum available torque for the current RPM. It then scales the maximum torque with the current throttle, a value between 0 and 1, to find the torque to apply this time step. The engine uses piecewise linear interpolation for lookups between the inserted values, and extrapolation of the first two or last two values for lookups outside of the torque curve domain.

An Engine has an idle RPM and the power generator has a corresponding minimum torque. When the engine is below the idle RPM, then the power generator will apply at least the minimum torque to reach the idle RPM.

Another torque curve engine is the PidControlledEngine. It inherits from Engine and by default behaves almost the same. The added functionality it provides is an ignition used to start and stop the engine and the ability to control the throttle automatically, for example to maintain a target RPM. Specific throttle controllers are created by inheriting from ThrottleCalculator. Provided with agxDriveTrain is RpmController, which is a PID controller that tries to maintain a target RPM.

engine = new agxDriveTrain::PidControlledEngine();
controller = new agxDriveTrain::RpmController(engine, targetRpm, pGain, dGain, iGain, iRange);
engine->setThrottleCalculator(controller);
engine->ignition(true);
// Don't forget to create the torque curve as well.

Idle RPM works differently for a PidControlledEngine compared to the base Engine. If a ThrottleCalculator has been set then that has full control over the throttle. If a ThrottleCalculator has not been set then the PidControlledEngine will use setGradient to force the engine RPM to reach the idle RPM.

19.3.2. Fixed velocity engine

The fixed velocity engine uses a velocity constraint to maintain the target velocity. This type of engine can be used when the expected velocity of the engine is known and any amount of torque is allowed to reach that velocity.

19.3.3. Combustion engine

Combustion engine [13] is one of the most widely used types of engines in various applications such as vehicles, excavators, wheelloaders, aircrafts and marine propulsion systems. It includes a number of components as shown in Fig. 19.1, such as the cylinders, pistons, crankshaft, camshafts, valves, fuel injection system, ignition system, air intake and exhaust systems. The cylinders and the pistons form the main body of the engine, where the combustion process occurs. The combustion converts the chemical energy of the air-fuel mixture into the heat energy. The heat energy generates the high temperature as well as the high pressure inside the cylinders. The pressure pushes the pistons to move during the power stroke and outputs the torque to rotate the crank shaft. The crank shaft drives the gears in the drive train, which eventually enables the motion of the vehicle. The valves control the flow of air and fuel into and out of the engine cylinders, and the fuel injection and ignition systems manage the combustion process.

../_images/agxDriveTrain_CombustionEngine.png

Fig. 19.1 Combustion engine schematic (source: [13]).

As a critical component of the vehicle, it is important to model the combustion engine accurately since it directly affects the performance of the vehicle, such as the stability, handling, and ride comfort. A detailed engine model can provide information such as the engine speed, torque, power and the fuel consumption. This information is critical for the design and development of efficient power train systems as well as the effective controlling strategies of the vehicle. This contributes to the increasing demands of accurate and efficient combustion engine models.

Modelling of the combustion engine involves the use of mathematical equations that accurately represent the physical behavior of the engine such as the thermodynamics, fluid mechanics, and rotational dynamics. The thermodynamic properties of the air-fuel mixture determine the efficiency and power output of the engine, while the fluid mechanics determine the flow of air and fuel into the combustion chamber. The rotational dynmics are important for modelling the engine’s crankshaft and connecting rods, which convert the linear motion of th pistons into the rotational motion. Depending on the level of details required, the models of combustion engine can be simplified or complex. For instance, in [14], computational fluid dynamics (CFD) method, which solves the partial differential equations, is used to simulate the combustion process. In [15], the dynamic artificial neural networks (ANN) have been employed to develop an engine model with high accuracy.

19.3.3.1. Modelling theory

In AGX Dynamics, the mean value engine model (MVEM) [13] has been implemented to model the combustion engine. It is a simplified time-based model used to predict averaged key engine combustion variables without modeling the detailed physical combustion process. It captures the dominated combustion characteristics averaged over one or several engine cycles.

The governing equations of the MVEM theory are simply just two ordinary differential equations as listed below.

\[\begin{split}\frac{d\!{\ p_{\text{im}}}}{d\!{\ t}} & = \frac{RT_{\text{im}}}{V_{\text{im}}}(\dot{m}_{\text{at}} - \dot{m}_{\text{ac}}) \\ \mathcal{J}\frac{d\!{\ N}}{d\!{\ t}} & = M_{i} - M_{f} - M_{p} - M_{load}\end{split}\]

The first equation is formulated for the development of the intake manifold pressure \(p_{im}\). \(T_ {im}\) refers to intake temperature. \(V_{im}\) is the volume of the intake manifold. \(R\) is the specific gas constant. The mass difference between throttle inflow \(\dot{m}_{\text{at}}\) and cylinder outflow \(\dot{m}_{\text{ac}}\) directly gives the rate of mass change in the intake system. It is worth noting that this differential equation is derived from the ideal gas law \(pV = mRT\).

The second equation is formulated for the rotational dynamics of the engine crankshaft with the moment of inertia \(J\). \(N\) is the rotational speed of the crank shaft. \(M_i\) is the indicated torque, \(M_f\) is the friction torque consumed by the engine components, \(M_{p}\) is the pump torque, \(M_{load}\) is the output torque.

19.3.3.1.1. Throttle mass flow

The throttle air mass flow \(\dot{m}_{at}\) is dependent not only on the motion of the throttle plate but also on the pressure development in the intake manifold. It is expressed as [6],

\[\begin{split}\dot{m}_{\text{at}} & = \frac{p_{\text{amb}}}{\sqrt{RT_{\text{amb}}}}A_{\text{eff}}(\alpha) \Psi_{\text{li}} \left( \Pi \left( \frac{p_{\text{im}}}{p_{\text{amb}}} \right) \right) \\\end{split}\]

where \(T_{\text{amb}}\) and \(p_{\text{amb}}\) are the ambient temperature and pressure, \(A_{\text{eff}}(\alpha)\) is the effective throttle openning area, \({\Psi_{\text{li}} \left( \Pi \left( \frac{p_{\text{im}}}{p_{\text{amb}}} \right) \right)}\) is the flow function. Here, the flow passing through the small throttle area has a large pressure difference, and the gas flow velocity is very high, which can be 70-100m/s. The flow is modelled as isentropic compressible flow.

19.3.3.1.2. Engine mass flow

The cylinder air mass flow \(\dot{m}_{ac}\) depends on the engine speed \(N\), intake pressure \(p_{im}\), and temperature \(T_{im}\). It is expressed as,

\[\begin{split}\dot{m}_{\text{ac}} & = \nu_{\text{vol}}(N,p_{\text{im}},\ldots)\frac{V_{D}Np_{\text{im}}}{n_{r}RT_{\text{im}}} \\\end{split}\]

where the volumetric efficiency \(v_{vol}\) defines the engine’s capability to induct new air into the cylinders. \(v_{vol}\) is defined as [16]

\[\begin{split}\nu_{\text{vol}} & = c_{0} + c_{1}N + c_{2}N^2 + \frac{c_{3}}{p_{\text{im}}}\\\end{split}\]

where, \(c_{0}\), \(c_{1}\), \(c_{2}\), \(c_{3}\) are pressure- and engine-speed-related coefficients.

19.3.3.1.3. Engine torques

The indicated torque \(M_{i}\), the friction torque \(M_f\) and the pump torque \(M_p\) are calcualted as

\[\begin{split}M_{i} & = \frac{\dot{m}_{f}Q_{hv}\eta_{t}}{N} = \frac{\dot{m}_{ac}Q_{hv}\eta_{t}}{AF \cdot N} \\ M_{f} & = \frac{V_{D}}{2\pi{n_{r}}} \left(C_{fr0} + C_{fr1}\frac{N}{1000} + C_{fr2}\left(\frac{N}{1000}\right)^2\right)\\ M_{p} & = \frac{V_{D}}{2\pi{n_{r}}}(p_{em} - p_{im}) \\\end{split}\]

where \(\dot{m}_{f}\) refers to the fuel flow rate, \(Q_{hv}\) is the heat value, \(\eta_{t}\) is the thermal efficiency, \(AF\) is the stoichiometric air-fuel ratio. \(C_{fr0}\), \(C_{fr1}\) and \(C_{fr2}\) are the coefficients [13] that define the quardratic relationships between friction torque \(M_{f}\) and engine speed \(N\). \(p_{em}\) is the pressure of the exhaust manifold.

19.3.3.2. Build combustion engine

The combustion engine is created and started as:

agxDriveTrain::CombustionEngineParameters engineParameters = agxDriveTrain::CombustionEngineParameters.Saab9000();
agxDriveTrain::CombustionEngineRef engine = new agxDriveTrain::CombustionEngine(engineParameters);
engine->setEnable(true);

Note that the combustion engine must be enabled to start it. Here, the program pre-set Saab engine with the displacement volume of 2.3 liter, the max torque of 212 Nm at 4000RPM is used.

19.3.3.2.1. Engine Customization

Apart from the program pre-set engines, the users can customize their own engine with the known engine parameters such as displacement volume, maxTorque, etc.

agxDriveTrain::CombustionEngineParameters engineParameters;
engineParameters.displacementVolume = 0.003;
engineParameters.maxTorque = 300;
engineParameters.maxTorqueRPM = 3000;
engineParameters.maxPower = 200;
engineParameters.maxPowerRPM = 4000;
engineParameters.idleRPM = 1000;
engineParameters.crankShaftInertia = 0.5;
agxDriveTrain::CombustionEngineRef engine = new agxDriveTrain::CombustionEngine(engineParameters);
engine->setEnable(true);

All the engine parameters that are needed for customizing a combustion engine are listed and described below.

Parameter

Unit

Description

displacementVolume

m^3

The total displacement volume of the engine, which is the sum of the volumes of the cylinders.

maxTorque

Nm

The maximum rated torque which is the highest brake torque that an engine is allowed to deliver over short/continous periods of operations

maxTorqueRPM

RPM

The rated torque speed (i.e. the crankshaft rotational speed) in which the maximum rated torque is delivered.

maxPower

W

The maximum rated power which is the highest brake power that an engine is allowed to deliver over short/continous periods of operations

maxPowerRPM

RPM

The rated power speed (i.e. the crankshaft rotational speed) in which the maximum rated power is delivered.

idleRPM

RPM

The crankshaft speed in which the engine is at idle condition.

crankShaftInertia

kg m^2

The moment of inertia of the crank shaft.

19.3.3.2.2. Throttle control

To change the velocity of the engine the throttle can be controlled. The value of the throttle is varying between 0 and 1, where 0 means idle and 1 full throttle.

engine->setThrottle(throttle);

The throttle parameters and throttle control methods are listed and described below. Also, the other engine parameters such as the number of revolution per cycle can be specified by the user given the varying engine configuration.

Parameter

Method

Description

Throttle

setThrottle

Percentage of open throttle. Value between 0 and 1.

Throttle Angle

setThrottleAngle

Set the angle of the throttle plate, instead of the percentage it is open

Idle Throttle Angle

setIdleThrottleAngle

The minimum angle the throttle plate can have when engine is running

Max. Throttle Angle

setMaxThrottleAngle

The maximum angle the throttle plate is allowed to open

Nr. Revolutions Per Cycle

setNrRevolutionsPerCycle

Should have value 1 for two-stroke engine and 2 for four-stroke

Detailed C++ and python examples with combustion engine are available in tutorials/agxOSG/tutorial_driveTrain_combustionEngine.cpp and python/tutorials/tutorial_driveTrain_combustinoEngine.agxPy.

19.3.3.3. Engine performance

Fig. 19.2 shows the torque/power curves of the combustion engine with the Saab engine parameters.

../_images/agxDriveTrain_CombustionEngine_Saab.png

Fig. 19.2 Torque/power curves of Saab engine.

Fig. 19.3 shows the torque/power curves of the combustion engine with the Volvo excavator engine parameters.

../_images/agxDriveTrain_CombustionEngine_VolvoExcavator.png

Fig. 19.3 Torque/power curves of volvo excavator engine.

19.4. Electric motor

An electric motor is a Unit that, similar to an engine, is a source of power in a drive train. It simulates the conversion of electrical energy to mechanical energy.

When creating an electrical motor one must first know the resistance, inductance, torque constant and back electromotive force (EMF) constant of the motor. The torque constant, \(\alpha\), is related to the torque, \(\tau\), and current, \(I\), as follows

\[\tau = \alpha I.\]

The EMF constant, \(\beta\), is related to the back EMF, \(V\), and the angular velocity of the motor, \(\omega\), as follows

\[V = \beta \omega.\]

For an ideal motor \(\alpha = \beta\). However, if we have additional energy losses in the motor then \(\beta \leq \alpha\). This happens at high current since energy in the form of heat is dissipated in the armature of the motor, and we thus get less mechanical energy out than electrical energy in.

When the motor is created the input voltage to the motor is by default set to zero, and thus it must be set to some other value to start the motor.

agxDriveTrain::ElectricMotorRef motor = new agxDriveTrain::ElectricMotor( resistance, torqueConstant,
                                                                          emfConstant, inductance );
motor->setVoltage( voltage );

The voltage can be set at each time step to regulate the angular velocity of the motor.

19.5. Clutch (deprecated)

Note

The class Clutch has been deprecated and we recommend using dryclutch instead.

A clutch is a Connector with a configurable efficiency and torque transfer constant. The efficiency is a value between 0 and 1 where 0 means no torque transfer and 1 means a rigid coupling. The torque transfer constant define the shape of the torque transfer curve as the efficiency is changed between 0 and 1, where a larger constant leads to a faster increase in torque as the efficiency is increased.

19.6. DryClutch

Dry-clutch as shown in Fig. 19.4 a) is a mechanism that can connect and disconnect the engine from the rest of the transmission, without stalling the engine. This is done by compressing rough plates against each other, allowing them to slip during the engagement process.

../_images/agxDriveTrain_DryClutch.png

Fig. 19.4 Dry clutch schematic. a) Relative position; b) Working schemes.

Fig. 19.4 b) shows the working schemes of the clutch. A variable of fraction \(f\) is employed to represent the relative position of the clutch discs with respect to the operation of the clutch pedal. \(0\) means that the clutch is fully disengaged and the clutch pedal is depressed down to the end. \(1\) refers to the fully engaged clutch. During the engaging and disengaging process, \(f\) is varying within the range of \([0, 1]\).

19.6.1. Governing equations

The dry-clutch is modelled with the dry friction between input and output shafts, as well as with a lock when the two shafts are rotating at nearly the same velocity. Dry friction is modelled as a velocity (nonholonomic) constraint which states “keep these velocities the same as long as the torque needed for that is below the slip threshold”. For the AGX model, there is also some amount of viscous friction though that’s only relevant in case of very heavy mass ratios.

\[0 = \omega_{e}-\omega_{s} \perp \tau \in[-\tau_{C},\tau_{C}]\]

where \(\omega_{e}\) refers to the angular speed of the engine crackshaft, \(\omega_{s}\) is the angular speed of the transmission input shaft, \(\tau\) is the torque transferred via the clutch discs, \(\tau_{C}\) is the maximum torque capacity. \(\perp\) is a perpendicularity condition which means, here that either \(\omega_{e}-\omega_{s} = 0\) and \(-\tau_{C} < \tau < \tau_{C}\) or \(\omega_{e}-\omega_{s} > 0\) and \(\tau = -\tau_{C}\), or \(\omega_{e}-\omega_{s} < 0\) and \(\tau = \tau_{C}\), or

When the lock, i.e. the positional – holonomic – constraint, is activated, the following constraint is enforced

\[0 = \phi_{e}-\phi_{s}\]

where \(\phi_{e}\) refers to the angular position of the engine crackshaft, \(\phi_{s}\) is the angular position of the transmission input shaft. By doing this, the lock mechanism of the clutch is modelled. Thus the engine crackshaft and the transmission shaft are able to be fixed rigidly together. Here there are no limits on the torque.

19.6.2. Parameters

As described above, there are physical parameters of the dry clutch, such as the torque capacity, fraction, etc. used for the modelling and simulation. Also, there are specific simulation parameters needed to be prescribed by the users as listed in the table below.

Parameter

Method

Description

Default

\(f\)

setFraction

Fraction of maximum distance between the plates (or the fraction of the maximum normal force betwen the clutch pads and the flywheel). Value varying between 0 and 1.

0

\(\tau_{C}\)

setTorqueCapacity

The maximum torque that the clutch plates can transfer. The unit is N.m

225

autoLock

setAutoLock

Activate the auto lock or not

False

timeConstant

setTimeConstant

The time to operate the clutch from disengaged to engaged or vice versa. The unit of timeConstant is the same as the unit of the time step size that the user defined. The timeConstant is varying within the range of \((0, \infty]\). \(\infty\) means that the clutch pedal is holding the same position as it was

2.5

minRelativeSlip

setMinRelativeSlip

The threshold to check whether the lock criteria is fulfilled. It is dimensionnless

1e-5

manual

setManualMode

Set manual mode or auto mode (See Clutch manipulation)

False

engage

setEngage

Activate engaging (True) or disengaging (False) operation

False

The default values of torque capacity \(\tau_{C}\) and timeConstant are chosen from [5], which are used for the engine of the medium size passenger car. For heavy duty engine, the clutch torque capacity can be as large as 1200N.m [6].

It is worth nothing that the users can customize all the parameters based on the different clutch properties as well as the varying driving operations as per traffic situations.

19.6.3. Build clutch

The clutch is created and started as:

agxPowerLine::PowerLineRef powerLine = new agxPowerLine::PowerLine();
agxDriveTrain::DryClutchRef dryClutch = new agxDriveTrain::DryClutch();
dryClutch->setTorqueCapacity(400.0);
dryClutch->setTimeConstant(2.0);
dryClutch->setAutoLock(true);
powerLine->add(dryClutch);

Once the clutch is built, it can be connected to the engine (See Engine) and transmission shafts (See Shaft).

agxDriveTrain::FixedVelocityEngineRef engine = new agxDriveTrain::FixedVelocityEngine();
agxDriveTrain::ShaftRef transmissionShaft = new agxDriveTrain::Shaft();
dryClutch->connect(engine);
dryClutch->connect(transmissionShaft);

19.6.4. Clutch manipulation

The clutch can be manipulated with two modes, namely manual and auto. With manual mode, the user can manipulate the clutch using the setFraction() method.

class manualClutchListener : public agxSDK::StepEventListener
{
  public:
    manualClutchListener(agxDriveTrain::dryClutch* clutch) :
    {
    }
    void pre(const agx::TimeStamp& t)
    {
      // Engaging
      if (t > 0 && t <= 1.0) {
        clutch->setFraction(t);
      }
      // Disengaging
      else if (t > 1.0 && t <= 3.0>) {
        clutch->setFraction(1 - (t-1) / 2);
      }
    }

As opposed to the manual mode, the engage() method instead of setFraction() is used to manipulate the clutch automatically.

class autoClutchListener : public agxSDK::StepEventListener
{
  public:
    autoClutchListener(agxDriveTrain::dryClutch* clutch) :
    {
    }
    void pre(const agx::TimeStamp& t)
    {
      // Engaging
      if (t > 3.0 && t <= 5.0)
      {
        clutch->engage(true);
        clutch->setTimeConstant(2.0);
      }
      // Disengaging
      else if (t> 7.0 && t <= 9.0)
      {
        clutch->engage(false);
        clutch->setTimeConstant(1.0);
      }
      // Clutch on-hold
      else {
        clutch->setTimeConstant(math.inf);
      }
    }

Detailed C++ and python examples with dryClutch are available in tutorials/agxOSG/tutorial_driveTrain.cpp and python/tutorials/tutorial_driveTrain_dryClutch.agxPy.

19.7. Differential

A differential is a Connector that distributes toque evenly over multiple output shafts in such a way that the angular velocity of the input shaft is the average of the velocities of the output shafts. The differential can be locked, forcing all outputs to rotate at the same speed. There is also a limited slip torque version of the lock, which causes only a limited amount of torque to be transferred between outputs in order to maintain equal velocity of the output shafts.

19.8. Connecting a hinge constraint

To connect the powerline to a hinge constraint we use the RotationalActuator class found in the agxPowerLine namespace. An Actuator is a powerline component that transfers motion between a powerline unit and a regular AGX constraint. Assuming there exists a wheel body attached to a chassis body using a hinge named hinge, we can drive that wheel with the drive train using the following code.

agxPowerLine::RotationalActuatorRef axle = new agxPowerLine::RotationalActuator(hinge);
shaft1->connect(axle);

19.9. Connecting a wire winch to a drivetrain

A agxWire::WireWinchController is a class that can winch in/out wire using a brake and a motor. A WireWinchController is a linear constraint, meaning it operates using a linear force specified in Newton (N). A winch is usually a rotating object with a certain effective radius (depending on how much wire is spooled in). To model a torque driven winch one need to connect a rotational power source such as a motorized Hinge or a Engine.

As the winch is linear and a motor/hinge is rotational, we need to transform rotational work to linear work. This is done using a agxPowerLine::RotationalTranslationalHolonomicConnector. We also need to connect the connector to a winch and this is done using a agxPowerLine::WireWinchActuator.

We will then end up with a powerline system that looks like:

Hinge---> Shaft ---> RotationalTranslationalHolonomicConnector ---> WireWinchActuator ---> Winch

Below is a sample code snippet that will create this system:

// Assume we have a pointer to a winch object with a routed wire.

// First create a shaft that will transfer rotation between the motorized hinge and the connector below
auto shaft = new agxDriveTrain::Shaft();
auto winch_socket = new agxPowerLine::RotationalTranslationalHolonomicConnector();

// The effective rotation of the "winch" can be specified here
// This will affect the ratio between rotational motion of the hinge and the linear motion of the winch
// A larger radius leads to a higher speed and less force
winch_socket->setShaftRadius( radius );

// Connect the shaft with the winch_socket
shaft->connect( winch_socket );
// Set some small inertia of the shaft. This is the inertia of the rotating drum.
shaft->setInertia( 1e-4 );

// Add the shaft to the powerline
power_line->add( shaft );

// Now create a constraint that will be attached to the shaft rigidbody (1-dimensional)
// First we need to orient the Hinge so that it rotates in the direction of the shaft body
auto frame = new agx.Frame()
frame->setLocalRotate( agx::Quat( agx::Vec3::Z_AXIS(), shaft->getRotationalDimension()->getWorldDirection())  );

// Next we create the hinge
auto winch_hinge = new agx::Hinge( shaft->getRotationalDimension()->getOrReserveBody(), frame );

// We will initially enable the lock of the hinge and disable the motor.
// If we want to winch, we just disable the lock and enable the motor with a target speed.
winch_hinge->getMotor1D()->setEnable( false );
winch_hinge->getMotor1D()->setSpeed( 0 );

// Remember a Lock1D is NOT a brake. It will work as a spring if you violate the target position.
// So either you have to set the position of the lock to avoid a "springback" or, you can use the friction controller
winch_hinge->getLock1D()->setEnable( true );
simulation->add( winch_hinge );

// Finally we create an actuator that will transfer the linear motion from the winch socket to the winch.
auto winch_actuator = new agxPowerLine::WireWinchActuator( winch );
winch_socket->connect( winch_actuator );
power_line->add( winch_actuator );

For a more complete example of this, see the python script data/python/torque_driven_winch.agxPy.