Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

zwh před 9 měsíci
rodič
revize
e4d54d1288

+ 4 - 2
aarch64/pjibot_delivery/common/service/disk_clean.go

@@ -79,8 +79,10 @@ func getIndexToRemoveForLRU() int {
 	for i >= 0 {
 		for i2, window := range entity.TimeWindowConsumerQueue {
 			for _, label := range window.Labels {
-				if masterConfig.LabelMapTriggerId[label] == lru[i] {
-					return i2
+				if value, ok := masterConfig.LabelMapTriggerId.Load(label); ok {
+					if value.(string) == lru[i] {
+						return i2
+					}
 				}
 			}
 		}

+ 3 - 1
aarch64/pjibot_delivery/common/service/rosbag_upload.go

@@ -123,7 +123,9 @@ outLoop:
 		// 在上传完成的包目录同级下添加一个目录同名的json
 		triggerIds := make([]string, 0)
 		for _, label := range currentTimeWindow.Labels {
-			triggerIds = append(triggerIds, masterConfig.LabelMapTriggerId[label])
+			if value, ok := masterConfig.LabelMapTriggerId.Load(label); ok {
+				triggerIds = append(triggerIds, value.(string))
+			}
 		}
 		callBackMap := map[string]interface{}{
 			"dataName":    currentTimeWindow.FaultTime, // 云端callback程序会将该值加8小时,因为UTC和CSV时区相差8小时

+ 97 - 71
aarch64/pjibot_delivery/master/package/config/trigger_init.go

@@ -11,28 +11,57 @@ import (
 	"github.com/bluenviron/goroslib/v2/pkg/msgs/sensor_msgs"
 	"github.com/bluenviron/goroslib/v2/pkg/msgs/std_msgs"
 	"plugin"
-	"strconv"
+	"slices"
 )
 
 func InitTriggerConfig() {
-	loadSuccess := 0
-	// 下载所有触发器的文件
-	for _, trigger := range config.PlatformConfig.TaskTriggers {
-		// 下载
-		triggerLocalPath := config.CloudConfig.TriggersDir + trigger.TriggerScriptPath
+	config.OssMutex.Lock()
+	defer config.OssMutex.Unlock()
+	triggerLocalPathsMapTriggerId := make(map[string]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)
+		hasIdDir := slices.Contains(localTriggerIds, id) // 改成了 slices 工具库
+		triggerLocalDir := config.CloudConfig.TriggersDir + id + "/"
+		hasLabelSo, soPaths := util.CheckSoFilesInDirectory(triggerLocalDir)
+		var triggerLocalPath string
+		if hasIdDir && hasLabelSo { // 已存在的触发器需要判断是否大小一致
+			triggerLocalPath = soPaths[0]
+			ossSize, _ := util.GetOSSFileSize(config.OssBucket, trigger.TriggerScriptPath)
+			localSize, _ := util.GetFileSize(triggerLocalPath)
+			if ossSize == localSize {
+				c_log.GlobalLogger.Info("触发器插件 ", triggerLocalPath, " 存在且与云端触发器大小一致。")
+				triggerLocalPathsMapTriggerId[triggerLocalPath] = id
+				continue
+			}
+		}
+		label := util.GetFileNameWithoutExtension(config.CloudConfig.TriggersDir + trigger.TriggerScriptPath)
+		triggerLocalPath = config.CloudConfig.TriggersDir + id + "/" + label + ".so"
+		c_log.GlobalLogger.Info("开始下载触发器插件从 ", trigger.TriggerScriptPath, " 到 ", triggerLocalPath)
 		_ = util.CreateParentDir(triggerLocalPath)
-		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.Errorf("下载oss上的触发器插件失败【%v】->【%v】:%v", trigger.TriggerScriptPath, triggerLocalPath, err)
-			continue
+		for {
+			if err := config.OssBucket.GetObjectToFile(trigger.TriggerScriptPath, triggerLocalPath); err != nil {
+				c_log.GlobalLogger.Error("下载触发器插件失败,再次尝试:", err)
+				continue
+			}
+			break
 		}
+		triggerLocalPathsMapTriggerId[triggerLocalPath] = id
+	}
+
+	success := 0
+	// 加载所有触发器的文件
+	for triggerLocalPath, triggerId := range triggerLocalPathsMapTriggerId {
 		// 载入插件到数组
 		open, err := plugin.Open(triggerLocalPath)
 		if err != nil {
 			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "失败。", err)
+			continue
 		}
 		topic0, err := open.Lookup("Topic")
 		if err != nil {
@@ -50,90 +79,87 @@ func InitTriggerConfig() {
 			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Rule方法失败。", err)
 			continue
 		}
-		// 判断topic
-		// todo 如果是未知的topic,可以添加一个循环,更新平台配置,同理金龙车和多功能车
+
 		if TopicOfDiagnostics == topic2 { // 1
-			f, ok := rule.(func(*diagnostic_msgs.DiagnosticArray) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *diagnostic_msgs.DiagnosticArray) string):", err)
-				continue
+			if f, ok1 := rule.(func(*diagnostic_msgs.DiagnosticArray) string); ok1 {
+				RuleOfDiagnostics = append(RuleOfDiagnostics, f)
+				goto JudgeDone
 			}
-			RuleOfDiagnostics = append(RuleOfDiagnostics, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfImu == topic2 { // 2
-			f, ok := rule.(func(data *sensor_msgs.Imu) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.Imu) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *sensor_msgs.Imu) string); ok1 {
+				RuleOfImu = append(RuleOfImu, f)
+				goto JudgeDone
 			}
-			RuleOfImu = append(RuleOfImu, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfLocateInfo == topic2 { // 3
-			f, ok := rule.(func(data *pjibot_delivery_msgs.LocateInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.LocateInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_delivery_msgs.LocateInfo) string); ok1 {
+				RuleOfLocateInfo = append(RuleOfLocateInfo, f)
+				goto JudgeDone
 			}
-			RuleOfLocateInfo = append(RuleOfLocateInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfObstacleDetection == topic2 { // 4
-			f, ok := rule.(func(data *std_msgs.UInt8) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *std_msgs.UInt8) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *std_msgs.UInt8) string); ok1 {
+				RuleOfObstacleDetection = append(RuleOfObstacleDetection, f)
+				goto JudgeDone
 			}
-			RuleOfObstacleDetection = append(RuleOfObstacleDetection, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfOdom == topic2 { // 5
-			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
+			if f, ok1 := rule.(func(data *nav_msgs.Odometry) string); ok1 {
+				RuleOfOdom = append(RuleOfOdom, f)
+				goto JudgeDone
 			}
-			RuleOfOdom = append(RuleOfOdom, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfSysInfo == topic2 { // 6
-			f, ok := rule.(func(data *pjibot_delivery_msgs.SysInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.SysInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_delivery_msgs.SysInfo) string); ok1 {
+				RuleOfSysInfo = append(RuleOfSysInfo, f)
+				goto JudgeDone
 			}
-			RuleOfSysInfo = append(RuleOfSysInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfRobotPose == topic2 { // 7
-			f, ok := rule.(func(data *geometry_msgs.PoseStamped) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.SysInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *geometry_msgs.PoseStamped) string); ok1 {
+				RuleOfRobotPose = append(RuleOfRobotPose, f)
+				goto JudgeDone
 			}
-			RuleOfRobotPose = append(RuleOfRobotPose, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfTaskFeedbackInfo == topic2 { // 8
-			f, ok := rule.(func(data *pjibot_delivery_msgs.TaskFeedbackInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjibot_delivery_msgs.TaskFeedbackInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_delivery_msgs.TaskFeedbackInfo) string); ok1 {
+				RuleOfTaskFeedbackInfo = append(RuleOfTaskFeedbackInfo, f)
+				goto JudgeDone
 			}
-			RuleOfTaskFeedbackInfo = append(RuleOfTaskFeedbackInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfWheelOdom == topic2 { // 9
-			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
+			if f, ok1 := rule.(func(data *nav_msgs.Odometry) string); ok1 {
+				RuleOfWheelOdom = append(RuleOfWheelOdom, f)
+				goto JudgeDone
 			}
-			RuleOfWheelOdom = append(RuleOfWheelOdom, f)
+			log(triggerLocalPath)
+			continue
 		} else {
 			c_log.GlobalLogger.Error("未知的topic:", topic2)
 			continue
 		}
-
+	JudgeDone:
 		label, err := open.Lookup("Label")
 		if err != nil {
-			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的TriggerName方法失败。", err)
-			continue
-		}
-		labelFunc, ok := label.(func() string)
-		if ok != true {
-			c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Label方法必须是(func() string):", err)
+			c_log.GlobalLogger.Error("加载本地插件 ", triggerLocalPath, " 中的 Label 方法失败。", err)
 			continue
 		}
+		labelFunc := label.(func() string)
 		labelString := labelFunc()
-		LabelMapTriggerId[labelString] = strconv.Itoa(trigger.TriggerId)
-		loadSuccess++
-		c_log.GlobalLogger.Info("主节点加载触发器插件:【ros topic】=", topic2, ",【触发器label】=", labelString, "【触发器ID】=", trigger.TriggerId)
+		LabelMapTriggerId.Store(labelString, triggerId)
+		success++
 	}
-	c_log.GlobalLogger.Infof("一共有%v个触发器,加载成功了%v个,【label和id映射关系】=%v", len(config.PlatformConfig.TaskTriggers), loadSuccess, LabelMapTriggerId)
+	c_log.GlobalLogger.Info("一共应加载", len(config.PlatformConfig.TaskTriggers), "个触发器,实际加载 ", success, " 个触发器。")
+}
+func log(triggerLocalPath string) {
+	c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的 Rule 方法参数格式不正确。")
 }

+ 2 - 1
aarch64/pjibot_delivery/master/package/config/trigger_var.go

@@ -7,10 +7,11 @@ import (
 	"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/std_msgs"
+	"sync"
 )
 
 var (
-	LabelMapTriggerId = make(map[string]string)
+	LabelMapTriggerId = new(sync.Map)
 
 	// 1
 	TopicOfDiagnostics = "/diagnostics"

+ 4 - 3
aarch64/pjibot_delivery/master/package/service/produce_window.go

@@ -40,9 +40,12 @@ func PrepareTimeWindowProducerQueue() {
 							faultLabel = f(data)
 							if faultLabel != "" {
 								if canCollect() {
+									c_log.GlobalLogger.Errorf("触发事件【%v】,开始采集。", faultLabel)
 									saveTimeWindow(faultLabel, faultHappenTime, lastTimeWindow)
 									subscribersTimes[i] = time.Now()
 									break
+								} else {
+									c_log.GlobalLogger.Errorf("触发事件【%v】,但当前周期内采集数量已超限额,不再采集。", faultLabel)
 								}
 							}
 						}
@@ -54,7 +57,6 @@ func PrepareTimeWindowProducerQueue() {
 		}
 		if err != nil {
 			c_log.GlobalLogger.Info("创建订阅者", masterConfig.TopicOfObstacleDetection, "发生故障:", err)
-			//TODO 如何回传日志
 			continue
 		}
 	}
@@ -148,9 +150,8 @@ func canCollect() bool {
 		return false
 	}
 	if resp.Code != 200 { // 不是200 代表不允许采集
-		c_log.GlobalLogger.Info("采集数量已超过限额,当前周期内不再采集。", resp.Code)
+		c_log.GlobalLogger.Infof("当前周期内采集数量已超过限额。%+v", resp)
 		return false
 	}
-	c_log.GlobalLogger.Info("允许采集。")
 	return true
 }

+ 4 - 2
aarch64/pjibot_patrol/common/service/disk_clean.go

@@ -79,8 +79,10 @@ func getIndexToRemoveForLRU() int {
 	for i >= 0 {
 		for i2, window := range entity.TimeWindowConsumerQueue {
 			for _, label := range window.Labels {
-				if masterConfig.LabelMapTriggerId[label] == lru[i] {
-					return i2
+				if value, ok := masterConfig.LabelMapTriggerId.Load(label); ok {
+					if value == lru[i] {
+						return i2
+					}
 				}
 			}
 		}

+ 3 - 1
aarch64/pjibot_patrol/common/service/rosbag_upload.go

@@ -123,7 +123,9 @@ outLoop:
 		// 在上传完成的包目录同级下添加一个目录同名的json
 		triggerIds := make([]string, 0)
 		for _, label := range currentTimeWindow.Labels {
-			triggerIds = append(triggerIds, masterConfig.LabelMapTriggerId[label])
+			if value, ok := masterConfig.LabelMapTriggerId.Load(label); ok {
+				triggerIds = append(triggerIds, value.(string))
+			}
 		}
 		callBackMap := map[string]interface{}{
 			"dataName":    currentTimeWindow.FaultTime, // 云端callback程序会将该值加8小时,因为UTC和CSV时区相差8小时

+ 97 - 70
aarch64/pjibot_patrol/master/package/config/trigger_init.go

@@ -11,28 +11,57 @@ import (
 	"github.com/bluenviron/goroslib/v2/pkg/msgs/sensor_msgs"
 	"github.com/bluenviron/goroslib/v2/pkg/msgs/std_msgs"
 	"plugin"
-	"strconv"
+	"slices"
 )
 
 func InitTriggerConfig() {
-	loadSuccess := 0
-	// 下载所有触发器的文件
-	for _, trigger := range config.PlatformConfig.TaskTriggers {
-		// 下载
-		triggerLocalPath := config.CloudConfig.TriggersDir + trigger.TriggerScriptPath
+	config.OssMutex.Lock()
+	defer config.OssMutex.Unlock()
+	triggerLocalPathsMapTriggerId := make(map[string]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)
+		hasIdDir := slices.Contains(localTriggerIds, id) // 改成了 slices 工具库
+		triggerLocalDir := config.CloudConfig.TriggersDir + id + "/"
+		hasLabelSo, soPaths := util.CheckSoFilesInDirectory(triggerLocalDir)
+		var triggerLocalPath string
+		if hasIdDir && hasLabelSo { // 已存在的触发器需要判断是否大小一致
+			triggerLocalPath = soPaths[0]
+			ossSize, _ := util.GetOSSFileSize(config.OssBucket, trigger.TriggerScriptPath)
+			localSize, _ := util.GetFileSize(triggerLocalPath)
+			if ossSize == localSize {
+				c_log.GlobalLogger.Info("触发器插件 ", triggerLocalPath, " 存在且与云端触发器大小一致。")
+				triggerLocalPathsMapTriggerId[triggerLocalPath] = id
+				continue
+			}
+		}
+		label := util.GetFileNameWithoutExtension(config.CloudConfig.TriggersDir + trigger.TriggerScriptPath)
+		triggerLocalPath = config.CloudConfig.TriggersDir + id + "/" + label + ".so"
+		c_log.GlobalLogger.Info("开始下载触发器插件从 ", trigger.TriggerScriptPath, " 到 ", triggerLocalPath)
 		_ = util.CreateParentDir(triggerLocalPath)
-		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.Errorf("下载oss上的触发器插件失败【%v】->【%v】:%v", trigger.TriggerScriptPath, triggerLocalPath, err)
-			continue
+		for {
+			if err := config.OssBucket.GetObjectToFile(trigger.TriggerScriptPath, triggerLocalPath); err != nil {
+				c_log.GlobalLogger.Error("下载触发器插件失败,再次尝试:", err)
+				continue
+			}
+			break
 		}
+		triggerLocalPathsMapTriggerId[triggerLocalPath] = id
+	}
+
+	success := 0
+	// 加载所有触发器的文件
+	for triggerLocalPath, triggerId := range triggerLocalPathsMapTriggerId {
 		// 载入插件到数组
 		open, err := plugin.Open(triggerLocalPath)
 		if err != nil {
 			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "失败。", err)
+			continue
 		}
 		topic0, err := open.Lookup("Topic")
 		if err != nil {
@@ -50,90 +79,88 @@ func InitTriggerConfig() {
 			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的Rule方法失败。", err)
 			continue
 		}
-		// 判断topic
-		// todo 如果是未知的topic,可以添加一个循环,更新平台配置,同理金龙车和多功能车
+
 		if TopicOfDiagnostics == topic2 { // 1
-			f, ok := rule.(func(*diagnostic_msgs.DiagnosticArray) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *diagnostic_msgs.DiagnosticArray) string):", err)
-				continue
+			if f, ok1 := rule.(func(*diagnostic_msgs.DiagnosticArray) string); ok1 {
+				RuleOfDiagnostics = append(RuleOfDiagnostics, f)
+				goto JudgeDone
 			}
-			RuleOfDiagnostics = append(RuleOfDiagnostics, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfImu == topic2 { // 2
-			f, ok := rule.(func(data *sensor_msgs.Imu) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *sensor_msgs.Imu) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *sensor_msgs.Imu) string); ok1 {
+				RuleOfImu = append(RuleOfImu, f)
+				goto JudgeDone
 			}
-			RuleOfImu = append(RuleOfImu, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfLocateInfo == topic2 { // 3
-			f, ok := rule.(func(data *pjibot_patrol_msgs.LocateInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.LocateInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_patrol_msgs.LocateInfo) string); ok1 {
+				RuleOfLocateInfo = append(RuleOfLocateInfo, f)
+				goto JudgeDone
 			}
-			RuleOfLocateInfo = append(RuleOfLocateInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfObstacleDetection == topic2 { // 4
-			f, ok := rule.(func(data *std_msgs.UInt8) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *std_msgs.UInt8) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *std_msgs.UInt8) string); ok1 {
+				RuleOfObstacleDetection = append(RuleOfObstacleDetection, f)
+				goto JudgeDone
 			}
-			RuleOfObstacleDetection = append(RuleOfObstacleDetection, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfOdom == topic2 { // 5
-			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
+			if f, ok1 := rule.(func(data *nav_msgs.Odometry) string); ok1 {
+				RuleOfOdom = append(RuleOfOdom, f)
+				goto JudgeDone
 			}
-			RuleOfOdom = append(RuleOfOdom, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfSysInfo == topic2 { // 6
-			f, ok := rule.(func(data *pjibot_patrol_msgs.SysInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.SysInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_patrol_msgs.SysInfo) string); ok1 {
+				RuleOfSysInfo = append(RuleOfSysInfo, f)
+				goto JudgeDone
 			}
-			RuleOfSysInfo = append(RuleOfSysInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfRobotPose == topic2 { // 7
-			f, ok := rule.(func(data *geometry_msgs.PoseStamped) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pji_msgs.SysInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *geometry_msgs.PoseStamped) string); ok1 {
+				RuleOfRobotPose = append(RuleOfRobotPose, f)
+				goto JudgeDone
 			}
-			RuleOfRobotPose = append(RuleOfRobotPose, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfTaskFeedbackInfo == topic2 { // 8
-			f, ok := rule.(func(data *pjibot_patrol_msgs.TaskFeedbackInfo) string)
-			if ok != true {
-				c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Topic方法必须是(func(data *pjibot_patrol_msgs.TaskFeedbackInfo) string):", err)
-				continue
+			if f, ok1 := rule.(func(data *pjibot_patrol_msgs.TaskFeedbackInfo) string); ok1 {
+				RuleOfTaskFeedbackInfo = append(RuleOfTaskFeedbackInfo, f)
+				goto JudgeDone
 			}
-			RuleOfTaskFeedbackInfo = append(RuleOfTaskFeedbackInfo, f)
+			log(triggerLocalPath)
+			continue
 		} else if TopicOfWheelOdom == topic2 { // 9
-			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
+			if f, ok1 := rule.(func(data *nav_msgs.Odometry) string); ok1 {
+				RuleOfWheelOdom = append(RuleOfWheelOdom, f)
+				goto JudgeDone
 			}
-			RuleOfWheelOdom = append(RuleOfWheelOdom, f)
+			log(triggerLocalPath)
+			continue
 		} else {
 			c_log.GlobalLogger.Error("未知的topic:", topic2)
 			continue
 		}
 
+	JudgeDone:
 		label, err := open.Lookup("Label")
 		if err != nil {
-			c_log.GlobalLogger.Error("加载本地插件", triggerLocalPath, "中的TriggerName方法失败。", err)
-			continue
-		}
-		labelFunc, ok := label.(func() string)
-		if ok != true {
-			c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的Label方法必须是(func() string):", err)
+			c_log.GlobalLogger.Error("加载本地插件 ", triggerLocalPath, " 中的 Label 方法失败。", err)
 			continue
 		}
+		labelFunc := label.(func() string)
 		labelString := labelFunc()
-		LabelMapTriggerId[labelString] = strconv.Itoa(trigger.TriggerId)
-		loadSuccess++
-		c_log.GlobalLogger.Info("主节点加载触发器插件:【ros topic】=", topic2, ",【触发器label】=", labelString, "【触发器ID】=", trigger.TriggerId)
+		LabelMapTriggerId.Store(labelString, triggerId)
+		success++
 	}
-	c_log.GlobalLogger.Infof("一共有%v个触发器,加载成功了%v个,【label和id映射关系】=%v", len(config.PlatformConfig.TaskTriggers), loadSuccess, LabelMapTriggerId)
+	c_log.GlobalLogger.Info("一共应加载", len(config.PlatformConfig.TaskTriggers), "个触发器,实际加载 ", success, " 个触发器。")
+}
+func log(triggerLocalPath string) {
+	c_log.GlobalLogger.Error("插件", triggerLocalPath, "中的 Rule 方法参数格式不正确。")
 }

+ 2 - 2
aarch64/pjibot_patrol/master/package/config/trigger_var.go

@@ -7,11 +7,11 @@ import (
 	"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/std_msgs"
+	"sync"
 )
 
 var (
-	LabelMapTriggerId = make(map[string]string)
-
+	LabelMapTriggerId = new(sync.Map)
 	// 1
 	TopicOfDiagnostics = "/diagnostics"
 	RuleOfDiagnostics  []func(data *diagnostic_msgs.DiagnosticArray) string

+ 4 - 2
aarch64/pjibot_patrol/master/package/service/produce_window.go

@@ -40,9 +40,12 @@ func PrepareTimeWindowProducerQueue() {
 							faultLabel = f(data)
 							if faultLabel != "" {
 								if canCollect() {
+									c_log.GlobalLogger.Errorf("触发事件【%v】,开始采集。", faultLabel)
 									saveTimeWindow(faultLabel, faultHappenTime, lastTimeWindow)
 									subscribersTimes[i] = time.Now()
 									break
+								} else {
+									c_log.GlobalLogger.Errorf("触发事件【%v】,但当前周期内采集数量已超限额,不再采集。", faultLabel)
 								}
 							}
 						}
@@ -148,9 +151,8 @@ func canCollect() bool {
 		return false
 	}
 	if resp.Code != 200 { // 不是200 代表不允许采集
-		c_log.GlobalLogger.Info("采集数量已超过限额,当前周期内不再采集。", resp.Code)
+		c_log.GlobalLogger.Infof("当前周期内采集数量已超过限额。%+v", resp)
 		return false
 	}
-	c_log.GlobalLogger.Info("允许采集。")
 	return true
 }