惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
Martin Fowler
Martin Fowler
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
Engineering at Meta
Engineering at Meta
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
罗磊的独立博客
B
Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
U
Unit 42
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
V2EX

洛屿的小站

脉冲线性加减速曲线的DDA实现 STM32F407 IAR环境下uC/OS-III移植完整指南 STM32 UCOS3+HAL库集成中的FPU HardFault问题 一种简单的卡尔曼滤波器设计 Cadence - 应律而动,落指成音 Zephyr - 聆风之息,为你而奏 不改一行插件代码,实现消息优先级与阻断 洛玖定时任务系统 在 butterfly 主题中添加首页点集动画(基于p2line项目) 你好,2026 stm32f4xx-ads1256驱动 stm32f4xx-ad9854并行驱动 主动式网站状态监测实现及其应用 右键菜单加入用Trae打开文件和文件夹 三角洲行动ID映射表 洛玖SDK说明 为网页文章开头添加原文连接 Hexo-Butterfly主题在主页添加GitHub贡献日历 Proteus中555定时器仿真问题 装饰器 洛玖开发日记 STS3032舵机获取力矩输出 kotlin网页前后端那些事 mspm0g3507-ad9850 Paddle模型转PaddleLite 人工智能考核 构建一个yolov3网络 yolo和paddle模型常见输出参数 PaddleDetection 随便写的一些东西
奇怪的bug
洛屿 · 2024-08-14 · via 洛屿的小站
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once
#include "../src/main.h"
#include "json.hpp"
#include <cmath>
#include <fstream>
#include <iostream>

using namespace std;

class ValueConfig {
private:

public:
struct Params {
// 丢线场计数
int out_count = 10;

// 短直道场计数
int short_count = 3;

// 急减速场计数
int slow_count = 30;

// 加速场计数
int fast_count = 30;

// speed_debug = true时,所有速度均为speed_normal设置的速度
bool speed_debug = false;
// 速度
int speed_bridge = 20;
int speed_danger = 10;
int speed_parking = 10;
int speed_racing = 20;
int speed_rescue = 10;

int speed_normal = 38;
int speed_fast = 38;
int speed_slow = 30;
int speed_slowest = speed_slow - 15;
int speed_add = 40;

// 圆环速度
int speed_circle_begin = 26;
int speed_circle_min = 25;

int speed_circle_runningl_s = speed_circle_min;
int speed_circle_runningl_m = speed_circle_min + 2;
int speed_circle_runningl_l = speed_circle_min + 4;

int speed_circle_runningr_s = speed_circle_min;
int speed_circle_runningr_m = speed_circle_min + 2;
int speed_circle_runningr_l = speed_circle_min + 4;

// 偏差速度控制值abs(4500 - midAdd) > BIAS_SPEED_LIMIT后进入慢速控制
int bias_speed_limit = 150;

// 逆透视半径计算瞄点
int LR_num1 = 8;
int LR_num2 = 16;
int LR_num3 = 24;

int RR_num1 = 8;
int RR_num2 = 16;
int RR_num3 = 24;

int LR_F_num1 = 24;
int LR_F_num2 = 34;
int LR_F_num3 = 44;

int RR_F_num1 = 24;
int RR_F_num2 = 34;
int RR_F_num3 = 44;

double aim_distance = 0.62;
double servo_pid_P1 = 1.7; // 一阶比例系数:直线控制量
double servo_pid_P2 = 0.1; // 二阶比例系数:弯道控制量
double servo_pid_f = 0.1; // 前馈系数
double servo_pid_D = 0; // 一阶比例系数:转弯控制量
double servo_pid_k1 = 2.25;
double servo_pid_k2 = 1.34;
double servo_pid_k3 = 3;

bool ai_debug = false; // AI图像显示使能
bool bi_debug = false; // 二值化图像显示使能
bool track_debug = false; // 赛道线图像显示使能
bool nts_debug = false; // 逆透视图像显示使能
bool saveImage = false; // 存图使能
float disGarageEntry = 0.7; // 车库入库距离(斑马线Image占比)

float cone_score = 0.6;
float bomb_score = 0.6;
float block_score = 0.6;
float bridge_score = 0.6;
float crosswalk_score = 0.6;
float people_score = 0.6;
float car_score = 0.75;

char BLOCK_POI = 'L'; // 黑块位置(L / l 左 , R / r 右)

float L_MID_L = 154;
float L_MID_R = 179;
float L_BLOCK_MID_L = 158;
float L_BLOCK_MID_R = 166;
int L_BOMB_Y_TOP = 15; // 爆炸物录入起始行
int L_CONE_Y_TOP = 67; // 锥桶录入起始行
int L_CONE_Y_DOWN = 207; // 锥桶录入终止行

float R_MID_L = 150;
float R_MID_R = 170.1;
float R_BLOCK_MID_L = 158;
float R_BLOCK_MID_R = 166;
int R_BOMB_Y_TOP = 15; // 爆炸物录入起始行
int R_CONE_Y_TOP = 67; // 锥桶录入起始行
int R_CONE_Y_DOWN = 207; // 锥桶录入终止行

bool it_AI = true; // AI区域使能
bool it_RESCUE = true; // 救援区使能
bool it_RACING = true; // 追逐区使能
bool it_DANGER = true; // 危险区使能
bool it_BRIDGE = true; // 桥使能

NLOHMANN_DEFINE_TYPE_INTRUSIVE(
Params,
out_count, short_count, slow_count,fast_count,
speed_debug,
speed_bridge, speed_danger, speed_parking, speed_racing, speed_rescue,
speed_normal, speed_fast, speed_slow, speed_slowest, speed_add,
speed_circle_begin, speed_circle_min,
speed_circle_runningl_s, speed_circle_runningl_m, speed_circle_runningl_l,
speed_circle_runningr_s, speed_circle_runningr_m, speed_circle_runningr_l,
bias_speed_limit,
aim_distance,
servo_pid_P1, servo_pid_P2, servo_pid_f, servo_pid_D, //servo_pid_k1, servo_pid_k2, servo_pid_k3,
ai_debug, bi_debug, track_debug, nts_debug, saveImage,
disGarageEntry,
cone_score,bomb_score,block_score,bridge_score,crosswalk_score,people_score,car_score,
BLOCK_POI,
L_MID_L, L_MID_R, L_BLOCK_MID_L, L_BLOCK_MID_R, L_BOMB_Y_TOP, L_CONE_Y_TOP, L_CONE_Y_DOWN,
R_MID_L, R_MID_R, R_BLOCK_MID_L, R_BLOCK_MID_R, R_BOMB_Y_TOP, R_CONE_Y_TOP, R_CONE_Y_DOWN,
it_AI, it_RESCUE, it_RACING, it_DANGER, it_BRIDGE); // 添加构造函数
};

Params params; // 读取控制参数
/**
* @brief 加载配置参数Json
*/
ValueConfig() {
string jsonPath = "../src/config/value_config.json";
std::ifstream config_is(jsonPath);
if (!config_is.good()) {
std::cout << "Error: Params file path:[" << jsonPath << "] not find .\n";
exit(-1);
}

nlohmann::json js_value;
config_is >> js_value;

try {
params = js_value.get<Params>();
} catch (const nlohmann::detail::exception &e) {
std::cerr << "Json Params Parse failed :" << e.what() << '\n';
exit(-1);
}
cout <<"--- out_count: " << params.out_count << endl
<< " | short_count: " << params.short_count << endl
<< " | slow_count: " << params.slow_count << endl;
cout <<"--- speed_debug: " << (params.speed_debug ? "true" : "false") << endl;
cout <<"--- speed_normal: " << params.speed_normal << endl;

printf("cone_score : %.2f\t", params.cone_score);
printf("bomb_score : %.2f\t", params.bomb_score);
printf("block_score : %.2f\t", params.block_score);
printf("bridge_score : %.2f\t", params.bridge_score);
printf("crosswalk_score : %.2f\n", params.crosswalk_score);
printf("rescue_score : %.2f\n", params.people_score);
printf("car_score : %.2f\n", params.car_score);
}
};

奇怪的bug:

NLOHMANN_DEFINE_TYPE_INTRUSIVE(
Params,
out_count, short_count, slow_count,fast_count,
speed_debug,
speed_bridge, speed_danger, speed_parking, speed_racing, speed_rescue,
speed_normal, speed_fast, speed_slow, speed_slowest, speed_add,
speed_circle_begin, speed_circle_min,
speed_circle_runningl_s, speed_circle_runningl_m, speed_circle_runningl_l,
speed_circle_runningr_s, speed_circle_runningr_m, speed_circle_runningr_l,
bias_speed_limit,
aim_distance,
servo_pid_P1, servo_pid_P2, servo_pid_f, servo_pid_D, //servo_pid_k1, servo_pid_k2, servo_pid_k3,
ai_debug, bi_debug, track_debug, nts_debug, saveImage,
disGarageEntry,
cone_score,bomb_score,block_score,bridge_score,crosswalk_score,people_score,car_score,
BLOCK_POI,
L_MID_L, L_MID_R, L_BLOCK_MID_L, L_BLOCK_MID_R, L_BOMB_Y_TOP, L_CONE_Y_TOP, L_CONE_Y_DOWN,
R_MID_L, R_MID_R, R_BLOCK_MID_L, R_BLOCK_MID_R, R_BOMB_Y_TOP, R_CONE_Y_TOP, R_CONE_Y_DOWN,
it_AI, it_RESCUE, it_RACING, it_DANGER, it_BRIDGE); // 添加构造函数
参数数量超过63个之后,会对其中几乎所有参数报错:
error: invalid use of non-static data member ValueConfig::Params::参数名

1
https://github.com/nlohmann/json

错误推测:
问题出在NLOHMANN_DEFINE_TYPE_INTRUSIVE宏的参数数量超过某个限制(64个参数)。

该宏在展开时会生成序列化代码,当参数过多时会导致宏展开失败,从而引发非静态成员访问错误。

检查json.hpp文件发现其中含有一份宏:

#define NLOHMANN_JSON_PASTE(…) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(VA_ARGS, \

​ NLOHMANN_JSON_PASTE64, \

​ NLOHMANN_JSON_PASTE63, \

​ …

​ NLOHMANN_JSON_PASTE2, \

​ NLOHMANN_JSON_PASTE1)(VA_ARGS))

推测是该宏导致的64个参数量的上限

NLOHMANN_DEFINE_TYPE_INTRUSIVE宏内部展开参数时,当参数数量超过其设计上限时,会导致展开失败,生成无效代码。

手动实现序列化函数可彻底避免此限制,是最可靠的解决方案。