refactor(log): 日志文案改 ASCII 英文,修 ROS_INFO 中文乱码
ROS_INFO/WARN/ERROR 走的不是 printf,而是 rosconsole -> log4cxx,后者按进程当前的 C 语言环境对消息做一次窄/宽字符转码。节点从未调用 setlocale,LC_CTYPE 停在默认的 "C"(ASCII),于是非 ASCII 的每个字节被替换成一个 '?'——一个汉字 3 字节正好 3 个 '?'。而 [config] 摘要那条 std::cout 路径直接写字节、不转码,所以之前只有 ROS_* 的 日志乱码。备选方案是 setlocale(LC_CTYPE, "")(3 行即可修),这里采用"运行时输出一律 英文":英文日志不依赖语言环境,systemd/robot_upstart 拉起时也不会因缺 LANG 复发。 改动与校验: - invicta_hardware / invicta_remote / invicta_deploy / invicta_msgs 共 20 个文件、 202 处字符串字面量改为 ASCII 英文。中文代码注释、标识符、话题名、JSON/TOML 键名、 日志前缀一律未动(把字面量内容挖空后与改前做骨架比对,20 个文件零差异)。 - printf 格式说明符(%s/%d/%zu/%.1f/%02X ...)的数量、类型、顺序逐文件与改前一致。 - 顺带 ASCII 化非中文字符:° -> deg、± -> +/-、× -> x、→ -> ->、框线 -> "+==+", 并修正了启动横幅框线宽度差 2 列的问题。 - motion_defs.h 的 GaitName / MotionParamName 显示名改英文(只用于日志与回包文案); 协议字段仍传整数(bs["MotionState"] = int(...)),不影响上位机协议。 注意:invicta_remote 回给手柄的 Unsupported / "Not allowed operation" 文案也变为英文, 会出现在上位机错误列表里。 已在 SBC(aarch64, Noetic)编译确认。
This commit is contained in:
@@ -163,17 +163,17 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
try {
|
||||
tbl = toml::parse_file(path);
|
||||
} catch (const toml::parse_error& e) {
|
||||
return fail(std::string("TOML 解析失败: ") + std::string(e.description()) + " @ " + path);
|
||||
return fail(std::string("TOML parse failed: ") + std::string(e.description()) + " @ " + path);
|
||||
}
|
||||
|
||||
const toml::table* robot = detail::Section(tbl, "robot");
|
||||
if (!robot) return fail("缺少 [robot] 段");
|
||||
if (!robot) return fail("missing [robot] section");
|
||||
detail::GetStr(robot, "name", robot_name);
|
||||
detail::GetStr(robot, "version", robot_version);
|
||||
detail::GetStrArr(robot, "joint_names", joint_names);
|
||||
if (joint_names.empty()) return fail("[robot].joint_names 为空");
|
||||
if (joint_names.empty()) return fail("[robot].joint_names is empty");
|
||||
dof = int(joint_names.size());
|
||||
if (dof % 2 != 0) return fail("joint_names 数量必须是偶数(每腿 摆臂+轮)");
|
||||
if (dof % 2 != 0) return fail("joint_names count must be even (one swing + one wheel per leg)");
|
||||
|
||||
std::vector<double> lower, upper, vel_limit;
|
||||
const toml::table* limits = detail::Section(tbl, "joint_limits");
|
||||
@@ -181,7 +181,7 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
detail::GetDoubleArr(limits, "upper", upper);
|
||||
detail::GetDoubleArr(limits, "vel_limit", vel_limit);
|
||||
if (int(lower.size()) != dof || int(upper.size()) != dof || int(vel_limit.size()) != dof) {
|
||||
return fail("[joint_limits] 的 lower/upper/vel_limit 长度必须等于关节数量");
|
||||
return fail("[joint_limits] lower/upper/vel_limit length must equal joint count");
|
||||
}
|
||||
joints.assign(size_t(dof), JointSpec{});
|
||||
for (int i = 0; i < dof; ++i) {
|
||||
@@ -204,7 +204,7 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
leg.swing_index = IndexOf(leg.swing_joint);
|
||||
leg.wheel_index = IndexOf(leg.wheel_joint);
|
||||
if (leg.swing_index < 0 || leg.wheel_index < 0) {
|
||||
return fail("[[legs]] " + leg.name + " 的 swing_joint/wheel_joint 不在 joint_names 里");
|
||||
return fail("[[legs]] " + leg.name + " swing_joint/wheel_joint not in joint_names");
|
||||
}
|
||||
joints[size_t(leg.swing_index)].leg = int(legs.size());
|
||||
joints[size_t(leg.wheel_index)].leg = int(legs.size());
|
||||
@@ -212,8 +212,8 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
legs.push_back(leg);
|
||||
}
|
||||
}
|
||||
if (legs.empty()) return fail("缺少 [[legs]] 段");
|
||||
if (int(legs.size()) * 2 != dof) return fail("腿数与关节数不匹配(每腿 2 个关节)");
|
||||
if (legs.empty()) return fail("missing [[legs]] section");
|
||||
if (int(legs.size()) * 2 != dof) return fail("leg count does not match joint count (2 joints per leg)");
|
||||
|
||||
const toml::table* gc = detail::Section(tbl, "leg");
|
||||
detail::Get(gc, "swing_link_len", swing_link_len);
|
||||
@@ -235,12 +235,12 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
detail::Get(gains, "damping_kd_wheel", damping_kd_wheel);
|
||||
detail::GetBool(gains, "wheel_kp_zero", wheel_kp_zero);
|
||||
|
||||
if (swing_link_len <= 1e-6) return fail("[leg].swing_link_len 必须 > 0");
|
||||
if (swing_link_len <= 1e-6) return fail("[leg].swing_link_len must be > 0");
|
||||
for (const auto& pair : {std::make_pair("stand_height", stand_height),
|
||||
std::make_pair("pre_height", pre_height),
|
||||
std::make_pair("lie_height", lie_height)}) {
|
||||
if (pair.second > swing_link_len) {
|
||||
return fail(std::string("[leg].") + pair.first + " 大于 swing_link_len,物理上不可达");
|
||||
return fail(std::string("[leg].") + pair.first + " greater than swing_link_len, physically unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,14 +264,14 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
detail::GetDoubleArr(pol, "kp", policy_kp);
|
||||
detail::GetDoubleArr(pol, "kd", policy_kd);
|
||||
if (policy_joint_order.empty()) policy_joint_order = joint_names;
|
||||
if (int(policy_joint_order.size()) != dof) return fail("[policy].joint_order 长度必须等于关节数量");
|
||||
if (int(policy_joint_order.size()) != dof) return fail("[policy].joint_order length must equal joint count");
|
||||
for (const auto& n : policy_joint_order) {
|
||||
if (IndexOf(n) < 0) return fail("[policy].joint_order 里的 " + n + " 不在 joint_names 里");
|
||||
if (IndexOf(n) < 0) return fail("[policy].joint_order entry " + n + " not in joint_names");
|
||||
}
|
||||
action_dim = dof;
|
||||
for (const auto& arr : {&action_scale, &default_joint_pos, &policy_kp, &policy_kd}) {
|
||||
if (int(arr->size()) != action_dim) {
|
||||
return fail("[policy] 的 action_scale/default_joint_pos/kp/kd 长度必须等于关节数量");
|
||||
return fail("[policy] action_scale/default_joint_pos/kp/kd length must equal joint count");
|
||||
}
|
||||
}
|
||||
obs_dim = 9 + 3 * action_dim; // 角速度(3) + 投影重力(3) + 速度指令(3) + 关节角 + 关节速度 + 上一步动作
|
||||
@@ -285,7 +285,7 @@ inline bool DeployConfig::Load(const std::string& path, std::string* error) {
|
||||
try {
|
||||
gait_policies[uint32_t(std::stoul(std::string(k.str())))] = v.value_or(std::string{});
|
||||
} catch (const std::exception&) {
|
||||
return fail("[gait.policies] 的键必须能转成整数步态值");
|
||||
return fail("[gait.policies] key must convert to an integer gait value");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +320,7 @@ inline std::string DeployConfig::Summary() const {
|
||||
for (size_t i = 0; i < legs.size(); ++i) {
|
||||
const double sw = SwingAngleForHeight(stand_height, int(i));
|
||||
const double li = SwingAngleForHeight(lie_height, int(i));
|
||||
snprintf(buf, sizeof(buf), "[config] %s splay=%+.0f 站立摆臂=%+.1f° 趴下=%+.1f°\n",
|
||||
snprintf(buf, sizeof(buf), "[config] %s splay=%+.0f stand swing=%+.1f deg lie down=%+.1f deg\n",
|
||||
legs[i].name.c_str(), legs[i].splay_sign, sw * 180. / M_PI, li * 180. / M_PI);
|
||||
s += buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user