trigger_init.go 17 KB

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