package config import ( "cicv-data-closedloop/aarch64/pjisuv/common/config" "cicv-data-closedloop/common/config/c_log" "cicv-data-closedloop/common/util" "cicv-data-closedloop/pjisuv_msgs" entity "cicv-data-closedloop/pjisuv_param" "github.com/bluenviron/goroslib/v2/pkg/msgs/geometry_msgs" "github.com/bluenviron/goroslib/v2/pkg/msgs/nav_msgs" "github.com/bluenviron/goroslib/v2/pkg/msgs/sensor_msgs" "github.com/bluenviron/goroslib/v2/pkg/msgs/tf2_msgs" "github.com/bluenviron/goroslib/v2/pkg/msgs/visualization_msgs" "plugin" ) func InitTriggerConfig() { var triggerLocalPaths []string c_log.GlobalLogger.Info("主节点加载触发器插件 - 开始。") // 1 获取数采任务的触发器列表 cloudTriggers := &config.PlatformConfig.TaskTriggers // 2 获取本地触发器列表(触发器目录的一级子目录为【触发器ID_触发器Label】) localTriggerIds := util.GetFirstLevelSubdirectories(config.CloudConfig.TriggersDir) // 3 对比触发器列表,本地没有的则下载 for _, trigger := range *cloudTriggers { id := util.ToString(trigger.TriggerId) var triggerLocalPath string triggerLocalDir := config.CloudConfig.TriggersDir + id + "/" _ = util.CreateParentDir(triggerLocalPath) hasIdDir, _ := util.ContainsElement(localTriggerIds, id) hasLabelSo, soPaths := util.CheckSoFilesInDirectory(triggerLocalDir) if hasIdDir && hasLabelSo { // 已存在的触发器不需要再次下载 triggerLocalPath = soPaths[0] c_log.GlobalLogger.Info("触发器插件从 ", triggerLocalPath, " 存在。") triggerLocalPaths = append(triggerLocalPaths, triggerLocalPath) continue } label := util.GetFileNameWithoutExtension(config.CloudConfig.TriggersDir + trigger.TriggerScriptPath) triggerLocalPath = config.CloudConfig.TriggersDir + id + "/" + label + ".so" c_log.GlobalLogger.Info("下载触发器插件从 ", trigger.TriggerScriptPath, " 到 ", triggerLocalPath) config.OssMutex.Lock() err := config.OssBucket.GetObjectToFile(trigger.TriggerScriptPath, triggerLocalPath) config.OssMutex.Unlock() if err != nil { c_log.GlobalLogger.Error("下载 OSS 上的触发器插件失败:", err) continue } triggerLocalPaths = append(triggerLocalPaths, triggerLocalPath) } // 下载所有触发器的文件 for _, triggerLocalPath := range triggerLocalPaths { // 载入插件到数组 open, err := plugin.Open(triggerLocalPath) if err != nil { c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "失败。", err) continue } topic0, err := open.Lookup("Topic") if err != nil { c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Topic方法失败。", err) continue } topic1, ok := topic0.(func() string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func() string):", err) continue } topic2 := topic1() rule, err := open.Lookup("Rule") if err != nil { c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Rule方法失败。", err) continue } if TopicOfCicvExtend == topic2 { // 自定义扩展 f, ok := rule.(func(param entity.PjisuvParam) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(param entity.ExtendParam):", err) continue } RuleOfCicvExtend = append(RuleOfCicvExtend, f) } else if TopicOfAmrPose == topic2 { //1 f, ok := rule.(func(data *visualization_msgs.MarkerArray) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err) continue } RuleOfAmrPose = append(RuleOfAmrPose, f) } else if TopicOfBoundingBoxesFast == topic2 { //2 f, ok := rule.(func(data *pjisuv_msgs.BoundingBoxArray) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.BoundingBoxArray) string):", err) continue } RuleOfBoundingBoxesFast = append(RuleOfBoundingBoxesFast, f) } else if TopicOfCameraFault == topic2 { //3 f, ok := rule.(func(data *pjisuv_msgs.FaultVec) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.FaultVec) string):", err) continue } RuleOfCameraFault = append(RuleOfCameraFault, f) } else if TopicOfCanData == topic2 { //4 f, ok := rule.(func(data *pjisuv_msgs.Frame) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Frame) string):", err) continue } RuleOfCanData = append(RuleOfCanData, f) } else if TopicOfCh128x1LslidarPointCloud == topic2 { //5 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfCh128x1LslidarPointCloud = append(RuleOfCh128x1LslidarPointCloud, f) } else if TopicOfCh64wLLslidarPointCloud == topic2 { //6 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfCh64wLLslidarPointCloud = append(RuleOfCh64wLLslidarPointCloud, f) } else if TopicOfCh64wLScan == topic2 { //7 f, ok := rule.(func(data *sensor_msgs.LaserScan) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.LaserScan) string):", err) continue } RuleOfCh64wLScan = append(RuleOfCh64wLScan, f) } else if TopicOfCh64wRLslidarPointCloud == topic2 { //8 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfCh64wRLslidarPointCloud = append(RuleOfCh64wRLslidarPointCloud, f) } else if TopicOfCh64wRScan == topic2 { //9 f, ok := rule.(func(data *sensor_msgs.LaserScan) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.LaserScan) string):", err) continue } RuleOfCh64wRScan = append(RuleOfCh64wRScan, f) } else if TopicOfCicvLidarclusterMovingObjects == topic2 { //10 f, ok := rule.(func(data *pjisuv_msgs.PerceptionCicvMovingObjects) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PerceptionCicvMovingObjects) string):", err) continue } RuleOfCicvLidarclusterMovingObjects = append(RuleOfCicvLidarclusterMovingObjects, f) } else if TopicOfCicvAmrTrajectory == topic2 { //11 f, ok := rule.(func(data *pjisuv_msgs.Trajectory, param entity.PjisuvParam) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Trajectory,param entity.PjisuvParam) string):", err) continue } RuleOfCicvAmrTrajectory = append(RuleOfCicvAmrTrajectory, f) } else if TopicOfCicvLocation == topic2 { //12 f, ok := rule.(func(data *pjisuv_msgs.PerceptionLocalization) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PerceptionLocalization) string):", err) continue } RuleOfCicvLocation = append(RuleOfCicvLocation, f) } else if TopicOfCloudClusters == topic2 { //13 f, ok := rule.(func(data *pjisuv_msgs.AutowareCloudClusterArray) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.AutowareCloudClusterArray) string):", err) continue } RuleOfCloudClusters = append(RuleOfCloudClusters, f) } else if TopicOfHeartbeatInfo == topic2 { //14 f, ok := rule.(func(data *pjisuv_msgs.HeartBeatInfo) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.HeartBeatInfo) string):", err) continue } RuleOfHeartbeatInfo = append(RuleOfHeartbeatInfo, f) } else if TopicOfLidarPretreatmentCost == topic2 { //15 f, ok := rule.(func(data *geometry_msgs.Vector3Stamped) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *geometry_msgs.Vector3Stamped) string):", err) continue } RuleOfLidarPretreatmentCost = append(RuleOfLidarPretreatmentCost, f) } else if TopicOfLidarPretreatmentOdometry == topic2 { //16 f, ok := rule.(func(data *nav_msgs.Odometry) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Odometry) string):", err) continue } RuleOfLidarPretreatmentOdometry = append(RuleOfLidarPretreatmentOdometry, f) } else if TopicOfLidarRoi == topic2 { //17 f, ok := rule.(func(data *geometry_msgs.PolygonStamped) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *geometry_msgs.PolygonStamped) string):", err) continue } RuleOfLidarRoi = append(RuleOfLidarRoi, f) } else if TopicOfLine1 == topic2 { //18 f, ok := rule.(func(data *nav_msgs.Path) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err) continue } RuleOfLine1 = append(RuleOfLine1, f) } else if TopicOfLine2 == topic2 { //19 f, ok := rule.(func(data *nav_msgs.Path) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err) continue } RuleOfLine2 = append(RuleOfLine2, f) } else if TopicOfMapPolygon == topic2 { //20 f, ok := rule.(func(data *pjisuv_msgs.PolygonStamped) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PolygonStamped) string):", err) continue } RuleOfMapPolygon = append(RuleOfMapPolygon, f) } else if TopicOfObstacleDisplay == topic2 { //21 f, ok := rule.(func(data *visualization_msgs.MarkerArray) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err) continue } RuleOfObstacleDisplay = append(RuleOfObstacleDisplay, f) } else if TopicOfPjControlPub == topic2 { //22 f, ok := rule.(func(data *pjisuv_msgs.CommonVehicleCmd) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.CommonVehicleCmd) string):", err) continue } RuleOfPjControlPub = append(RuleOfPjControlPub, f) } else if TopicOfPointsCluster == topic2 { //23 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfPointsCluster = append(RuleOfPointsCluster, f) } else if TopicOfPointsConcat == topic2 { //24 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfPointsConcat = append(RuleOfPointsConcat, f) } else if TopicOfReferenceDisplay == topic2 { //25 f, ok := rule.(func(data *nav_msgs.Path) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err) continue } RuleOfReferenceDisplay = append(RuleOfReferenceDisplay, f) } else if TopicOfReferenceTrajectory == topic2 { //26 f, ok := rule.(func(data *pjisuv_msgs.Trajectory) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Trajectory) string):", err) continue } RuleOfReferenceTrajectory = append(RuleOfReferenceTrajectory, f) } else if TopicOfRoiPoints == topic2 { //27 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfRoiPoints = append(RuleOfRoiPoints, f) } else if TopicOfRoiPolygon == topic2 { //28 f, ok := rule.(func(data *nav_msgs.Path) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err) continue } RuleOfRoiPolygon = append(RuleOfRoiPolygon, f) } else if TopicOfTf == topic2 { //29 f, ok := rule.(func(data *tf2_msgs.TFMessage) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *tf2_msgs.TFMessage) string):", err) continue } RuleOfTf = append(RuleOfTf, f) } else if TopicOfTpperception == topic2 { //30 f, ok := rule.(func(data *pjisuv_msgs.PerceptionObjects, param entity.PjisuvParam) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.PerceptionObjects, param entity.ExtendParam) string):", err) continue } RuleOfTpperception = append(RuleOfTpperception, f) } else if TopicOfTpperceptionVis == topic2 { //31 f, ok := rule.(func(data *visualization_msgs.MarkerArray) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *visualization_msgs.MarkerArray) string):", err) continue } RuleOfTpperceptionVis = append(RuleOfTpperceptionVis, f) } else if TopicOfTprouteplan == topic2 { //32 f, ok := rule.(func(data *pjisuv_msgs.RoutePlan) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.RoutePlan) string):", err) continue } RuleOfTprouteplan = append(RuleOfTprouteplan, f) } else if TopicOfTrajectoryDisplay == topic2 { //33 f, ok := rule.(func(data *nav_msgs.Path) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *nav_msgs.Path) string):", err) continue } RuleOfTrajectoryDisplay = append(RuleOfTrajectoryDisplay, f) } else if TopicOfUngroundCloudpoints == topic2 { //34 f, ok := rule.(func(data *sensor_msgs.PointCloud2) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.PointCloud2) string):", err) continue } RuleOfUngroundCloudpoints = append(RuleOfUngroundCloudpoints, f) } else if TopicOfCameraImage == topic2 { //35 f, ok := rule.(func(data *sensor_msgs.Image) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.Image) string):", err) continue } RuleOfCameraImage = append(RuleOfCameraImage, f) } else if TopicOfDataRead == topic2 { //36 f, ok := rule.(func(data *pjisuv_msgs.Retrieval) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.Retrieval) string):", err) continue } RuleOfDataRead = append(RuleOfDataRead, f) } else if TopicOfPjVehicleFdbPub == topic2 { //39 f, ok := rule.(func(data *pjisuv_msgs.VehicleFdb, param *entity.PjisuvParam) string) if ok != true { c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjisuv_msgs.VehicleFdb) string):", err) continue } RuleOfPjVehicleFdbPub = append(RuleOfPjVehicleFdbPub, f) } else { c_log.GlobalLogger.Error("未知的topic:", topic2) continue } _, err = open.Lookup("Label") if err != nil { c_log.GlobalLogger.Error("加载本地插件 ", triggerLocalPath, " 中的 Label 方法失败。", err) continue } } c_log.GlobalLogger.Info("一共有", len(config.PlatformConfig.TaskTriggers), "个触发器。") }