- Messages
- 57
- Country

Hey folks,
Just thought I'd share this. The code below is what we used in the 717 to prevent creeping with the brakes (either parking brake or toe brakes) with high thrust to allow static takeoffs. It also allows the aircraft to continue rolling after picking up some speed taxiing, giving it a more natural idle taxi effect. It also reads the surface type to determine whether or not it is reasonable to be able to idle taxi/glide (i.e. not so much on grass, etc.). It's by no means perfect, but it does the trick.
How it Works
Brake Creep Prevention: It reads thrust and brakes and conditionally sets the velocity to 0.
Idle Taxi/Friction Reduction: It uses the basic F=MA (force equals mass times acceleration) rule of physics combined with aircraft specific tuners to determine speeds and blends smoothly up until built-in acceleration can take over.
Note: To use this, you will need a basic understanding of SimConnect and C++, as it must be part of a C++ gauge.
Just thought I'd share this. The code below is what we used in the 717 to prevent creeping with the brakes (either parking brake or toe brakes) with high thrust to allow static takeoffs. It also allows the aircraft to continue rolling after picking up some speed taxiing, giving it a more natural idle taxi effect. It also reads the surface type to determine whether or not it is reasonable to be able to idle taxi/glide (i.e. not so much on grass, etc.). It's by no means perfect, but it does the trick.
How it Works
Brake Creep Prevention: It reads thrust and brakes and conditionally sets the velocity to 0.
Idle Taxi/Friction Reduction: It uses the basic F=MA (force equals mass times acceleration) rule of physics combined with aircraft specific tuners to determine speeds and blends smoothly up until built-in acceleration can take over.
Note: To use this, you will need a basic understanding of SimConnect and C++, as it must be part of a C++ gauge.
C++:
//scdata is a SimConnect data struct
//relevant pieces of it are shown below
//on_ground
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "SIM ON GROUND", "bool");
//ground_speed
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "GROUND VELOCITY", "knots");
//l_brake
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "BRAKE LEFT POSITION", "percent");
//r_brake
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "BRAKE RIGHT POSITION", "percent");
//park_brake_indicator
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "BRAKE PARKING INDICATOR", "bool");
//l_thrust
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "TURB ENG JET THRUST:1", "pounds");
//r_thrust
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "TURB ENG JET THRUST:2", "pounds");
//total_weight
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "TOTAL WEIGHT", "pounds");
//surface_type
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "SURFACE TYPE", "number");
//vel_body_z
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_READ, "RELATIVE WIND VELOCITY BODY Z", "knots");
//the definition of SIM_DEFINITION_DATA_WRITE_Z_VELOCITY is this
SimConnect_AddToDataDefinition(hSimConn, SIM_DEFINITION_DATA_WRITE_Z_VELOCITY, "VELOCITY BODY Z", "feet per second");
//first_simconnect_frame_handled is just a flag set after the first time scdata is updated to ensure we're not using bad/default data - may not apply to all cases
//force_mod, mass_mod, and accel_mod can be used to tweak the behavior of the aircraft.
if (scdata->on_ground == TRUE && scdata->ground_speed <= 40 && first_simconnect_frame_handled == true) {
double brake = ((scdata->l_brake + scdata->r_brake) / 200.0);
brake = max(scdata->park_brake_indicator, brake);
brake = min(brake, 1.0);
double speed = 0;
bool use_accel = brake < 0.1 && scdata->l_thrust >= 0 && scdata->r_thrust >= 0;
switch ((int)scdata->surface_type) {
case 1: //grass
case 2: //water
case 3: //grass_bumpy
case 5: //short grass
case 6: //long grass
case 7: //hard turf
case 8: //snow
case 10: //urban
case 14: //gravel
case 21: //sand
use_accel = false;
break;
}
if (use_accel == true) {
//F = M*A
//A = F/M
//F = thrust
//M = total weight
static double force_mod = 20.0;
static double mass_mod = 1.0;
static double accel_mod = 1.0;
double force = (scdata->l_thrust + scdata->r_thrust) * force_mod;
double mass = scdata->total_weight * mass_mod;
double accel = (force / mass) * accel_mod;
if (accel > 0) {
accel *= 0.592484; //feet per second per second
speed = scdata->vel_body_z + (accel * sctimediff);
SimConnect_SetDataOnSimObject(hSimConn, SIM_DEFINITION_DATA_WRITE_Z_VELOCITY, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(double), &speed);
}
}
else {
if (fabs(scdata->vel_body_z) < 1.0 && brake > 0.8) {
SimConnect_SetDataOnSimObject(hSimConn, SIM_DEFINITION_DATA_WRITE_Z_VELOCITY, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0, sizeof(double), &speed);
}
}
}




