Jelajahi Sumber

生成视频

root 2 tahun lalu
induk
melakukan
1973566f3f
13 mengubah file dengan 107 tambahan dan 95 penghapusan
  1. 5 0
      api-common/src/main/java/api/common/util/StringUtil.java
  2. 1 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/feign/VideoService.java
  3. 1 1
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/feign/fallback/VideoServiceFallBack.java
  4. 3 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/manager/TaskManager.java
  5. 7 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/AutoSubProjectMapper.java
  6. 7 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/ManualProjectMapper.java
  7. 1 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/ProjectPO.java
  8. 5 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/service/TaskService.java
  9. 11 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/util/ProjectUtil.java
  10. 2 1
      simulation-resource-video/src/main/java/com/css/simulation/resource/video/controller/VideoController.java
  11. 10 31
      simulation-resource-video/src/main/java/com/css/simulation/resource/video/mapper/VehicleMapper.java
  12. 33 31
      simulation-resource-video/src/main/java/com/css/simulation/resource/video/pojo/po/VehiclePO.java
  13. 21 23
      simulation-resource-video/src/main/java/com/css/simulation/resource/video/service/VideoService.java

+ 5 - 0
api-common/src/main/java/api/common/util/StringUtil.java

@@ -5,6 +5,11 @@ import java.util.UUID;
 
 public class StringUtil {
 
+    //* -------------------------------- D --------------------------------
+    public static String doubleToString(double doubleNumber, int bit) {
+        return String.format("%." + bit + "f", doubleNumber);
+    }
+
     /**
      * 复制一个字符串
      * @param charArray 字符数组

+ 1 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/feign/VideoService.java

@@ -18,6 +18,7 @@ public interface VideoService {
     ResponseBodyVO<String> generateVideo(
            @RequestParam("projectId") String projectId,
            @RequestParam("projectType") String projectType,
+           @RequestParam("maxSimulationTime") String maxSimulationTime,
            @RequestParam("taskId") String taskId
     );
 }

+ 1 - 1
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/feign/fallback/VideoServiceFallBack.java

@@ -6,7 +6,7 @@ import com.css.simulation.resource.scheduler.feign.VideoService;
 
 public class VideoServiceFallBack implements VideoService {
     @Override
-    public ResponseBodyVO<String> generateVideo(String projectId, String projectType, String taskId) {
+    public ResponseBodyVO<String> generateVideo(String projectId, String projectType,String maxSimulationTime, String taskId) {
         return new ResponseBodyVO<>(ResponseBodyVO.Response.SERVER_FAILURE);
     }
 }

+ 3 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/manager/TaskManager.java

@@ -92,7 +92,7 @@ public class TaskManager {
 
     @SneakyThrows
     @Transactional
-    public boolean isProjectCompleted(PrefixTO redisPrefix, String projectId, String projectType, String taskId, String state, String podName) {
+    public boolean isProjectCompleted(PrefixTO redisPrefix, String projectId, String projectType, String maxSimulationTime, String taskId, String state, String podName) {
         String nodeName = projectUtil.getNodeNameOfPod(podName);
         if ("Running".equals(state)) {  // 运行中的 pod 无需删除
             // 将运行中的任务的 pod 名称放入 redis
@@ -133,7 +133,8 @@ public class TaskManager {
                 } else if ("PendingAnalysis".equals(state)) {
                     taskMapper.updateSuccessStateWithStopTime(taskId, state, TimeUtil.getNowForMysql());
                     // 创建视频和生成
-                    videoService.generateVideo(projectId, projectType, taskId);
+
+                    videoService.generateVideo(projectId, projectType, maxSimulationTime, taskId);
                 }
                 // -------------------------------- 判断项目是否结束 --------------------------------
                 ProjectMessageDTO projectMessageDTO = JsonUtil.jsonToBean(stringRedisTemplate.opsForValue().get(redisPrefix.getProjectRunningKey()), ProjectMessageDTO.class);

+ 7 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/AutoSubProjectMapper.java

@@ -16,9 +16,14 @@ public interface AutoSubProjectMapper {
             @Result(column = "scene", property = "scenePackageId", jdbcType = JdbcType.VARCHAR),
             @Result(column = "create_user_id", property = "createUserId", jdbcType = JdbcType.VARCHAR),
             @Result(column = "parallelism", property = "parallelism", jdbcType = JdbcType.VARCHAR),
-            @Result(column = "project_type", property = "projectType", jdbcType = JdbcType.VARCHAR)
+            @Result(column = "project_type", property = "projectType", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "max_simulation_time", property = "maxSimulationTime", jdbcType = JdbcType.VARCHAR)
     })
-    @Select("select sas.id, sap.scene, sas.create_user_id\n" +
+    @Select("select sas.id,\n" +
+            "       sap.scene,\n" +
+            "       sas.create_user_id,\n" +
+            "       '2' project_type,\n" +
+            "       sap.max_simulation_time\n" +
             "from simulation_automatic_subproject sas\n" +
             "         left join simulation_automatic_project sap on sas.parent_id = sap.id\n" +
             "where sas.id = #{projectId}")

+ 7 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/ManualProjectMapper.java

@@ -17,9 +17,14 @@ public interface ManualProjectMapper {
             @Result(column = "scene", property = "scenePackageId", jdbcType = JdbcType.VARCHAR),
             @Result(column = "create_user_id", property = "createUserId", jdbcType = JdbcType.VARCHAR),
             @Result(column = "parallelism", property = "parallelism", jdbcType = JdbcType.VARCHAR),
-            @Result(column = "project_type", property = "projectType", jdbcType = JdbcType.VARCHAR)
+            @Result(column = "project_type", property = "projectType", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "max_simulation_time", property = "maxSimulationTime", jdbcType = JdbcType.VARCHAR)
     })
-    @Select("select id, scene, create_user_id\n" +
+    @Select("select id,\n" +
+            "       scene,\n" +
+            "       create_user_id,\n" +
+            "       '1' project_type,\n" +
+            "       max_simulation_time\n" +
             "from simulation_manual_project\n" +
             "where id = #{projectId}")
     ProjectPO selectById(@Param("projectId") String projectId);

+ 1 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/ProjectPO.java

@@ -16,6 +16,7 @@ public class ProjectPO {
     private String createUserId;
     private String parallelism;
     private String projectType;
+    private String maxSimulationTime;
 
 
 }

+ 5 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/service/TaskService.java

@@ -3,6 +3,7 @@ package com.css.simulation.resource.scheduler.service;
 import api.common.util.SshUtil;
 import com.css.simulation.resource.scheduler.manager.TaskManager;
 import com.css.simulation.resource.scheduler.mapper.TaskMapper;
+import com.css.simulation.resource.scheduler.pojo.po.ProjectPO;
 import com.css.simulation.resource.scheduler.pojo.po.TaskPO;
 import com.css.simulation.resource.scheduler.pojo.to.PrefixTO;
 import com.css.simulation.resource.scheduler.util.ProjectUtil;
@@ -43,11 +44,13 @@ public class TaskService {
             return;
         }
         String projectId = taskPO.getPId(); // 项目 id
-        String projectType = projectUtil.getProjectTypeByProjectId(projectId);  // 项目类型
+        ProjectPO projectPO = projectUtil.getProjectByProjectId(projectId);
+        String projectType = projectPO.getProjectType();  // 项目类型
+        String maxSimulationTime = projectPO.getMaxSimulationTime();  // 项目类型
         String userId = taskPO.getCreateUserId();   // 用户 id
         PrefixTO redisPrefix = projectUtil.getRedisPrefixByUserIdAndProjectIdAndTaskId(userId, projectId, taskId);  // 项目前缀
         //1 判断项目是否已完成
-        boolean projectCompleted = taskManager.isProjectCompleted(redisPrefix, projectId,projectType, taskId, state, podName);
+        boolean projectCompleted = taskManager.isProjectCompleted(redisPrefix, projectId, projectType, maxSimulationTime, taskId, state, podName);
         if (!projectCompleted) {
             return;
         }

+ 11 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/util/ProjectUtil.java

@@ -158,6 +158,17 @@ public class ProjectUtil {
         return projectType;
     }
 
+    public ProjectPO getProjectByProjectId(String projectId) {
+        ProjectPO manualProjectPO = manualProjectMapper.selectById(projectId);
+        ProjectPO autoSubProjectPO = autoSubProjectMapper.selectById(projectId);
+        if (manualProjectPO != null) {
+            return manualProjectPO;
+        } else if (autoSubProjectPO != null) {
+            return autoSubProjectPO;
+        }
+        throw new RuntimeException("ProjectUtil--getProjectByProjectId 不存在项目:" + projectId);
+    }
+
 
     /**
      * 获取正在运行的项目的并行度总和

+ 2 - 1
simulation-resource-video/src/main/java/com/css/simulation/resource/video/controller/VideoController.java

@@ -28,9 +28,10 @@ public class VideoController {
     ResponseBodyVO<String> generateVideo(
             @RequestParam("projectId") String projectId,
             @RequestParam("projectType") String projectType,
+            @RequestParam("maxSimulationTime") String maxSimulationTime,
             @RequestParam("taskId") String taskId
     ) {
-        return videoService.generateVideo(projectId, projectType, taskId);
+        return videoService.generateVideo(projectId, projectType, maxSimulationTime,taskId);
     }
 
 

+ 10 - 31
simulation-resource-video/src/main/java/com/css/simulation/resource/video/mapper/VehicleMapper.java

@@ -1,6 +1,5 @@
 package com.css.simulation.resource.video.mapper;
 
-import api.common.pojo.vo.model.VehicleVO;
 import com.css.simulation.resource.video.pojo.po.VehiclePO;
 import feign.Param;
 import org.apache.ibatis.annotations.Mapper;
@@ -13,7 +12,13 @@ import org.apache.ibatis.type.JdbcType;
 public interface VehicleMapper {
 
     @Results(id = "vehicle", value = {
-            @Result(column = "model_label", property = "modelLabel", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "id", property = "id", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "vehicle_code", property = "vehicleCode", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "vehicle_name", property = "vehicleName", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "description", property = "description", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "vehicle_type", property = "vehicleType", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "vehicle_front_view", property = "vehicleFrontView", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "vehicle_top_view", property = "vehicleTopView", jdbcType = JdbcType.VARCHAR),
             @Result(column = "max_speed", property = "maxSpeed", jdbcType = JdbcType.DECIMAL),
             @Result(column = "engine_power", property = "enginePower", jdbcType = JdbcType.DECIMAL),
             @Result(column = "max_deceleration", property = "maxDeceleration", jdbcType = JdbcType.DECIMAL),
@@ -31,39 +36,13 @@ public interface VehicleMapper {
             @Result(column = "right_distance", property = "rightDistance", jdbcType = JdbcType.DECIMAL),
             @Result(column = "height_distance", property = "heightDistance", jdbcType = JdbcType.DECIMAL),
             @Result(column = "wheelbase", property = "wheelbase", jdbcType = JdbcType.DECIMAL),
+            @Result(column = "share", property = "share", jdbcType = JdbcType.VARCHAR)
     })
-    @Select("select model_label,\n" +
-            "       max_speed,\n" +
-            "       engine_power,\n" +
-            "       max_deceleration,\n" +
-            "       max_steering_angle,\n" +
-            "       mass,\n" +
-            "       front_surface_effective,\n" +
-            "       air_drag_coefficient,\n" +
-            "       rolling_resistance_coefficient,\n" +
-            "       wheel_diameter,\n" +
-            "       wheel_drive,\n" +
-            "       overall_efficiency,\n" +
-            "       front_distance,\n" +
-            "       rear_distance,\n" +
-            "       left_distance,\n" +
-            "       right_distance,\n" +
-            "       height_distance,\n" +
-            "       wheelbase\n" +
-            "from model_vehicle\n" +
-            "where is_deleted = '0'\n" +
-            "  and id = (\n" +
-            "    select mc.vehicle_id\n" +
-            "    from model_config mc\n" +
-            "    where mc.id = #{vehicleConfigId}\n" +
-            ")")
-    VehiclePO selectByVehicleConfigId(@Param("vehicleConfigId") String vehicleConfigId);
-
     @Select("select id,\n" +
             "       vehicle_code,\n" +
             "       vehicle_name,\n" +
             "       description,\n" +
-            "       vehicle_type vehicle_type_string,\n" +
+            "       vehicle_type ,\n" +
             "       model_label,\n" +
             "       vehicle_front_view,\n" +
             "       vehicle_top_view,\n" +
@@ -87,5 +66,5 @@ public interface VehicleMapper {
             "       share\n" +
             "from model_vehicle\n" +
             "where  id = #{vehicleId}\n")
-    VehicleVO getVehicleInfo(@Param("vehicleId") String vehicleId);
+    VehiclePO getVehicleInfo(@Param("vehicleId") String vehicleId);
 }

+ 33 - 31
simulation-resource-video/src/main/java/com/css/simulation/resource/video/pojo/po/VehiclePO.java

@@ -1,59 +1,61 @@
 package com.css.simulation.resource.video.pojo.po;
 
-import lombok.AllArgsConstructor;
-import lombok.Builder;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 import java.math.BigDecimal;
 
 @Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
 public class VehiclePO {
 
-    /**
-     * 车辆模型
-     * "model": {
-     * "model_label": "AudiA6_10"
-     * },
-     * "dynamics": {
-     * "dynamics_maxspeed": 67,
-     * "dynamics_enginepower": 150000,
-     * "dynamics_maxdecel": 9.5,
-     * "dynamics_maxsteering": 0.48,
-     * "dynamics_mass": 1700,
-     * "dynamics_frontsurfaceeffective": 2.2,
-     * "dynamics_airdragcoefficient": 0.31,
-     * "dynamics_rollingresistance": 0,
-     * "dynamics_wheeldiameter": 0.684,
-     * "dynamics_wheeldrive": "wheel_drive_front",
-     * "dynamics_overallefficiency": 0.75,
-     * "dynamics_distfront": 3.838,
-     * "dynamics_distrear": 1.086,
-     * "dynamics_distleft": 0.94,
-     * "dynamics_distright": 0.94,
-     * "dynamics_distheight": 1.444,
-     * "dynamics_wheelbase": 2.91
-     * },
-     */
+    //主键id
+    private String id;
+    //车辆编码
+    private String vehicleCode;
+    //车辆名称
+    private String vehicleName;
+    //车辆描述
+    private String description;
+    //车辆模型标签
     private String modelLabel;
+    //车辆模型字符串
+    private String vehicleType;
+    private String vehicleFrontView;
+    //车辆俯视图
+    private String vehicleTopView;
+    //最大速度(千米/小时)
     private BigDecimal maxSpeed;
+    //发动机功率(千瓦)
     private BigDecimal enginePower;
+    //最大减速度(米/秒2)
     private BigDecimal maxDeceleration;
+    //最大转角(度)
     private BigDecimal maxSteeringAngle;
+    //质量(千克)
     private BigDecimal mass;
+    //前表面有效面积(平方米)
     private BigDecimal frontSurfaceEffective;
+    //空气阻力系数
     private BigDecimal airDragCoefficient;
+    //滚动阻力系数
     private BigDecimal rollingResistanceCoefficient;
+    //车轮直径(米)
     private BigDecimal wheelDiameter;
+    //驱动方式
     private String wheelDrive;
+    //总效率
     private BigDecimal overallEfficiency;
+    //车前距(米)
     private BigDecimal frontDistance;
+    //车后距(米)
     private BigDecimal rearDistance;
+    //车左距(米)
     private BigDecimal leftDistance;
+    //车右距(米)
     private BigDecimal rightDistance;
+    //车高(米)
     private BigDecimal heightDistance;
+    //轴距(米)
     private BigDecimal wheelbase;
+    //是否分享
+    private String share;
 }

+ 21 - 23
simulation-resource-video/src/main/java/com/css/simulation/resource/video/service/VideoService.java

@@ -2,12 +2,13 @@ package com.css.simulation.resource.video.service;
 
 import api.common.pojo.common.ResponseBodyVO;
 import api.common.pojo.po.scene.VehicleTypePO;
-import api.common.pojo.vo.model.VehicleVO;
 import api.common.util.FileUtil;
 import api.common.util.LinuxUtil;
+import api.common.util.StringUtil;
 import com.css.simulation.resource.video.mapper.ConfigMapper;
 import com.css.simulation.resource.video.mapper.SimulationAutomaticProjectMapper;
 import com.css.simulation.resource.video.mapper.VehicleMapper;
+import com.css.simulation.resource.video.pojo.po.VehiclePO;
 import com.css.simulation.resource.video.util.MinioUtil;
 import io.minio.MinioClient;
 import lombok.SneakyThrows;
@@ -26,6 +27,7 @@ import java.io.File;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.Iterator;
@@ -50,6 +52,7 @@ public class VideoService {
     public static final String oldXoscRelativePath = "xosc/simulation_my0.xosc";
     public static final String csv1Name = "Ego.csv";
     public static final String csv2Name = "evaluation.csv";
+    public static final String videoName = "simulation_output.mp4";
 
     //* -------------------------------- Comment --------------------------------
     @Value("${scheduler.linux-path.temp}")
@@ -68,7 +71,7 @@ public class VideoService {
      * 生成视频
      */
     @SneakyThrows
-    public ResponseBodyVO<String> generateVideo(String projectId, String projectType, String taskId) {
+    public ResponseBodyVO<String> generateVideo(String projectId, String projectType, String maxSimulationTime, String taskId) {
         //1 获取两个 csv 的目录,和 xodr 和 osgb 三个路径
         String rootDirectoryPathOfMinio = projectResultPathOfMinio + projectId + "/" + taskId + "/";
         String xodrPathOfMinio = rootDirectoryPathOfMinio + taskId + ".xodr";
@@ -91,23 +94,21 @@ public class VideoService {
         //4 生成图片
         String pictureDirectoryPath = rootDirectoryPathOfLinux + "picture";
         FileUtil.createDirectory(pictureDirectoryPath);
-        String esminiCommandTemp = esminiCommand + " "
-                + xoscPath + " " + pictureDirectoryPath + "/screenshot";
+        String esminiCommandTemp = esminiCommand + " " + xoscPath + " " + pictureDirectoryPath + "/screenshot " + StringUtil.doubleToString(Double.parseDouble(maxSimulationTime), 2);
         String esminiResult = LinuxUtil.execute(esminiCommandTemp);
         //5 生成视频
-        String videoName = "simulation_output.mp4";
-        String videoTargetPathOfLinux = rootDirectoryPathOfLinux + "video";
-        FileUtil.createDirectory(videoTargetPathOfLinux);
-        String videoTargetPathOfMinio = projectResultPathOfMinio + projectId + "/" + taskId + "/" + videoName;
+        String videoTargetPathOfLinux = rootDirectoryPathOfLinux + "video/" + videoName;
+        FileUtil.createParentDirectory(videoTargetPathOfLinux);
+        String videoTargetPathOfMinio = rootDirectoryPathOfMinio + videoName;
 
         String execute = LinuxUtil.execute("ffmpeg"
                 + " -f image2 -framerate 30 "
                 + " -i " + pictureDirectoryPath + "/screenshot_%05d.tga"
                 + " -c:v libx264 -vf format=yuv420p -crf 20 "
-                + videoTargetPathOfLinux + "/" + videoName
+                + videoTargetPathOfLinux
         );
         //6 将视频上传到 minio
-        MinioUtil.uploadFromFile(minioClient, videoTargetPathOfLinux + videoName, bucketName, videoTargetPathOfMinio);
+        MinioUtil.uploadFromFile(minioClient, videoTargetPathOfLinux, bucketName, videoTargetPathOfMinio);
         return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
     }
 
@@ -279,11 +280,11 @@ public class VideoService {
         String vehicleId = configMapper.getVehicleId(vehicle);
 
         log.info("VideoService--vehicleById 车辆 Id 为:" + vehicleId);
-        VehicleVO vehicleInfo = vehicleMapper.getVehicleInfo(vehicleId);
+        VehiclePO vehicleInfo = vehicleMapper.getVehicleInfo(vehicleId);
         log.info("VideoService--vehicleById 车辆信息为:" + vehicleInfo);
 
         //自车模型
-        String car = vehicleInfo.getVehicleTypeStr().substring(0, vehicleInfo.getVehicleTypeStr().indexOf(","));
+        String car = vehicleInfo.getVehicleType().substring(0, vehicleInfo.getVehicleType().indexOf(","));
         car = car.substring(0, 1).toLowerCase() + car.substring(1);
         if (car.contains("truck")) {
             po.setVehicleCategory("truck");
@@ -299,12 +300,8 @@ public class VideoService {
             po.setVehicleCategory("motorbike");
         } else if (car.contains("bicycle")) {
             po.setVehicleCategory("bicycle");
-        } else if (car.contains("bicycle")) {
-            po.setVehicleCategory("bicycle");
         } else if (car.contains("train")) {
             po.setVehicleCategory("train");
-        } else if (car.contains("tram")) {
-            po.setVehicleCategory("tram");
         } else {
             po.setVehicleCategory("car");
         }
@@ -314,16 +311,17 @@ public class VideoService {
         //车后距
         BigDecimal mo2 = new BigDecimal("2");
         BigDecimal rearDistance = vehicleInfo.getRearDistance();
+        BigDecimal CenterX;
+        BigDecimal divide = (frontDistance.add(rearDistance)).divide(mo2, 6, RoundingMode.CEILING);
         if (frontDistance.compareTo(rearDistance) > 0) {
-            BigDecimal CenterX = (frontDistance.add(rearDistance)).divide(mo2).subtract(rearDistance);
-            po.setCenterX(CenterX);
+            CenterX = divide.subtract(rearDistance);
         } else {
-            BigDecimal CenterX = (frontDistance.add(rearDistance)).divide(mo2).subtract(frontDistance);
-            po.setCenterX(CenterX);
+            CenterX = divide.subtract(frontDistance);
         }
+        po.setCenterX(CenterX);
         //车高
         BigDecimal mo3 = new BigDecimal("3");
-        po.setCenterZ(vehicleInfo.getHeightDistance().divide(mo3));
+        po.setCenterZ(vehicleInfo.getHeightDistance().divide(mo3, 6, RoundingMode.CEILING));
         //车左距  车右距
         BigDecimal LeftDistance = vehicleInfo.getLeftDistance();
         BigDecimal RightDistance = vehicleInfo.getRightDistance();
@@ -335,11 +333,11 @@ public class VideoService {
         po.setPerformanceMaxDeceleration(vehicleInfo.getMaxDeceleration());
         BigDecimal moπ = new BigDecimal("3.141516");
         BigDecimal mo180 = new BigDecimal("180");
-        po.setFrontAxleMaxSteering(vehicleInfo.getMaxSteeringAngle().multiply(moπ).divide(mo180));
+        po.setFrontAxleMaxSteering(vehicleInfo.getMaxSteeringAngle().multiply(moπ).divide(mo180, 6, RoundingMode.CEILING));
         po.setFrontAxleWheelDiameter(vehicleInfo.getWheelDiameter());
         BigDecimal mo4 = new BigDecimal("4");
         BigDecimal mo5 = new BigDecimal("5");
-        po.setFrontAxleTrackWidth(LeftDistance.add(RightDistance).multiply(mo4).divide(mo5));
+        po.setFrontAxleTrackWidth(LeftDistance.add(RightDistance).multiply(mo4).divide(mo5, 6, RoundingMode.CEILING));
         po.setFrontAxlePositionX(po.getCenterX());
         po.setFrontAxlePositionZ(po.getCenterZ());