Skip to content

Instantly share code, notes, and snippets.

@nk4dev
Created February 7, 2026 14:20
Show Gist options
  • Select an option

  • Save nk4dev/91eb34b11120ff000afb0de3e0257b6f to your computer and use it in GitHub Desktop.

Select an option

Save nk4dev/91eb34b11120ff000afb0de3e0257b6f to your computer and use it in GitHub Desktop.
//script for ange-yaghi/engine-sim
import "engine_sim.mr"
units units()
constants constants()
impulse_response_library ir_lib()
label cycle(2 * 360 * units.deg)
// 点火ワイヤー
private node wires {
output wire1: ignition_wire();
output wire2: ignition_wire();
output wire3: ignition_wire();
output wire4: ignition_wire();
output wire5: ignition_wire();
output wire6: ignition_wire();
output wire7: ignition_wire();
output wire8: ignition_wire();
}
// シリンダーヘッド(NA用にリフト量とフローを標準化)
private node f136_head {
input intake_camshaft;
input exhaust_camshaft;
input chamber_volume: 60 * units.cc;
input intake_runner_volume: 149.6 * units.cc;
input intake_runner_cross_section_area: 2.2 * units.inch * 2.2 * units.inch;
input exhaust_runner_volume: 50.0 * units.cc;
input exhaust_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch;
input flow_attenuation: 1.0;
input lift_scale: 1.0; // ターボ用の1.2から1.0へ戻す
input flip_display: false;
alias output __out: head;
function intake_flow(50 * units.thou)
intake_flow
.add_flow_sample(0 * lift_scale, 0 * flow_attenuation)
.add_flow_sample(50 * lift_scale, 58 * flow_attenuation)
.add_flow_sample(100 * lift_scale, 103 * flow_attenuation)
.add_flow_sample(150 * lift_scale, 156 * flow_attenuation)
.add_flow_sample(200 * lift_scale, 214 * flow_attenuation)
.add_flow_sample(250 * lift_scale, 249 * flow_attenuation)
.add_flow_sample(300 * lift_scale, 268 * flow_attenuation)
.add_flow_sample(350 * lift_scale, 280 * flow_attenuation)
.add_flow_sample(400 * lift_scale, 280 * flow_attenuation)
.add_flow_sample(450 * lift_scale, 281 * flow_attenuation)
function exhaust_flow(50 * units.thou)
exhaust_flow
.add_flow_sample(0 * lift_scale, 0 * flow_attenuation)
.add_flow_sample(50 * lift_scale, 37 * flow_attenuation)
.add_flow_sample(100 * lift_scale, 72 * flow_attenuation)
.add_flow_sample(150 * lift_scale, 113 * flow_attenuation)
.add_flow_sample(200 * lift_scale, 160 * flow_attenuation)
.add_flow_sample(250 * lift_scale, 196 * flow_attenuation)
.add_flow_sample(300 * lift_scale, 222 * flow_attenuation)
.add_flow_sample(350 * lift_scale, 235 * flow_attenuation)
.add_flow_sample(400 * lift_scale, 245 * flow_attenuation)
.add_flow_sample(450 * lift_scale, 246 * flow_attenuation)
generic_cylinder_head head(
chamber_volume: chamber_volume,
intake_runner_volume: intake_runner_volume,
intake_runner_cross_section_area: intake_runner_cross_section_area,
exhaust_runner_volume: exhaust_runner_volume,
exhaust_runner_cross_section_area: exhaust_runner_cross_section_area,
intake_port_flow: intake_flow,
exhaust_port_flow: exhaust_flow,
valvetrain: standard_valvetrain(
intake_camshaft: intake_camshaft,
exhaust_camshaft: exhaust_camshaft
),
flip_display: flip_display
)
}
// カムシャフト
private node f136_camshaft {
input lobe_profile;
input intake_lobe_profile: lobe_profile;
input exhaust_lobe_profile: lobe_profile;
input lobe_separation: 114 * units.deg;
input intake_lobe_center: lobe_separation;
input exhaust_lobe_center: lobe_separation;
input advance: 0 * units.deg;
input base_radius: 0.5 * units.inch;
output intake_cam_0: _intake_cam_0;
output exhaust_cam_0: _exhaust_cam_0;
output intake_cam_1: _intake_cam_1;
output exhaust_cam_1: _exhaust_cam_1;
camshaft_parameters params (
advance: advance,
base_radius: base_radius
)
camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile)
camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile)
camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile)
camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile)
label rot(90 * units.deg)
label rot360(360 * units.deg)
// 点火順序: 1-5-3-7-4-8-2-6 (フラットプレーンV8典型)
_exhaust_cam_0
.add_lobe(rot360 - exhaust_lobe_center + 0 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 6 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 2 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 4 * rot)
_intake_cam_0
.add_lobe(rot360 + intake_lobe_center + 0 * rot)
.add_lobe(rot360 + intake_lobe_center + 6 * rot)
.add_lobe(rot360 + intake_lobe_center + 2 * rot)
.add_lobe(rot360 + intake_lobe_center + 4 * rot)
_exhaust_cam_1
.add_lobe(rot360 - exhaust_lobe_center + 1 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 7 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 3 * rot)
.add_lobe(rot360 - exhaust_lobe_center + 5 * rot)
_intake_cam_1
.add_lobe(rot360 + intake_lobe_center + 1 * rot)
.add_lobe(rot360 + intake_lobe_center + 7 * rot)
.add_lobe(rot360 + intake_lobe_center + 3 * rot)
.add_lobe(rot360 + intake_lobe_center + 5 * rot)
}
// 燃焼速度係数
private node turbulence_to_flame_speed_ratio {
alias output __out:
function(5.0)
.add_sample(0.0, 3.0)
.add_sample(5.0, 1.5 * 5.0)
.add_sample(10.0, 1.75 * 10.0)
.add_sample(15.0, 2.0 * 15.0)
.add_sample(20.0, 2.0 * 20.0)
.add_sample(25.0, 2.0 * 25.0)
.add_sample(30.0, 2.0 * 30.0)
.add_sample(35.0, 2.0 * 35.0)
.add_sample(40.0, 2.0 * 40.0)
.add_sample(45.0, 2.0 * 45.0);
}
// エンジン本体
public node f136_v8 {
alias output __out: engine;
engine engine(
name: "AS408",
starter_torque: 78 * units.lb_ft,
starter_speed: 1000 * units.rpm,
redline: 10500 * units.rpm,
throttle_gamma: 2.0,
fuel: fuel(
max_burning_efficiency: 1.0, // ターボ用の1.2から通常値へ
turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio()
),
hf_gain: 0.01, // ターボノイズ(0.1)を除去し、クリアなNAサウンドへ
noise: 1.0,
jitter: 0.15,
simulation_frequency: 10000
)
wires wires()
label stroke(80.1 * units.mm)
label bore(96 * units.mm)
label rod_length(150 * units.mm)
label rod_mass(30 * units.g)
label compression_height(1.0 * units.inch)
label crank_mass(60 * units.lb)
label flywheel_mass(18 * units.lb)
label flywheel_radius(4 * units.inch)
label crank_moment(
1.5 * disk_moment_of_inertia(mass: crank_mass, radius: stroke)
)
label flywheel_moment(
disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius)
)
label other_moment(
disk_moment_of_inertia(mass: 1 * units.kg, radius: 1.0 * units.cm)
)
label v_angle(90 * units.deg)
crankshaft c0(
throw: stroke / 2,
flywheel_mass: flywheel_mass,
mass: crank_mass,
friction_torque: 2.0 * units.lb_ft,
moment_of_inertia: crank_moment + flywheel_moment + other_moment,
position_x: 0.0,
position_y: 0.0,
tdc: 90 * units.deg + (v_angle / 2.0)
)
rod_journal rj0(angle: 0 * units.deg)
rod_journal rj1(angle: 180 * units.deg)
rod_journal rj2(angle: 180 * units.deg)
rod_journal rj3(angle: 0 * units.deg)
c0
.add_rod_journal(rj0)
.add_rod_journal(rj1)
.add_rod_journal(rj2)
.add_rod_journal(rj3)
piston_parameters piston_params(
mass: (70) * units.g,
compression_height: compression_height,
wrist_pin_position: 0.0,
displacement: 0.0
)
connecting_rod_parameters cr_params(
mass: rod_mass,
moment_of_inertia: rod_moment_of_inertia(
mass: rod_mass,
length: rod_length
),
center_of_mass: 0.0,
length: rod_length
)
// ■ NA仕様への変更点 ■
intake intake(
plenum_volume: 1.325 * units.L,
plenum_cross_section_area: 20.0 * units.cm2,
intake_flow_rate: k_carb(1200.0), // 5000から700へ(自然吸気の流量)
runner_flow_rate: k_carb(400.0), // 1000から100へ
runner_length: 12.0 * units.inch,
idle_flow_rate: k_carb(0.0),
idle_throttle_plate_position: 0.996,
velocity_decay: 0.5
)
exhaust_system_parameters es_params(
outlet_flow_rate: k_carb(1000.0), // 5000から1000へ戻す
primary_tube_length: 23.0 * units.inch,
primary_flow_rate: k_carb(600.0),
velocity_decay: 0.5
)
exhaust_system exhaust0(
es_params,
audio_volume: 2.0 * 0.1,
length: 46 * units.inch,
impulse_response: ir_lib.mild_exhaust_0_reverb
)
exhaust_system exhaust1(
es_params,
audio_volume: 3.6 * 0.09,
length: 50 * units.inch,
impulse_response: ir_lib.mild_exhaust_0_reverb
)
cylinder_bank_parameters bank_params(
bore: bore,
deck_height: stroke / 2 + rod_length + compression_height
)
cylinder_bank b0(bank_params, angle: v_angle / 2.0)
cylinder_bank b1(bank_params, angle: -v_angle / 2.0)
b0
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj0,
intake: intake,
exhaust_system: exhaust0,
ignition_wire: wires.wire1,
sound_attenuation: 0.9,
primary_length: 2 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj1,
intake: intake,
exhaust_system: exhaust0,
ignition_wire: wires.wire2,
sound_attenuation: 0.8,
primary_length: 1 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj2,
intake: intake,
exhaust_system: exhaust0,
ignition_wire: wires.wire3,
sound_attenuation: 1.1,
primary_length: 3 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj3,
intake: intake,
exhaust_system: exhaust0,
ignition_wire: wires.wire4,
sound_attenuation: 1.0,
primary_length: 5 * units.cm
)
.set_cylinder_head(
f136_head(
intake_camshaft: camshaft.intake_cam_0,
exhaust_camshaft: camshaft.exhaust_cam_0,
flip_display: true,
flow_attenuation: 1.0)
)
b1
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj0,
intake: intake,
exhaust_system: exhaust1,
ignition_wire: wires.wire5,
sound_attenuation: 1.0,
primary_length: 1 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj1,
intake: intake,
exhaust_system: exhaust1,
ignition_wire: wires.wire6,
sound_attenuation: 0.8,
primary_length: 5 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj2,
intake: intake,
exhaust_system: exhaust1,
ignition_wire: wires.wire7,
sound_attenuation: 0.9,
primary_length: 7 * units.cm
)
.add_cylinder(
piston: piston(piston_params, blowby: k_28inH2O(0.0)),
connecting_rod: connecting_rod(cr_params),
rod_journal: rj3,
intake: intake,
exhaust_system: exhaust1,
ignition_wire: wires.wire8,
sound_attenuation: 0.7,
primary_length: 0 * units.cm
)
.set_cylinder_head(
f136_head(
intake_camshaft: camshaft.intake_cam_1,
exhaust_camshaft: camshaft.exhaust_cam_1,
flow_attenuation: 1.0)
)
engine
.add_cylinder_bank(b0)
.add_cylinder_bank(b1)
engine.add_crankshaft(c0)
harmonic_cam_lobe intake_lobe(
duration_at_50_thou: 230 * units.deg,
gamma: 0.9,
lift: 551 * units.thou,
steps: 256
)
harmonic_cam_lobe exhaust_lobe(
duration_at_50_thou: 230 * units.deg,
gamma: 0.9,
lift: 551 * units.thou,
steps: 256
)
f136_camshaft camshaft(
lobe_profile: "N/A",
intake_lobe_profile: intake_lobe,
exhaust_lobe_profile: exhaust_lobe,
intake_lobe_center: 116 * units.deg,
exhaust_lobe_center: 116 * units.deg,
base_radius: 1.0 * units.inch
)
function timing_curve(1000 * units.rpm)
timing_curve
.add_sample(0000 * units.rpm, 12 * units.deg)
.add_sample(1000 * units.rpm, 12 * units.deg)
.add_sample(2000 * units.rpm, 20 * units.deg)
.add_sample(3000 * units.rpm, 30 * units.deg)
.add_sample(4000 * units.rpm, 40 * units.deg)
.add_sample(5000 * units.rpm, 40 * units.deg)
.add_sample(6000 * units.rpm, 40 * units.deg)
.add_sample(7000 * units.rpm, 40 * units.deg)
.add_sample(8000 * units.rpm, 40 * units.deg)
ignition_module ignition_module(
timing_curve: timing_curve,
rev_limit: 11100 * units.rpm, // フェラーリらしい高回転リミット
limiter_duration: 0.1)
ignition_module
.connect_wire(wires.wire1, 0 * 90 * units.deg)
.connect_wire(wires.wire5, 1 * 90 * units.deg)
.connect_wire(wires.wire3, 2 * 90 * units.deg)
.connect_wire(wires.wire7, 3 * 90 * units.deg)
.connect_wire(wires.wire4, 4 * 90 * units.deg)
.connect_wire(wires.wire8, 5 * 90 * units.deg)
.connect_wire(wires.wire2, 6 * 90 * units.deg)
.connect_wire(wires.wire6, 7 * 90 * units.deg)
engine.add_ignition_module(ignition_module)
}
// 車両設定(標準的なスポーツカー)
private node mustang_vehicle {
alias output __out:
vehicle(
mass: 1305* units.kg,
drag_coefficient: 0.25,
cross_sectional_area: (72 * units.inch) * (55 * units.inch),
diff_ratio: 3.42,
tire_radius: 19 * units.inch,
rolling_resistance: 200 * units.N
);
}
private node performance_8_speed_transmission {
alias output __out:
transmission(
// 高出力エンジンでもクラッチが滑らないようにトルク容量を強化
max_clutch_torque: 1500 * units.lb_ft
)
// 1速: 強力な加速
.add_gear(4.82)
// 2速
.add_gear(3.243)
// 3速
.add_gear(2.423)
// 4速: 中速コーナーや追い越し
.add_gear(1.951)
// 5速
.add_gear(1.66)
// 6速: 直結 (1.100)
.add_gear(1.420)
// 7速: 高速巡航用オーバードライブ
.add_gear(1.29);
}
public node main {
run(
engine: f136_v8(),
vehicle: mustang_vehicle(),
transmission: performance_8_speed_transmission()
)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment