logo资料库

移动机器人软件框架构思.pdf

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
移动机器人软件框架构思
文件目录
整体架构
Tricks
RoboMaster⼯ 个 阶 、PPT后 从11⽉ 到1⽉ computer上 MCU上 ⻅RoboRTS和RoboRTS-Firmware, 了Driver、Perception、Decision-Making、Planning部 中RoboRTS运 ,RoboRTS-Frimware运 在on-board 现Control部 下RoboRTS是 新feature的 为Driver、Perception、Decision-Making、Planning、Control五 ├── cmake ├── common ├── docs ├── modules └── tools 程 师 移 动 机 器 ⼈ 软 件 框 架 构 思 对 于 软 件 系 统 设 计 ⽽ ⾔ , 我 们 ⼀ 点 经 验 都 没 有 , 刚 开 始 的 时 候 根 本 ⽆ 从 下 ⼿ , 看 了 很 多 开 源 框 架 就 开 始 慢 慢 着 ⼿ 了 。 这 个 阶 段 的 思 想 ⾄ 关 重 要 , 最 后 框 架 的 样 ⼦ 完 全 由 你 这 段 的 思 想 决 定 。 份 下 旬 , 我 们 花 了 两 个 半 ⽉ 的 时 间 来 搭 ⾃ 动 ⻋ 的 软 件 框 架 , 除 了 通 信 以 外 , 基 本 完 成 了 ⾃ 动 机 器 ⼈ 软 件 系 统 框 架 的 搭 建 与 算 法 的 重 构 , 项 ⽬ 代 码 其 ⾏ , 主 要 实 现 分 ⾏ 在 , 主 要 实 分 。 下 ⾯ 主 要 谈 ⼀ 实 现 思 路 , 能 ⼒ 有 限 , 欢 迎 批 评 指 正 〜 ⽂ 件 ⽬ 录 如 果 ⽂ 件 ⽬ 录 前 期 没 有 定 好 , 后 期 添 加 时 候 就 会 显 得 ⾮ 常 乱 、 思 路 不 清 晰 , 导 致 同 事 或 ⽤ 户 难 以 理 解 。 机 器 ⼈ 相 关 算 法 ⼀ 般 分 个 模 块 , 如 下 图 所 ⽰ 思 路 清 晰 了 , ⽂ 件 的 ⽬ 录 也 就 很 容 易 搭 出 来 , ⼀ 级 ⽬ 录 如 下
含.cmake⽂ cmake包 tools包 ;common下 ;modules下 ├── decision ├── driver │ ├── camera │ └── serial ├── perception │ ├── detection │ │ ├── armor_detection │ │ │ ├── constraint_set │ │ └── util │ ├── localization │ │ ├── amcl │ └── map │ └── costmap ├── planning │ ├── global_planner │ │ ├── a_star_planner │ └── local_planner │ └── timed_elastic_band └── stream ├── messages │ ├── action │ └── msg └── tf_tree 过std::condition_variable来 planner、local planner这 Decision模 。localization、detection、global ,Driver、Perception、Planning模 ⽤publish/subscribe来 ,Decision和 actionlib来 了ROS的publish/subscribe、actionlib等 件 , ⽤ 于 查 找 第 三 ⽅ 依 赖 库 是 ⼀ 些 共 有 的 代 码 , ⽐ 如 读 取 ⽂ 件 、 测 试 时 间 等 ; 含 ⼀ 些 启 动 脚 本 、 常 ⽤ ⼯ 具 等 就 是 上 图 所 ⽰ 的 各 个 模 块 整 体 架 构 整 体 的 架 构 主 要 是 指 各 模 块 之 间 如 何 衔 接 、 数 据 流 如 何 传 输 等 。 模 块 衔 接 我 们 主 要 聚 焦 在 于 如 何 实 现 每 个 模 块 单 独 控 制 , 每 个 模 块 都 可 以 ⾃ 由 实 现 开 启 、 暂 停 、 终 ⽌ 等 操 作 。 我 们 的 模 块 控 制 是 通 实 现 的 , 代 码 也 很 简 单 , 就 不 多 说 了 些 模 块 什 么 时 候 运 ⾏ 、 什 么 时 候 暂 停 可 以 ⾃ 由 控 制 后 , ⻋ 体 的 状 态 也 就 增 加 了 , 这 样 块 才 能 更 加 灵 活 。 数 据 传 输 我 们 没 有 时 间 也 没 有 能 ⼒ 来 设 计 ⼀ 套 通 讯 框 架 , 所 以 暂 时 还 是 利 ⽤ 基 本 功 能 块 间 是 通 讯 的 其 他 模 块 间 的 通 讯 是 ⽤ 完 成 的 , 各 模 块 的 数 据 流 如 下 图 所 ⽰ :
以detection模 到camera, 如mapping、detection、recognition等 开camera了 个sensor, 个camera的 个camera时 1. 很 2. 存 3. 如 Detection这 我 们 块 为 例 , ⼤ 概 说 ⼀ 下 单 个 模 块 的 构 架 。 我 们 设 计 这 部 分 的 框 架 时 主 要 考 虑 以 下 ⼏ 个 ⽅ ⾯ : 多 算 法 中 都 会 ⽤ ⽐ , 那 我 们 就 不 能 像 之 前 写 程 序 那 样 直 接 在 某 个 算 法 的 程 序 中 打 , ⽽ 需 要 把 摄 像 头 看 做 ⼀ 写 ⼀ 驱 动 ; 在 多 , 如 何 实 现 快 速 切 换 数 据 ? 何 把 驱 动 、 算 法 、 ⽤ 户 等 各 层 解 耦 。 块 主 要 由 驱 动 、 缓 存 、 算 法 、 ⽤ 户 四 个 层 构 成 , 如 下 图 , 其 中 ⽤ 户 层 和 算 法 层 是 所 有 模 块 都 应 当 有 的 。 第 ⼀ 层 : 驱 动 层 。 我 们 ⽤ 四 个 线 程 来 读 取 四 个 相 机 , 分 别 获 得 图 像 ;
双buffer容 器), 个buffer中 个buffer中 双buffer容 如buffer_10、buffer_11共 把camera_id传 间+算 应camera的 的detection算 过".xml"或 者".prototxt"等 的detection算 的detection算 考RoboRTS/common/example。 Tricks C++和python是 的feature甚 度Apollo的 把ROS的 #define MAIN(RRTS_CLASS,module_name) \ int main(int argc, char **argv){ \ rrts::common::GLogWrapper glog_wrapper(argv[0]); \ signal(SIGINT, SignalHandler); \ signal(SIGTERM,SignalHandler); \ ros::init(argc, argv, module_name, ros::init_options::NoSigintHandler); \ RRTS_CLASS rrts(module_name); \ rrts.Run(); \ return 0; \ } RRTS类 块node类 test_node.h中 ,TestNode必 承RRTS class TestNode : public rrts::common::RRTS { public: TestNode ( std::string name); ~TestNode (); private: ros::NodeHandle nh_; ros::Subscriber sub_; }; 在test_node.cpp的 加MAIN即 第 ⼆ 层 : 缓 存 层 。 把 每 个 相 机 的 图 像 放 到 ⼀ 个 器 ( 颜 ⾊ 相 同 的 ⽅ 框 , 同 组 成 ⼀ 个 第 ⼀ 帧 放 到 第 ⼀ , 第 ⼆ 帧 放 到 第 ⼆ , 往 复 循 环 。 设 计 该 层 的 ⽬ 的 是 为 了 使 得 相 机 读 取 和 算 法 处 理 同 时 进 ⾏ , 如 果 没 有 该 层 , 算 法 在 执 ⾏ 之 前 必 须 先 读 取 图 像 , 这 样 每 ⼀ 轮 的 时 间 就 等 于 读 取 图 像 的 时 法 处 理 时 间 , 做 ⼀ 个 缓 冲 层 , 就 可 以 让 图 像 读 取 和 算 法 处 理 并 ⾏ ; 第 三 层 : 算 法 层 。 算 法 层 这 ⾥ 只 需 要 声 明 缓 冲 层 的 ⼀ 个 对 象 , 然 后 进 缓 冲 层 中 的 图 像 获 取 函 数 接 ⼝ 就 可 以 得 到 相 最 新 图 像 了 , 之 后 你 就 可 以 ⽤ 该 图 像 做 滤 波 、 特 征 提 取 等 ⼀ 系 列 处 理 。 这 ⼀ 层 要 ⽤ 到 ⼯ ⼚ 类 来 注 册 所 有 法 。 第 四 层 : ⽤ 户 层 。 ⽤ 户 层 这 ⾥ 可 以 通 配 置 ⽂ 件 来 选 择 ⽤ 哪 ⼀ 种 算 法 。 ⽐ 如 某 同 学 觉 得 前 任 队 友 写 法 不 够 完 美 , 就 重 写 ⼀ 种 算 法 , 将 其 注 册 进 算 法 ⼯ ⼚ , 然 后 只 需 要 在 ⽤ 户 层 这 ⾥ 改 ⼀ 下 配 置 ⽂ 件 就 可 以 将 前 任 队 友 写 法 替 换 成 ⾃ ⼰ 的 算 法 了 。 具 体 的 代 码 实 例 可 以 参 完 全 不 同 的 , 很 多 想 法 实 现 起 来 ⾮ 常 困 难 , 有 ⾄ 要 花 费 好 ⼏ 天 的 时 间 来 完 成 , 举 ⼏ 个 例 ⼦ : ⼊ ⼝ 函 数 这 块 参 考 了 百 实 现 过 程 , 主 要 想 初 始 化 、 启 动 消 息 回 调 、 等 待 终 ⽌ 信 号 等 操 作 统 ⼀ 放 在 ⼀ 起 是 所 有 模 的 基 类 , 举 个 栗 ⼦ 须 继 尾 部 添 可 , 如 下 所 ⽰
TestNode::TestNode (std::string name):RRTS::RRTS (name)) { //加 } MAIN(rrts::common::TestNode ,"test_node" ); 在node类 caffe、MXnet等 了ROS的 1. 如 者std::function就 2. 当 3. 如 了Apollo、 :1. ⼯ ;2. 动 态library, ⽤lambda表 ⽤std::placeholder_template+可 板 __VA_ARGS__ +变 ⻅RoboRTS 有A*和Dijkstra两 rrts::common::REGISTER_ALGORITHM (GlobalPlannerBase , "a_star_planner" , AStarPlanner , std::shared_ptr ); global_planner_ptr_ = rrts::common::AlgorithmFactory ::CreateAlgorithm (selected_algorithm_ , costmap_ptr_ ); NOTICE机 些log来 印log, 了detection的 接 std::out << "msg" << std::endl ; , 置flag, :1. 设 if else来 太low了 ;2. 利 量std::condition_variable来 ;3. 利 这 样 每 个 模 块 的 ⼊ ⼝ 函 数 就 统 ⼀ 了 , 然 后 的 构 造 函 数 中 创 建 新 的 ⼦ 线 程 , 在 ⼦ 线 程 中 实 现 对 应 的 算 法 。 ⼯ ⼚ 类 前 期 想 实 现 这 样 ⼀ 个 功 能 : 给 每 个 模 块 写 ⼀ 个 ⽤ 户 层 , ⽤ 户 层 可 以 ⽅ 便 选 择 调 ⽤ 该 模 块 所 有 的 算 法 , 这 样 就 可 以 把 算 法 和 ⽤ 户 层 解 耦 。 听 起 来 貌 似 很 简 单 , 但 想 要 优 雅 的 实 现 , 也 有 ⼀ 定 的 困 难 。 在 着 ⼿ 之 前 , 我 看 ⼤ 型 项 ⽬ 的 ⼯ ⼚ 类 实 现 , 也 看 插 件 机 制 实 现 ⽅ 式 。 发 现 ⼀ 般 有 两 种 实 现 ⽅ 式 ⼚ 类 , 每 个 模 块 下 的 所 有 算 法 都 ⽤ 都 ⽤ 这 个 ⼯ ⼚ 类 注 册 , 然 后 就 可 以 ⽤ 该 ⼯ ⼚ ⽣ 产 已 经 注 册 的 算 法 态 链 接 库 的 调 ⽤ , 也 就 是 继 承 机 制 , 给 所 有 的 算 法 ⼀ 个 共 同 的 基 类 , 然 后 把 所 有 的 算 法 编 译 成 动 在 ⽤ 户 层 调 ⽤ 算 法 的 接 ⼝ 函 数 。 动 态 链 接 库 的 缺 点 在 于 不 ⽅ 便 调 试 , 最 后 就 选 了 ⼯ ⼚ 类 的 实 现 ⽅ 式 。 ⼯ ⼚ ⽅ 法 其 实 是 设 计 模 式 ⾥ 最 常 ⻅ 的 ⼀ 种 模 式 , 这 ⾥ 主 要 记 录 ⼀ 下 在 研 发 的 过 程 中 遇 到 的 ⼏ 个 问 题 。 何 把 类 的 内 存 分 配 转 移 到 创 建 算 法 阶 段 , ⽽ 不 在 注 册 阶 段 分 配 内 存 ? 其 实 很 简 单 , ⼀ 般 达 式 或 可 以 实 现 。 类 的 构 造 函 数 参 数 个 数 、 类 型 不 确 定 时 , 是 否 可 以 调 ⽤ 同 ⼀ 个 ⼯ ⼚ 注 册 ? 这 个 问 题 我 想 了 很 久 , 看 了 很 多 代 码 , 感 觉 实 现 的 都 不 是 很 好 , 最 后 变 参 数 模 参 模 板 参 数 包 的 ⽅ 法 实 现 了 , 感 觉 优 点 复 杂 , 不 知 道 还 有 没 有 其 他 更 好 的 实 现 ⽅ 式 , 迫 于 时 间 问 题 , 没 有 继 续 深 究 。 何 实 现 ⼀ 个 单 例 模 式 ? 实 现 过 程 其 实 很 简 单 , 需 要 注 意 的 是 ⽗ 类 指 针 和 ⼦ 类 的 指 针 ⼀ 定 要 搞 清 楚 , 不 然 很 可 能 创 建 了 多 个 单 例 , 这 样 ⽆ 论 注 册 了 多 少 算 法 , 还 是 ⽆ 法 创 建 已 经 注 册 的 算 法 。 详 细 的 代 码 以 全 局 路 径 规 划 为 例 , 我 们 种 算 法 , 我 只 需 要 在 算 法 对 应 的 头 ⽂ 件 中 将 函 数 注 册 到 算 法 ⼯ ⼚ 中 , 如 : 这 样 我 就 可 以 在 全 局 路 径 规 划 的 ⽤ 户 层 中 进 ⾏ 调 ⽤ 制 有 很 多 时 候 我 们 需 要 在 ⼀ 个 循 环 中 打 ⽐ 如 : 在 摄 像 头 驱 动 没 有 开 启 前 开 启 算 法 , 此 时 我 想 要 打 ⼀ 提 醒 ⽤ 户 开 启 摄 像 头 驱 动 , 当 然 你 可 以 在 循 环 中 直 然 后 这 条 消 息 就 ⼀ 直 在 屏 幕 上 疯 狂 刷 新 , 能 不 能 在 循 环 中 只 执 ⾏ ⼀ 次 该 语 句 ? 当 时 想 到 有 三 种 ⽅ 法 然 后 ⽤ 实 现 , 感 觉 这 样 ⽤ 条 件 变 实 现 ⽤ 宏 定 义 。 我 觉 得 最 有 效 、 最 通 ⽤ 的 ⼿ 段 就 是 宏 定 义 , 代 码 如 下 : 载 参 数 、 选 择 算 法 、 开 启 ⼦ 线 程 等 ⼀ 系 列 操 作
#define NOTICE(text) { \ static bool flag = true; \ if(flag) { \ std::cout << text << std::endl; \ flag = false; \ } \ } \ ⽤ NOTICE(“ 你 息”) 就 while(flag) { if(!img.empty()) { NOTICE("Begin to detect xxx!" ) 开 } else } NOTICE("Waiting for run camera driver..." ) 的NOTICE消 现glog中 #define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ static int LOG_OCCURRENCES = 0; \ if (LOG_OCCURRENCES <= n) \ ++LOG_OCCURRENCES; \ if (LOG_OCCURRENCES <= n) \ google::LogMessage( \ __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ &what_to_do).stream() void FunctionA () { TIMER_START (FunctionA ) SomeFunction (); TIMER_END (FunctionA ) } #define TIMER_START(FUNC) boost::timer t_##FUNC; #define TIMER_END(FUNC) std::cout << "[" << #FUNC << "]" << "cost time: " << t_##FUNC.elapsed() << std::endl; C++11中 了 __func__ 功 你 只 需 要 在 循 环 中 使 想 打 印 的 消 可 以 了 , ⽽ 且 在 任 何 循 环 中 都 可 以 使 ⽤ , ⽐ 如 : 所 有 循 环 中 息 只 会 打 印 ⼀ 次 。 后 来 发 也 有 类 似 的 实 现 , 还 可 以 定 义 打 印 次 数 , 如 下 测 试 时 间 如 何 ⽅ 便 的 测 试 函 数 运 ⾏ 时 间 ? 如 下 代 码 可 以 这 样 来 实 现 提 供 能 , 所 以 就 更 ⽅ 便 了 启 算 法
void FunctionA () { TIMER_START SomeFunction (); TIMER_END } #define TIMER_START boost::timer t_##__func__; #define TIMER_END std::cout << "[" << #__func__ << "]" << "cost time: " << t_##__func__.elapsed() << std::endl;   实 现 起 来 也 很 简 单 框 架 其 实 还 不 是 很 完 善 , 我 们 会 慢 慢 改 进 , 希 望 ⼤ 家 多 提 意 ⻅ , 不 胜 感 激 〜
分享到:
收藏