%% GENERATE_PAR_FILES - 生成CarSim原生.par参数文件
% 兼容版本：MATLAB R2016b + CarSim 2019.0
% 功能：生成CarSim可以直接导入的.par文件
%
% 蒙多学习：.par是CarSim原生格式，比.cpar更可靠
%
% 作者：LiHongwei
% 日期：2026-05-29

clear; clc; close all;

fprintf('============================================================\n');
fprintf('  CarSim .PAR 文件生成工具\n');
fprintf('  解决CPAR文件无法打开的问题\n');
fprintf('============================================================\n\n');

%% ==================== 配置参数 ====================

% 道路参数
road.length = 50;           % 道路长度 [m]
road.width = 6;             % 道路宽度 [m]

% 车位参数
parking.spot_length = 5;    % 车位长度 [m]
parking.spot_width = 2.5;   % 车位宽度 [m]
parking.num_spots = 10;     % 车位数量
parking.target_spot = 5;    % 目标车位（空置）
parking.occupancy = [1, 1, 1, 1, 0, 1, 1, 1, 1, 1];

% 车辆初始条件
vehicle.init_x = 45;
vehicle.init_y = 3;
vehicle.init_yaw = 0;
vehicle.init_speed = 5;

fprintf('[步骤1/5] 配置参数加载完成\n\n');

%% ==================== 生成道路参数文件 ====================

fprintf('[步骤2/5] 生成道路参数文件...\n');

road_file = 'road_geometry.par';
fid = fopen(road_file, 'w');

fprintf(fid, '! CarSim Road Geometry Parameters\n');
fprintf(fid, '! Generated by MATLAB\n');
fprintf(fid, '! Date: %s\n\n', datestr(now, 'yyyy-mm-dd'));

fprintf(fid, '! Road Configuration\n');
fprintf(fid, 'ROAD_TYPE = FLAT\n');
fprintf(fid, 'ROAD_LENGTH = %.1f\n', road.length);
fprintf(fid, 'ROAD_WIDTH = %.1f\n', road.width);
fprintf(fid, 'NUM_LANES = 2\n');
fprintf(fid, 'LANE_WIDTH = %.1f\n', road.width / 2);
fprintf(fid, 'SURFACE_TYPE = DRY_ASPHALT\n');
fprintf(fid, 'FRICTION = 0.85\n');
fprintf(fid, 'ROUGHNESS = SMOOTH\n');

fclose(fid);
fprintf('  ✓ %s 已生成\n', road_file);

%% ==================== 生成车辆参数文件 ====================

fprintf('[步骤3/5] 生成车辆参数文件...\n');

vehicle_file = 'vehicle_params.par';
fid = fopen(vehicle_file, 'w');

fprintf(fid, '! CarSim Vehicle Parameters\n');
fprintf(fid, '! Generated by MATLAB\n\n');

fprintf(fid, '! Vehicle Body\n');
fprintf(fid, 'MASS = 1500\n');
fprintf(fid, 'LENGTH = 4.5\n');
fprintf(fid, 'WIDTH = 1.8\n');
fprintf(fid, 'HEIGHT = 1.5\n');
fprintf(fid, 'WHEELBASE = 2.7\n');
fprintf(fid, 'FRONT_OVERHANG = 0.9\n');
fprintf(fid, 'REAR_OVERHANG = 0.9\n\n');

fprintf(fid, '! Powertrain\n');
fprintf(fid, 'ENGINE_TORQUE = 250\n');
fprintf(fid, 'TRANSMISSION = AUTO_6AT\n');
fprintf(fid, 'FINAL_DRIVE_RATIO = 3.5\n');
fprintf(fid, 'REVERSE_GEAR_RATIO = 3.2\n\n');

fprintf(fid, '! Brakes\n');
fprintf(fid, 'FRONT_BRAKE_GAIN = 250\n');
fprintf(fid, 'REAR_BRAKE_GAIN = 150\n');
fprintf(fid, 'MAX_BRAKE_PRESSURE = 15000\n');
fprintf(fid, 'ABS = ENABLED\n\n');

fprintf(fid, '! Steering\n');
fprintf(fid, 'STEERING_RATIO = 16\n');
fprintf(fid, 'MAX_STEERING_ANGLE = 540\n');
fprintf(fid, 'POWER_STEERING = ENABLED\n');

fclose(fid);
fprintf('  ✓ %s 已生成\n', vehicle_file);

%% ==================== 生成初始条件文件 ====================

fprintf('[步骤4/5] 生成初始条件文件...\n');

init_file = 'initial_conditions.par';
fid = fopen(init_file, 'w');

fprintf(fid, '! CarSim Initial Conditions\n');
fprintf(fid, '! Generated by MATLAB\n\n');

fprintf(fid, '! Initial Position\n');
fprintf(fid, 'INIT_X = %.1f\n', vehicle.init_x);
fprintf(fid, 'INIT_Y = %.1f\n', vehicle.init_y);
fprintf(fid, 'INIT_YAW = %.1f\n', vehicle.init_yaw);
fprintf(fid, 'INIT_SPEED = %.1f\n', vehicle.init_speed);
fprintf(fid, 'INIT_GEAR = 1\n\n');

fprintf(fid, '! Simulation Events\n');
fprintf(fid, '! Event 1: Approach (0-10s)\n');
fprintf(fid, 'EVENT1_NAME = APPROACH\n');
fprintf(fid, 'EVENT1_START = 0\n');
fprintf(fid, 'EVENT1_DURATION = 10\n');
fprintf(fid, 'EVENT1_SPEED = 5\n');
fprintf(fid, 'EVENT1_GEAR = 1\n\n');

fprintf(fid, '! Event 2: Prepare (10-12s)\n');
fprintf(fid, 'EVENT2_NAME = PREPARE\n');
fprintf(fid, 'EVENT2_START = 10\n');
fprintf(fid, 'EVENT2_DURATION = 2\n');
fprintf(fid, 'EVENT2_SPEED = 0\n');
fprintf(fid, 'EVENT2_GEAR = 0\n');
fprintf(fid, 'EVENT2_BRAKE = 100\n\n');

fprintf(fid, '! Event 3: Reverse (12-60s)\n');
fprintf(fid, 'EVENT3_NAME = REVERSE\n');
fprintf(fid, 'EVENT3_START = 12\n');
fprintf(fid, 'EVENT3_DURATION = 48\n');
fprintf(fid, 'EVENT3_SPEED = -2\n');
fprintf(fid, 'EVENT3_GEAR = -1\n');
fprintf(fid, 'EVENT3_CONTROL = SIMULINK\n');

fclose(fid);
fprintf('  ✓ %s 已生成\n', init_file);

%% ==================== 生成Simulink接口文件 ====================

fprintf('[步骤5/5] 生成Simulink接口文件...\n');

simulink_file = 'simulink_interface.par';
fid = fopen(simulink_file, 'w');

fprintf(fid, '! CarSim Simulink Interface\n');
fprintf(fid, '! Generated by MATLAB\n\n');

fprintf(fid, '! S-Function Configuration\n');
fprintf(fid, 'SFUNC_NAME = sf_car_sim\n');
fprintf(fid, 'SFUNC_OUTPUT = mexw64\n\n');

fprintf(fid, '! Input Channels\n');
fprintf(fid, 'NUM_INPUTS = 4\n');
fprintf(fid, 'INPUT1 = IMP_STEER_SW, deg, 0\n');
fprintf(fid, 'INPUT2 = IMP_PBK_CON, kPa, 0\n');
fprintf(fid, 'INPUT3 = IMP_THROTTLE, %%, 0\n');
fprintf(fid, 'INPUT4 = IMP_GEARCHANGE, -, 0\n\n');

fprintf(fid, '! Output Channels\n');
fprintf(fid, 'NUM_OUTPUTS = 6\n');
fprintf(fid, 'OUTPUT1 = XCG, m\n');
fprintf(fid, 'OUTPUT2 = YCG, m\n');
fprintf(fid, 'OUTPUT3 = YAW, rad\n');
fprintf(fid, 'OUTPUT4 = VX, km/h\n');
fprintf(fid, 'OUTPUT5 = VY, km/h\n');
fprintf(fid, 'OUTPUT6 = AVZ, deg/s\n');

fclose(fid);
fprintf('  ✓ %s 已生成\n', simulink_file);

%% ==================== 生成导入脚本 ====================

fprintf('\n生成MATLAB导入脚本...\n');

import_script = 'import_par_to_carsim.m';
fid = fopen(import_script, 'w');

fprintf(fid, '%% IMPORT_PAR_TO_CARSIM - 导入.par文件到CarSim\n');
fprintf(fid, '%% 兼容版本：MATLAB R2016b + CarSim 2019.0\n\n');

fprintf(fid, 'clear; clc;\n\n');

fprintf(fid, 'fprintf(''============================================================\\n'');\n');
fprintf(fid, 'fprintf(''  CarSim .PAR 文件导入工具\\n'');\n');
fprintf(fid, 'fprintf(''============================================================\\n\\n'');\n\n');

fprintf(fid, '%% 连接CarSim\n');
fprintf(fid, 'try\n');
fprintf(fid, '    fprintf(''连接CarSim...\\n'');\n');
fprintf(fid, '    h = actxserver(''CarSim.Application'');\n');
fprintf(fid, '    fprintf(''✓ 成功连接CarSim\\n\\n'');\n\n');

fprintf(fid, '    %% 导入.par文件\n');
fprintf(fid, '    par_files = {''road_geometry.par'', ''vehicle_params.par'', ...\n');
fprintf(fid, '                 ''initial_conditions.par'', ''simulink_interface.par''};\n\n');

fprintf(fid, '    for i = 1:length(par_files)\n');
fprintf(fid, '        if exist(par_files{i}, ''file'')\n');
fprintf(fid, '            fprintf(''导入: %s\\n'', par_files{i});\n');
fprintf(fid, '            h.ImportDataset(fullfile(pwd, par_files{i}));\n');
fprintf(fid, '            fprintf(''  ✓ 成功\\n'');\n');
fprintf(fid, '        else\n');
fprintf(fid, '            fprintf(''  ✗ 文件不存在: %s\\n'', par_files{i});\n');
fprintf(fid, '        end\n');
fprintf(fid, '    end\n\n');

fprintf(fid, '    %% 导出S-Function\n');
fprintf(fid, '    fprintf(''\\n导出S-Function...\\n'');\n');
fprintf(fid, '    h.ExportSFunction();\n');
fprintf(fid, '    fprintf(''✓ S-Function导出成功\\n\\n'');\n\n');

fprintf(fid, '    %% 释放连接\n');
fprintf(fid, '    h.release;\n');
fprintf(fid, '    fprintf(''✓ 导入完成！\\n'');\n\n');

fprintf(fid, 'catch ME\n');
fprintf(fid, '    fprintf(''\\n✗ 错误: %s\\n'', ME.message);\n');
fprintf(fid, '    fprintf(''\\n请手动导入：\\n'');\n');
fprintf(fid, '    fprintf(''1. 打开CarSim\\n'');\n');
fprintf(fid, '    fprintf(''2. File → Import Dataset\\n'');\n');
fprintf(fid, '    fprintf(''3. 选择.par文件\\n'');\n');
fprintf(fid, 'end\n');

fclose(fid);
fprintf('  ✓ %s 已生成\n', import_script);

%% ==================== 显示结果 ====================

fprintf('\n============================================================\n');
fprintf('  所有文件生成完成！\n');
fprintf('============================================================\n\n');

fprintf('生成的文件列表：\n');
fprintf('  1. %s (道路参数)\n', road_file);
fprintf('  2. %s (车辆参数)\n', vehicle_file);
fprintf('  3. %s (初始条件)\n', init_file);
fprintf('  4. %s (Simulink接口)\n', simulink_file);
fprintf('  5. %s (导入脚本)\n\n', import_script);

fprintf('使用方法：\n');
fprintf('  方法1: 在CarSim中逐个导入.par文件\n');
fprintf('  方法2: 运行 %s 自动导入\n\n', import_script);

fprintf('文件路径：\n');
fprintf('  %s\\*.par\n', pwd);
