LingxinMeng 11 ヶ月 前
コミット
5665b4627c

+ 5 - 0
.idea/sqldialects.xml

@@ -1,8 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="SqlDialectMappings">
+    <file url="file://$PROJECT_DIR$/amd64/score_server/sql/collect_limit-insert_new.sql" dialect="MySQL" />
+    <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-reset-by-id.sql" dialect="MySQL" />
+    <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-select-all.sql" dialect="MySQL" />
     <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-select-details-by-id.sql" dialect="MySQL" />
     <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-select-latest-by-team_name.sql" dialect="GenericSQL" />
+    <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-update-deduct_score_offline-by-id.sql" dialect="MySQL" />
+    <file url="file://$PROJECT_DIR$/amd64/score_server/sql/exam-update-end_time-by-id.sql" dialect="MySQL" />
     <file url="PROJECT" dialect="MySQL" />
   </component>
 </project>

+ 27 - 17
aarch64/pji/common/config/c_cloud.go

@@ -51,24 +51,34 @@ type trigger struct {
 	Topics []string `yaml:"topics"`
 }
 
+type CollectLimitStruct struct {
+	Url   string `yaml:"url"`
+	Day   int    `yaml:"day"`
+	Week  int    `yaml:"week"`
+	Month int    `yaml:"month"`
+	Year  int    `yaml:"year"`
+}
+
 type cloudConfig struct {
-	FullCollect           bool          `yaml:"full-collect"`
-	ConfigRefreshInterval int           `yaml:"config-refresh-interval"` // 配置刷新时间间隔
-	BagNumber             int           `yaml:"bag-number"`
-	TimeWindowSendGap     int           `yaml:"time-window-send-gap"` // 主节点向从节点发送窗口的最小时间间隔
-	MapBagPath            string        `yaml:"map-bag-path"`
-	TfstaticBagPath       string        `yaml:"tfstatic-bag-path"`
-	CostmapBagPath        string        `yaml:"costmap-bag-path"`
-	BagDataDir            string        `yaml:"bag-data-dir"`
-	BagCopyDir            string        `yaml:"bag-copy-dir"`
-	TriggersDir           string        `yaml:"triggers-dir"`
-	RpcPort               string        `yaml:"rpc-port"`
-	Triggers              []trigger     `yaml:"triggers"`
-	Hosts                 []hostStruct  `yaml:"hosts"`
-	Ros                   ros           `yaml:"ros"`
-	Platform              platform      `yaml:"platform"`
-	Disk                  disk          `yaml:"disk"`
-	Monitor               MonitorStruct `yaml:"monitor"`
+	CollectLimit          CollectLimitStruct `yaml:"collect-limit"`
+	MapBufFiles           []string           `yaml:"map-buf-files"`
+	FullCollect           bool               `yaml:"full-collect"`
+	ConfigRefreshInterval int                `yaml:"config-refresh-interval"` // 配置刷新时间间隔
+	BagNumber             int                `yaml:"bag-number"`
+	TimeWindowSendGap     int                `yaml:"time-window-send-gap"` // 主节点向从节点发送窗口的最小时间间隔
+	MapBagPath            string             `yaml:"map-bag-path"`
+	TfstaticBagPath       string             `yaml:"tfstatic-bag-path"`
+	CostmapBagPath        string             `yaml:"costmap-bag-path"`
+	BagDataDir            string             `yaml:"bag-data-dir"`
+	BagCopyDir            string             `yaml:"bag-copy-dir"`
+	TriggersDir           string             `yaml:"triggers-dir"`
+	RpcPort               string             `yaml:"rpc-port"`
+	Triggers              []trigger          `yaml:"triggers"`
+	Hosts                 []hostStruct       `yaml:"hosts"`
+	Ros                   ros                `yaml:"ros"`
+	Platform              platform           `yaml:"platform"`
+	Disk                  disk               `yaml:"disk"`
+	Monitor               MonitorStruct      `yaml:"monitor"`
 }
 
 // Request 结构体定义

+ 26 - 5
aarch64/pji/common/config/yaml/引导机器人默认配置文件双摄像头-cloud-config.yaml

@@ -1,4 +1,10 @@
 ---
+collect-limit:
+  url: http://36.110.106.142:12341/web_server/collect_limit/can_collect
+  day: 1
+  week: 7
+  month: 31
+  year: 366
 monitor:
   url: http://36.110.106.142:12341/web_server/monitor/insert
 platform:
@@ -10,14 +16,29 @@ bag-number: 60
 config-refresh-interval: 60
 disk:
   name: /dev/mmcblk0p8 # 磁盘名称
-  used: 20000000000 # 磁盘占用阈值,单位bytes
-map-buf-dir: /root/pjirobot/data/mapBuf/
+  used: 22000000000 # 磁盘占用阈值,单位bytes
+map-buf-files:
+  - /root/pjirobot/data/mapBuf/forbid_area.json
+  - /root/pjirobot/data/mapBuf/forbid_area.yaml
+  - /root/pjirobot/data/mapBuf/forbid_area_init.json
+  - /root/pjirobot/data/mapBuf/forbid_area_init.yaml
+  - /root/pjirobot/data/mapBuf/function_area.json
+  - /root/pjirobot/data/mapBuf/function_area_init.json
+  - /root/pjirobot/data/mapBuf/function_links.json
+  - /root/pjirobot/data/mapBuf/map.json
+  - /root/pjirobot/data/mapBuf/map.pbstream
+  - /root/pjirobot/data/mapBuf/map.pgm
+  - /root/pjirobot/data/mapBuf/map.yaml
+  - /root/pjirobot/data/mapBuf/map_type.json
+  - /root/pjirobot/data/mapBuf/param.yaml
+  - /root/pjirobot/data/mapBuf/stations.json
+  - /root/pjirobot/data/mapBuf/stations_init.json
 map-bag-path: /root/cicv-data-closedloop/map.bag
 #bag-data-dir: /root/cicv-data-closedloop/data/
 #bag-copy-dir: /root/cicv-data-closedloop/copy/
-bag-data-dir: /root/cicv-data-closedloop/data/
-bag-copy-dir: /root/cicv-data-closedloop/copy/
-triggers-dir: /root/cicv-data-closedloop/triggers/
+bag-data-dir: /root/pjirobot/data/cicv-data-closedloop/data/
+bag-copy-dir: /root/pjirobot/data/cicv-data-closedloop/copy/
+triggers-dir: /root/pjirobot/data/cicv-data-closedloop/triggers/
 time-window-send-gap: 6
 rpc-port: 12341
 ros:

+ 6 - 2
aarch64/pji/common/service/rosbag_upload.go

@@ -9,6 +9,7 @@ import (
 	"cicv-data-closedloop/common/util"
 	"fmt"
 	"os"
+	"path/filepath"
 	"strings"
 	"time"
 )
@@ -141,13 +142,16 @@ outLoop:
 		}
 		commonConfig.OssMutex.Lock()
 		err = commonConfig.OssBucket.PutObject(objectKey3+"callback.json", strings.NewReader(callBackJson))
+		for _, file := range commonConfig.CloudConfig.MapBufFiles {
+			err = commonConfig.OssBucket.PutObjectFromFile(objectKey3+filepath.Base(file), file)
+		}
 		commonConfig.OssMutex.Unlock()
 		if err != nil {
-			c_log.GlobalLogger.Error("上传 callback.json", callBackJson, "失败:", err)
+			c_log.GlobalLogger.Error("上传 callback.json 或 mapBuf 文件失败:", err)
 		}
 
 		// 删除本地所有已上传的bag文件
-		c_log.GlobalLogger.Infof("结束处理窗口,【Lable】=%v,【FaultTime】=%v,【Length】=%v", currentTimeWindow.Labels, currentTimeWindow.FaultTime, currentTimeWindow.Length)
+		c_log.GlobalLogger.Infof("结束处理窗口,【Lable】=%v,【FaultTime】=%v,【Length】=%v", currentTimeWindow.Labels, currentTimeWindow.FaultTime, currentTimeWindow.Length)
 		if err = util.RemoveDir(dir); err != nil {
 			continue outLoop
 		}

+ 38 - 3
aarch64/pji/master/package/service/produce_window.go

@@ -4,9 +4,11 @@ import (
 	commonConfig "cicv-data-closedloop/aarch64/pji/common/config"
 	commonService "cicv-data-closedloop/aarch64/pji/common/service"
 	masterConfig "cicv-data-closedloop/aarch64/pji/master/package/config"
+	"cicv-data-closedloop/amd64/dispatch_server/package/util"
 	"cicv-data-closedloop/common/config/c_log"
 	"cicv-data-closedloop/common/entity"
 	commonUtil "cicv-data-closedloop/common/util"
+	"encoding/json"
 	"github.com/bluenviron/goroslib/v2"
 	"github.com/bluenviron/goroslib/v2/pkg/msgs/std_msgs"
 	"sync"
@@ -37,9 +39,11 @@ func PrepareTimeWindowProducerQueue() {
 						for _, f := range masterConfig.RuleOfObstacleDetection {
 							faultLabel = f(data)
 							if faultLabel != "" {
-								saveTimeWindow(faultLabel, faultHappenTime, lastTimeWindow)
-								subscribersTimes[i] = time.Now()
-								break
+								if canCollect() {
+									saveTimeWindow(faultLabel, faultHappenTime, lastTimeWindow)
+									subscribersTimes[i] = time.Now()
+									break
+								}
 							}
 						}
 						subscribersMutexes[i].Unlock()
@@ -118,3 +122,34 @@ func getTopicsOfNode(faultLabel string) (masterTopics []string, slaveTopics []st
 	}
 	return faultCodeTopics, nil
 }
+
+// 判断采集包数量是否超过限额
+func canCollect() bool {
+	responseString, err := commonUtil.HttpPostJsonWithHeaders(
+		commonConfig.CloudConfig.CollectLimit.Url,
+		map[string]string{"Authorization": "U9yKpD6kZZDDe4LFKK6myAxBUT1XRrDM"},
+		map[string]string{
+			"snCode":            commonConfig.LocalConfig.SecretKey,
+			"collectLimitDay":   util.ToString(commonConfig.CloudConfig.CollectLimit.Day),
+			"collectLimitWeek":  util.ToString(commonConfig.CloudConfig.CollectLimit.Week),
+			"collectLimitMonth": util.ToString(commonConfig.CloudConfig.CollectLimit.Month),
+			"collectLimitYear":  util.ToString(commonConfig.CloudConfig.CollectLimit.Year),
+		},
+	)
+	if err != nil {
+		c_log.GlobalLogger.Error("发送http请求获取是否允许采集失败:", err)
+		return false
+	}
+	// 解析JSON字符串到Response结构体
+	var resp entity.Response
+	err = json.Unmarshal([]byte(responseString), &resp)
+	if err != nil {
+		c_log.GlobalLogger.Error("解析是否允许采集接口返回结果失败:", err)
+		return false
+	}
+	if resp.Code != 200 { // 不是200 代表不允许采集
+		c_log.GlobalLogger.Info("采集数量已超过限额,当前周期内不再采集。")
+		return false
+	}
+	return true
+}

+ 56 - 0
amd64/score_server/dao/mapper/mapper_collect_limit.go

@@ -0,0 +1,56 @@
+package mapper
+
+import (
+	webServerEntity "cicv-data-closedloop/amd64/score_server/entity"
+	"cicv-data-closedloop/common/config/c_db"
+	"cicv-data-closedloop/common/config/c_log"
+	"cicv-data-closedloop/common/util"
+)
+
+func SelectFromCollectLimitBySnCode(snCode string) webServerEntity.CollectLimitPo {
+	// 如果查出是空,则插入一条新数据
+	var resultPos []webServerEntity.CollectLimitPo
+	selectSql, _ := util.ReadFile(c_db.SqlFilesMap["collect_limit-select-by-sn_code.sql"])
+	err := c_db.MysqlDb.Select(&resultPos, selectSql, snCode)
+	if err != nil || len(resultPos) == 0 {
+		c_log.GlobalLogger.Error(err)
+		InsertNew(snCode)
+		return *new(webServerEntity.CollectLimitPo)
+	}
+	return resultPos[0]
+}
+
+func InsertNew(snCode string) {
+	sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["collect_limit-insert_new.sql"])
+	if err := c_db.DoTx(sqlTemplate, []any{snCode}); err != nil {
+		c_log.GlobalLogger.Error("插入数据报错:", err)
+		return
+	}
+}
+
+func UpdateCollectLimit(snCode string) {
+	// 更新记录结束时间为默认时间
+	sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["collect_limit-select-by-sn_code.sql"])
+	if err := c_db.DoTx(sqlTemplate, []any{
+		snCode,
+	}); err != nil {
+		c_log.GlobalLogger.Error("插入数据报错:", err)
+		return
+	}
+}
+
+//
+//func SelectLatestByTeamName(teamName string) []webServerEntity.ExamPo {
+//	// 车辆不是在起点启动的自动驾驶模式
+//	var result []webServerEntity.ExamPo
+//	selectSql, err := util.ReadFile(c_db.SqlFilesMap["exam-select-latest-by-team_name.sql"])
+//	if err != nil {
+//		c_log.GlobalLogger.Error("读取sql文件报错:", err)
+//		return nil
+//	}
+//	if err = c_db.MysqlDb.Select(&result, selectSql, teamName); err != nil {
+//		c_log.GlobalLogger.Error("数据库查询报错:", err)
+//		return nil
+//	}
+//	return result
+//}

+ 11 - 0
amd64/score_server/entity/e_collect_limit.go

@@ -0,0 +1,11 @@
+package entity
+
+type CollectLimitPo struct {
+	Id                   int    `db:"id" `                    // 自增id
+	SnCode               string `db:"sn_code" `               // 设备 sn 码
+	DayCollectedNumber   string `db:"day_collected_number" `  // 本日已采集包数量
+	WeekCollectedNumber  string `db:"week_collected_number" ` // 本周已采集包数量
+	MonthCollectedNumber string `db:"month_collected_number"` // 本月已采集包数量
+	YearCollectedNumber  string `db:"year_collected_number"`  // 本年已采集包数量
+	ModifyTime           string `db:"modify_time" `           // 数据修改时间
+}

+ 56 - 0
amd64/score_server/handler/h_collect_limit.go

@@ -0,0 +1,56 @@
+package handler
+
+import (
+	"cicv-data-closedloop/amd64/score_server/dao/mapper"
+	"cicv-data-closedloop/common/config/c_log"
+	commonEntity "cicv-data-closedloop/common/entity"
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"sync"
+)
+
+type CollectLimitPao struct {
+	SnCode            string ` json:"snCode"`            // 机器人sn码
+	CollectLimitDay   string ` json:"collectLimitDay"`   // 机器人配置的每日限额采集数
+	CollectLimitWeek  string ` json:"collectLimitWeek"`  // 机器人配置的每周限额采集数
+	CollectLimitMonth string ` json:"collectLimitMonth"` // 机器人配置的每月限额采集数
+	CollectLimitYear  string ` json:"collectLimitYear"`  // 机器人配置的每年限额采集数
+}
+
+var globalMutex sync.Mutex
+
+// 接收设备数据采集触发信号,判断是否允许设备继续采集,如果允许返回允许信号(code为200),否则为拒绝采集
+func TriggerCollect(c *gin.Context) {
+	globalMutex.Lock()
+	defer globalMutex.Unlock()
+	param := new(CollectLimitPao)
+	// 映射到结构体
+	if err := c.ShouldBindJSON(&param); err != nil {
+		c_log.GlobalLogger.Error("项目启动接收请求参数报错:", err)
+		c.JSON(http.StatusBadRequest, commonEntity.Response{Code: 500, Msg: "请求体解析失败。"})
+		return
+	}
+	// 1 根据sn码查询当前设备已采集的包数量
+	collectLimitPo := mapper.SelectFromCollectLimitBySnCode(param.SnCode)
+	// 2 将查出的数据与参数中的限额数进行对比,判断是否允许采集,如果允许,则返回 code 200
+	if collectLimitPo.YearCollectedNumber < param.CollectLimitYear {
+		if collectLimitPo.MonthCollectedNumber < param.CollectLimitMonth {
+			if collectLimitPo.WeekCollectedNumber < param.CollectLimitWeek {
+				if collectLimitPo.DayCollectedNumber < param.CollectLimitDay {
+					// 所有值添加一
+					mapper.UpdateCollectLimit(param.SnCode)
+					// 返回允许信号
+					c.JSON(http.StatusOK, commonEntity.Response{
+						Code: 200,
+						Msg:  "允许采集。",
+					})
+					return
+				}
+			}
+		}
+	}
+	c.JSON(http.StatusOK, commonEntity.Response{
+		Code: 400,
+		Msg:  "不允许采集。",
+	})
+}

+ 6 - 0
amd64/score_server/main.go

@@ -56,6 +56,12 @@ func main() {
 			monitorPrefix.POST("/insert", handler.SaveDeviceMonitor)
 		}
 	}
+	{
+		monitorPrefix := router.Group("/web_server/collect_limit") // todo web_server会改成score_server,后续修改
+		{
+			monitorPrefix.POST("/can_collect", handler.TriggerCollect)
+		}
+	}
 	// 端口
 	err := router.Run(":" + infra.ApplicationYaml.Web.Port)
 	if err != nil {

+ 7 - 0
amd64/score_server/sql/collect_limit-add_one.sql

@@ -0,0 +1,7 @@
+update collect_limit
+set day_collected_number   = day_collected_number + 1,
+    week_collected_number  = week_collected_number + 1,
+    month_collected_number = month_collected_number + 1,
+    year_collected_number  = year_collected_number + 1,
+    modify_time            = current_time()
+where sn_code = ?

+ 3 - 0
amd64/score_server/sql/collect_limit-insert_new.sql

@@ -0,0 +1,3 @@
+insert into collect_limit(sn_code, day_collected_number, week_collected_number, month_collected_number,
+                          year_collected_number, modify_time)
+values (?, 0, 0, 0, 0, current_time())

+ 9 - 0
amd64/score_server/sql/collect_limit-select-by-sn_code.sql

@@ -0,0 +1,9 @@
+select id,
+       sn_code,
+       day_collected_number,
+       week_collected_number,
+       month_collected_number,
+       year_collected_number,
+       modify_time
+from collect_limit
+where sn_code = ?