trigger_init.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package config
  2. import (
  3. "cicv-data-closedloop/aarch64/pjisuv/common/config"
  4. "cicv-data-closedloop/common/config/c_log"
  5. "cicv-data-closedloop/common/util"
  6. "cicv-data-closedloop/pjisuv_msgs"
  7. entity "cicv-data-closedloop/pjisuv_param"
  8. "github.com/bluenviron/goroslib/v2/pkg/msgs/geometry_msgs"
  9. "github.com/bluenviron/goroslib/v2/pkg/msgs/nav_msgs"
  10. "github.com/bluenviron/goroslib/v2/pkg/msgs/sensor_msgs"
  11. "github.com/bluenviron/goroslib/v2/pkg/msgs/tf2_msgs"
  12. "github.com/bluenviron/goroslib/v2/pkg/msgs/visualization_msgs"
  13. "plugin"
  14. "slices"
  15. )
  16. func InitTriggerConfig() {
  17. triggerLocalPathsMapTriggerId := make(map[string]string)
  18. c_log.GlobalLogger.Info("主节点加载触发器插件 - 开始。")
  19. // 1 获取数采任务的触发器列表
  20. cloudTriggers := &config.PlatformConfig.TaskTriggers
  21. // 2 获取本地触发器列表(触发器目录的一级子目录为【触发器ID_触发器Label】)
  22. localTriggerIds := util.GetFirstLevelSubdirectories(config.CloudConfig.TriggersDir)
  23. // 3 对比触发器列表,本地没有的则下载
  24. for _, trigger := range *cloudTriggers {
  25. id := util.ToString(trigger.TriggerId)
  26. hasIdDir := slices.Contains(localTriggerIds, id) // 改成了 slices 工具库
  27. triggerLocalDir := config.CloudConfig.TriggersDir + id + "/"
  28. hasLabelSo, soPaths := util.CheckSoFilesInDirectory(triggerLocalDir)
  29. var triggerLocalPath string
  30. if hasIdDir && hasLabelSo { // 已存在的触发器不需要再次下载
  31. triggerLocalPath = soPaths[0]
  32. c_log.GlobalLogger.Info("触发器插件 ", triggerLocalPath, " 存在。")
  33. triggerLocalPathsMapTriggerId[triggerLocalPath] = id
  34. continue
  35. }
  36. label := util.GetFileNameWithoutExtension(config.CloudConfig.TriggersDir + trigger.TriggerScriptPath)
  37. triggerLocalPath = config.CloudConfig.TriggersDir + id + "/" + label + ".so"
  38. c_log.GlobalLogger.Info("下载触发器插件从 ", trigger.TriggerScriptPath, " 到 ", triggerLocalPath)
  39. config.OssMutex.Lock()
  40. _ = util.CreateParentDir(triggerLocalPath)
  41. err := config.OssBucket.GetObjectToFile(trigger.TriggerScriptPath, triggerLocalPath)
  42. config.OssMutex.Unlock()
  43. if err != nil {
  44. c_log.GlobalLogger.Error("下载 OSS 上的触发器插件失败:", err)
  45. continue
  46. }
  47. triggerLocalPathsMapTriggerId[triggerLocalPath] = id
  48. }
  49. success := 0
  50. // 加载所有触发器的文件
  51. for triggerLocalPath, triggerId := range triggerLocalPathsMapTriggerId {
  52. // 载入插件到数组
  53. open, err := plugin.Open(triggerLocalPath)
  54. if err != nil {
  55. c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "失败。", err)
  56. continue
  57. }
  58. topic0, err := open.Lookup("Topic")
  59. if err != nil {
  60. c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Topic方法失败。", err)
  61. continue
  62. }
  63. topic1, ok := topic0.(func() string)
  64. if ok != true {
  65. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func() string):", err)
  66. continue
  67. }
  68. topic2 := topic1()
  69. rule, err := open.Lookup("Rule")
  70. if err != nil {
  71. c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Rule方法失败。", err)
  72. continue
  73. }
  74. if TopicOfCicvExtend == topic2 { // 自定义扩展
  75. f, ok := rule.(func(param entity.PjisuvParam) string)
  76. if ok != true {
  77. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(param entity.ExtendParam):", err)
  78. continue
  79. }
  80. RuleOfCicvExtend = append(RuleOfCicvExtend, f)
  81. } else if TopicOfAmrPose == topic2 { //1
  82. f, ok := rule.(func(data *visualization_msgs.MarkerArray) string)
  83. if ok != true {
  84. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err)
  85. continue
  86. }
  87. RuleOfAmrPose = append(RuleOfAmrPose, f)
  88. } else if TopicOfBoundingBoxesFast == topic2 { //2
  89. f, ok := rule.(func(data *pjisuv_msgs.BoundingBoxArray) string)
  90. if ok != true {
  91. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.BoundingBoxArray) string):", err)
  92. continue
  93. }
  94. RuleOfBoundingBoxesFast = append(RuleOfBoundingBoxesFast, f)
  95. } else if TopicOfCameraFault == topic2 { //3
  96. f, ok := rule.(func(data *pjisuv_msgs.FaultVec) string)
  97. if ok != true {
  98. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.FaultVec) string):", err)
  99. continue
  100. }
  101. RuleOfCameraFault = append(RuleOfCameraFault, f)
  102. } else if TopicOfCanData == topic2 { //4
  103. f, ok := rule.(func(data *pjisuv_msgs.Frame) string)
  104. if ok != true {
  105. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Frame) string):", err)
  106. continue
  107. }
  108. RuleOfCanData = append(RuleOfCanData, f)
  109. } else if TopicOfCh128x1LslidarPointCloud == topic2 { //5
  110. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  111. if ok != true {
  112. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  113. continue
  114. }
  115. RuleOfCh128x1LslidarPointCloud = append(RuleOfCh128x1LslidarPointCloud, f)
  116. } else if TopicOfCh64wLLslidarPointCloud == topic2 { //6
  117. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  118. if ok != true {
  119. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  120. continue
  121. }
  122. RuleOfCh64wLLslidarPointCloud = append(RuleOfCh64wLLslidarPointCloud, f)
  123. } else if TopicOfCh64wLScan == topic2 { //7
  124. f, ok := rule.(func(data *sensor_msgs.LaserScan) string)
  125. if ok != true {
  126. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.LaserScan) string):", err)
  127. continue
  128. }
  129. RuleOfCh64wLScan = append(RuleOfCh64wLScan, f)
  130. } else if TopicOfCh64wRLslidarPointCloud == topic2 { //8
  131. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  132. if ok != true {
  133. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  134. continue
  135. }
  136. RuleOfCh64wRLslidarPointCloud = append(RuleOfCh64wRLslidarPointCloud, f)
  137. } else if TopicOfCh64wRScan == topic2 { //9
  138. f, ok := rule.(func(data *sensor_msgs.LaserScan) string)
  139. if ok != true {
  140. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.LaserScan) string):", err)
  141. continue
  142. }
  143. RuleOfCh64wRScan = append(RuleOfCh64wRScan, f)
  144. } else if TopicOfCicvLidarclusterMovingObjects == topic2 { //10
  145. f, ok := rule.(func(data *pjisuv_msgs.PerceptionCicvMovingObjects) string)
  146. if ok != true {
  147. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PerceptionCicvMovingObjects) string):", err)
  148. continue
  149. }
  150. RuleOfCicvLidarclusterMovingObjects = append(RuleOfCicvLidarclusterMovingObjects, f)
  151. } else if TopicOfCicvAmrTrajectory == topic2 { //11
  152. f, ok := rule.(func(data *pjisuv_msgs.Trajectory, param entity.PjisuvParam) string)
  153. if ok != true {
  154. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Trajectory,param entity.PjisuvParam) string):", err)
  155. continue
  156. }
  157. RuleOfCicvAmrTrajectory = append(RuleOfCicvAmrTrajectory, f)
  158. } else if TopicOfCicvLocation == topic2 { //12
  159. f1, ok1 := rule.(func(data *pjisuv_msgs.PerceptionLocalization) string)
  160. if ok1 {
  161. RuleOfCicvLocation1 = append(RuleOfCicvLocation1, f1)
  162. } else {
  163. f2, ok2 := rule.(func(data *pjisuv_msgs.PerceptionLocalization, param entity.PjisuvParam) string)
  164. if ok2 {
  165. RuleOfCicvLocation2 = append(RuleOfCicvLocation2, f2)
  166. } else {
  167. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Rule方法参数格式错误:", err)
  168. continue
  169. }
  170. }
  171. } else if TopicOfCloudClusters == topic2 { //13
  172. f, ok := rule.(func(data *pjisuv_msgs.AutowareCloudClusterArray) string)
  173. if ok != true {
  174. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.AutowareCloudClusterArray) string):", err)
  175. continue
  176. }
  177. RuleOfCloudClusters = append(RuleOfCloudClusters, f)
  178. } else if TopicOfHeartbeatInfo == topic2 { //14
  179. f, ok := rule.(func(data *pjisuv_msgs.HeartBeatInfo) string)
  180. if ok != true {
  181. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.HeartBeatInfo) string):", err)
  182. continue
  183. }
  184. RuleOfHeartbeatInfo = append(RuleOfHeartbeatInfo, f)
  185. } else if TopicOfLidarPretreatmentCost == topic2 { //15
  186. f, ok := rule.(func(data *geometry_msgs.Vector3Stamped) string)
  187. if ok != true {
  188. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *geometry_msgs.Vector3Stamped) string):", err)
  189. continue
  190. }
  191. RuleOfLidarPretreatmentCost = append(RuleOfLidarPretreatmentCost, f)
  192. } else if TopicOfLidarPretreatmentOdometry == topic2 { //16
  193. f, ok := rule.(func(data *nav_msgs.Odometry) string)
  194. if ok != true {
  195. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Odometry) string):", err)
  196. continue
  197. }
  198. RuleOfLidarPretreatmentOdometry = append(RuleOfLidarPretreatmentOdometry, f)
  199. } else if TopicOfLidarRoi == topic2 { //17
  200. f, ok := rule.(func(data *geometry_msgs.PolygonStamped) string)
  201. if ok != true {
  202. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *geometry_msgs.PolygonStamped) string):", err)
  203. continue
  204. }
  205. RuleOfLidarRoi = append(RuleOfLidarRoi, f)
  206. } else if TopicOfLine1 == topic2 { //18
  207. f, ok := rule.(func(data *nav_msgs.Path) string)
  208. if ok != true {
  209. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err)
  210. continue
  211. }
  212. RuleOfLine1 = append(RuleOfLine1, f)
  213. } else if TopicOfLine2 == topic2 { //19
  214. f, ok := rule.(func(data *nav_msgs.Path) string)
  215. if ok != true {
  216. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err)
  217. continue
  218. }
  219. RuleOfLine2 = append(RuleOfLine2, f)
  220. } else if TopicOfMapPolygon == topic2 { //20
  221. f, ok := rule.(func(data *pjisuv_msgs.PolygonStamped, param entity.PjisuvParam) string)
  222. if ok != true {
  223. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PolygonStamped,param entity.PjisuvParam) string):", err)
  224. continue
  225. }
  226. RuleOfMapPolygon = append(RuleOfMapPolygon, f)
  227. } else if TopicOfObstacleDisplay == topic2 { //21
  228. f, ok := rule.(func(data *visualization_msgs.MarkerArray) string)
  229. if ok != true {
  230. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err)
  231. continue
  232. }
  233. RuleOfObstacleDisplay = append(RuleOfObstacleDisplay, f)
  234. } else if TopicOfPjControlPub == topic2 { //22
  235. f, ok := rule.(func(data *pjisuv_msgs.CommonVehicleCmd) string)
  236. if ok != true {
  237. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.CommonVehicleCmd) string):", err)
  238. continue
  239. }
  240. RuleOfPjControlPub = append(RuleOfPjControlPub, f)
  241. } else if TopicOfPointsCluster == topic2 { //23
  242. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  243. if ok != true {
  244. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  245. continue
  246. }
  247. RuleOfPointsCluster = append(RuleOfPointsCluster, f)
  248. } else if TopicOfPointsConcat == topic2 { //24
  249. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  250. if ok != true {
  251. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  252. continue
  253. }
  254. RuleOfPointsConcat = append(RuleOfPointsConcat, f)
  255. } else if TopicOfReferenceDisplay == topic2 { //25
  256. f, ok := rule.(func(data *nav_msgs.Path) string)
  257. if ok != true {
  258. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err)
  259. continue
  260. }
  261. RuleOfReferenceDisplay = append(RuleOfReferenceDisplay, f)
  262. } else if TopicOfReferenceTrajectory == topic2 { //26
  263. f, ok := rule.(func(data *pjisuv_msgs.Trajectory) string)
  264. if ok != true {
  265. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Trajectory) string):", err)
  266. continue
  267. }
  268. RuleOfReferenceTrajectory = append(RuleOfReferenceTrajectory, f)
  269. } else if TopicOfRoiPoints == topic2 { //27
  270. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  271. if ok != true {
  272. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  273. continue
  274. }
  275. RuleOfRoiPoints = append(RuleOfRoiPoints, f)
  276. } else if TopicOfRoiPolygon == topic2 { //28
  277. f, ok := rule.(func(data *nav_msgs.Path) string)
  278. if ok != true {
  279. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err)
  280. continue
  281. }
  282. RuleOfRoiPolygon = append(RuleOfRoiPolygon, f)
  283. } else if TopicOfTf == topic2 { //29
  284. f, ok := rule.(func(data *tf2_msgs.TFMessage) string)
  285. if ok != true {
  286. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *tf2_msgs.TFMessage) string):", err)
  287. continue
  288. }
  289. RuleOfTf = append(RuleOfTf, f)
  290. } else if TopicOfTpperception == topic2 { //30
  291. f, ok := rule.(func(data *pjisuv_msgs.PerceptionObjects, param entity.PjisuvParam) string)
  292. if ok != true {
  293. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PerceptionObjects, param entity.ExtendParam) string):", err)
  294. continue
  295. }
  296. RuleOfTpperception = append(RuleOfTpperception, f)
  297. } else if TopicOfTpperceptionVis == topic2 { //31
  298. f, ok := rule.(func(data *visualization_msgs.MarkerArray) string)
  299. if ok != true {
  300. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err)
  301. continue
  302. }
  303. RuleOfTpperceptionVis = append(RuleOfTpperceptionVis, f)
  304. } else if TopicOfTprouteplan == topic2 { //32
  305. f, ok := rule.(func(data *pjisuv_msgs.RoutePlan) string)
  306. if ok != true {
  307. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.RoutePlan) string):", err)
  308. continue
  309. }
  310. RuleOfTprouteplan = append(RuleOfTprouteplan, f)
  311. } else if TopicOfTrajectoryDisplay == topic2 { //33
  312. f, ok := rule.(func(data *nav_msgs.Path) string)
  313. if ok != true {
  314. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err)
  315. continue
  316. }
  317. RuleOfTrajectoryDisplay = append(RuleOfTrajectoryDisplay, f)
  318. } else if TopicOfUngroundCloudpoints == topic2 { //34
  319. f, ok := rule.(func(data *sensor_msgs.PointCloud2) string)
  320. if ok != true {
  321. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err)
  322. continue
  323. }
  324. RuleOfUngroundCloudpoints = append(RuleOfUngroundCloudpoints, f)
  325. } else if TopicOfCameraImage == topic2 { //35
  326. f, ok := rule.(func(data *sensor_msgs.Image) string)
  327. if ok != true {
  328. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.Image) string):", err)
  329. continue
  330. }
  331. RuleOfCameraImage = append(RuleOfCameraImage, f)
  332. } else if TopicOfDataRead == topic2 { //36
  333. f, ok := rule.(func(data *pjisuv_msgs.Retrieval) string)
  334. if ok != true {
  335. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Retrieval) string):", err)
  336. continue
  337. }
  338. RuleOfDataRead = append(RuleOfDataRead, f)
  339. } else if TopicOfPjVehicleFdbPub == topic2 { //39
  340. f, ok := rule.(func(data *pjisuv_msgs.VehicleFdb, param *entity.PjisuvParam) string)
  341. if ok != true {
  342. c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.VehicleFdb) string):", err)
  343. continue
  344. }
  345. RuleOfPjVehicleFdbPub = append(RuleOfPjVehicleFdbPub, f)
  346. } else {
  347. c_log.GlobalLogger.Error("未知的topic:", topic2)
  348. continue
  349. }
  350. label, err := open.Lookup("Label")
  351. if err != nil {
  352. c_log.GlobalLogger.Error("加载本地插件 ", triggerLocalPath, " 中的 Label 方法失败。", err)
  353. continue
  354. }
  355. labelFunc := label.(func() string)
  356. labelString := labelFunc()
  357. LabelMapTriggerId.Store(labelString, triggerId)
  358. success++
  359. }
  360. c_log.GlobalLogger.Info("一共应加载", len(config.PlatformConfig.TaskTriggers), "个触发器,实际加载 ", success, " 个触发器。")
  361. }