start_project.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package handler
  2. import (
  3. "dcl_dispatch_server/src/package/domain"
  4. "dcl_dispatch_server/src/package/entity"
  5. "dcl_dispatch_server/src/package/global"
  6. "dcl_dispatch_server/src/package/infra"
  7. "github.com/gin-gonic/gin"
  8. "net/http"
  9. )
  10. /*
  11. {
  12. "projectId": "项目ID",
  13. "algorithmObjectKey": "算法在阿里云的存储路径",
  14. "userId": "用户ID",
  15. "parallelism": 10,
  16. "tasks": [
  17. {
  18. "info": {
  19. "project_id": "项目ID",
  20. "task_id": "任务ID",
  21. "task_path": "任务结果路径",
  22. "default_time": "最大仿真时间"
  23. },
  24. "scenario": {
  25. "scenario_osc": "xosc或xml路径",
  26. "scenario_odr": "xodr路径",
  27. "scenario_osgb": "osgb路径"
  28. },
  29. "vehicle": {
  30. "model": {
  31. "model_label": "模型标签"
  32. },
  33. "dynamics": {
  34. "dynamics_maxspeed": 0.0, //最大速度(千米/小时)
  35. "dynamics_enginepower": 0.0, // 发动机功率(千瓦)
  36. "dynamics_maxdecel": 0.0, // 最大减速度(米/秒2)
  37. "dynamics_maxsteering": 0.0, // 最大减速度(米/秒2)
  38. "dynamics_mass": 0.0, // 质量(千克)
  39. "dynamics_frontsurfaceeffective": 0.0, // 前表面有效面积(平方米)
  40. "dynamics_airdragcoefficient": 0.0, // 空气阻力系数
  41. "dynamics_rollingresistance": 0.0, // 滚动阻力系数
  42. "dynamics_wheeldiameter": 0.0, // 车轮直径(米)
  43. "dynamics_wheeldrive": "wheel_drive_front", // 驱动方式
  44. "dynamics_overallefficiency": 0.0, // 总效率
  45. "dynamics_distfront": 0.0, // 车前距(米)
  46. "dynamics_distrear": 0.0, // 车后距(米)
  47. "dynamics_distleft": 0.0, // 车左距(米)
  48. "dynamics_distright": 0.0, // 车右距(米)
  49. "dynamics_distheight": 0.0, // 车高(米)
  50. "dynamics_wheelbase": 0.0 // 轴距(米)
  51. },
  52. "sensors": {
  53. "camera": [
  54. {
  55. "sensor_name": "",
  56. "sensor_near": 0,
  57. "sensor_far": 0,
  58. "sensor_x": 0,
  59. "sensor_y": 0,
  60. "sensor_z": 0,
  61. "sensor_h": 0,
  62. "sensor_p": 0,
  63. "sensor_r": 0,
  64. "sensor_fovH": 0, // 水平视场角
  65. "sensor_fovV": 0, // 垂直视场角
  66. "sensor_resolution": 0, // 水平视场角偏移量
  67. "sensor_frameRate": 0 // 垂直视场角偏移量
  68. }
  69. ],
  70. "OGT": [
  71. {
  72. "sensor_name": "", // 传感器名称
  73. "sensor_near": 0, // 盲区距离
  74. "sensor_far": 0, // 探测距离
  75. "sensor_x": 0, // 传感器横向偏移量(x轴)
  76. "sensor_y": 0, // 传感器纵向偏移量(y轴)
  77. "sensor_z": 0, // 传感器安装高度(z轴)
  78. "sensor_h": 0, // 传感器横摆角
  79. "sensor_p": 0, // 传感器俯仰角
  80. "sensor_r": 0, // 传感器横滚角
  81. "sensor_fovHLeft": 0, // 水平现场角左
  82. "sensor_fovHRight": 0, // 水平现场角右
  83. "sensor_fovVTop": 0, // 垂直现场角顶
  84. "sensor_fovVBottom": 0, // 垂直现场角底
  85. "sensor_filter": "0,5,6", // 目标物筛选序列(0,1,2)
  86. "sensor_display": false, // 显示目标物
  87. "sensor_maxObjects": 0, // 最大目标物个数
  88. "sensor_port": 0 // 端口
  89. },
  90. {
  91. "sensor_name": "",
  92. "sensor_near": 0,
  93. "sensor_far": 0,
  94. "sensor_x": 0,
  95. "sensor_y": 0,
  96. "sensor_z": 0,
  97. "sensor_h": 0,
  98. "sensor_p": 0,
  99. "sensor_r": 0,
  100. "sensor_fovHLeft": 0,
  101. "sensor_fovHRight": 0,
  102. "sensor_fovVTop": 0,
  103. "sensor_fovVBottom": 0,
  104. "sensor_filter": "1,2,3,4",
  105. "sensor_display": false,
  106. "sensor_maxObjects": 0,
  107. "sensor_port": 0
  108. }
  109. ]
  110. }
  111. }
  112. }
  113. ]
  114. }
  115. */
  116. func StartProject(c *gin.Context) {
  117. //// 读取请求体
  118. //bodyBytes, err := io.ReadAll(c.Request.Body)
  119. //if err != nil {
  120. // c.String(500, "Error reading request body")
  121. // return
  122. //}
  123. //// 将请求体转换为字符串
  124. //bodyString := string(bodyBytes)
  125. //infra.GlobalLogger.Info("项目启动接收请求参数为:", bodyString)
  126. projectStartParam := new(entity.Project)
  127. if err := c.ShouldBindJSON(&projectStartParam); err != nil {
  128. infra.GlobalLogger.Error("项目启动接收请求参数报错:", err)
  129. c.JSON(http.StatusBadRequest, entity.HttpResult{Status: false, Code: "1003", Message: "请求参数格式错误。"})
  130. return
  131. }
  132. // ------------ 维护一个运行任务队列,绑定用户id和节点名称,供下面两个判断同时使用(使用redis的队列)
  133. userId := projectStartParam.UserId // 用户ID
  134. taskReceived := projectStartParam.Tasks // 接收到的所有任务
  135. userParallelism := projectStartParam.Parallelism // 用户的并行度上限
  136. algorithmObjectKey := projectStartParam.AlgorithmObjectKey
  137. // 1 判断用户并行度
  138. for _, task := range taskReceived {
  139. global.RunTaskMutex.Lock()
  140. // 1 判断用户并行度是否有剩余,有剩余则加入集群等待队列,并从用户等待队列中拿出,没有剩余则不需要改动
  141. if domain.CanRunUser(userId, userParallelism) { // 可以运行
  142. err := domain.AddWaitingCluster(userId, userParallelism, algorithmObjectKey, task)
  143. if err != nil {
  144. infra.GlobalLogger.Errorf("将任务 %v 添加到【集群等待队列】失败,错误信息为:%v", task, err)
  145. continue
  146. }
  147. infra.GlobalLogger.Infof("将任务 %v 添加到【集群等待队列】成功。", task.Info.TaskId)
  148. } else { // 不能运行
  149. err := domain.AddWaitingUser(userId, userParallelism, algorithmObjectKey, task)
  150. if err != nil {
  151. infra.GlobalLogger.Errorf("将任务 %v 添加到【用户等待队列】失败,错误信息为:%v", task, err)
  152. continue
  153. }
  154. infra.GlobalLogger.Infof("将任务 %v 添加到【用户等待队列】成功。", task.Info.TaskId)
  155. }
  156. global.RunTaskMutex.Unlock()
  157. }
  158. // 4 返回
  159. c.JSON(http.StatusOK, entity.HttpResult{Status: true, Code: "2000", Message: "项目启动请求已被成功接收,等待调度处理。"})
  160. }