PX4模块设计之十九:Replay模块
1. Replay模块简介
Replay模块同样继承ModuleBase模块的基本命令start/stop/status命令。
此外增加了两个自定义子命令:
- trystart
- tryapplyparams
Replay模块主要就是回放的功能,将飞控的飞行姿态根据播放速率重新回放一遍。
pxh> replay
### Description
This module is used to replay ULog files.
There are 2 environment variables used for configuration: `
Usage: replay <command> [arguments...]
Commands:
start Start replay, using log file from ENV variable 'replay'
trystart Same as 'start', but silently exit if no log file given
tryapplyparams Try to apply the parameters from the log file
stop
status print status info
注:上述打印帮助来自函数Replay::print_usage,具体Coding这里不再赘述,有兴趣的同学可以独立深入。
2. 模块入口函数
2.1 主入口replay_main
replay_main
├──> const char *logfile = getenv(replay::ENV_FILENAME);
├──> <logfile && !Replay::isSetup()>
│ ├──> PX4_INFO("using replay log file: %s", logfile);
│ └──> Replay::setupReplayFile(logfile);
└──> return Replay::main(argc, argv); // 调用ModuleBase的main方法
注:具体入口后实现详见【PX4模块设计之十七:ModuleBase模块】
2.2 自定义子命令Replay::custom_command
Replay::custom_command
├──> <!strcmp(argv[0], "tryapplyparams")>
│ └──> return Replay::applyParams(true);
├──> <!strcmp(argv[0], "trystart")>
│ └──> return Replay::task_spawn(argc, argv);
└──> return print_usage("unknown command");
3. 重要实现函数
3.1 Replay::task_spawn
Replay::task_spawn
├──> <!isSetup()> // check if a log file was found
│ ├──> <argc > 0 && strncmp(argv[0], "try", 3) == 0>
│ │ └──> return 0;
│ ├──> PX4_ERR("no log file given (via env variable %s)", replay::ENV_FILENAME);
│ └──> return -1;
├──> _task_id = px4_task_spawn_cmd("replay", SCHED_DEFAULT, SCHED_PRIORITY_MAX - 5, 4000, (px4_main_t)&run_trampoline, (char *const *)argv);
├──> <_task_id < 0>
│ ├──> _task_id = -1;
│ └──> return -errno;
└──> return 0;
3.2 Replay::instantiate
Replay::instantiate
├──> const char *replay_mode = getenv(replay::ENV_MODE);
├──> Replay *instance = nullptr;
├──> <replay_mode && strcmp(replay_mode, "ekf2") == 0>
│ ├──> PX4_INFO("Ekf2 replay mode");
│ └──> instance = new ReplayEkf2();
├──> <else>
│ └──> instance = new Replay();
└──> return instance;
3.3 Replay::run
主要订阅回放的是"sensor_combined"uORB消息,通过传感器反馈数据对飞行姿态进行回放。
Replay::run
├──> ifstream replay_file(_replay_file, ios::in | ios::binary);
├──> <!readDefinitionsAndApplyParams(replay_file)>
│ └──> return
├──> _speed_factor = 1.f;
├──> const char *speedup = getenv("PX4_SIM_SPEED_FACTOR");
├──> <speedup>
│ └──> _speed_factor = atof(speedup);
├──> onEnterMainLoop();
├──> _replay_start_time = hrt_absolute_time();
├──> PX4_INFO("Replay in progress...");
├──> replay_file.seekg(_data_section_start);
├──> replay_file.read((char *)&message_header, ULOG_MSG_HEADER_LEN); //we know the next message must be an ADD_LOGGED_MSG
├──> <!readAndAddSubscription(replay_file, message_header.msg_size)>
│ ├──> <PX4_ERR("Failed to read subscription");>
│ └──> return
├──> const uint64_t timestamp_offset = getTimestampOffset();
├──> uint32_t nr_published_messages = 0;
├──> streampos last_additional_message_pos = _data_section_start; //给出了数据日志记录的起始位置
├──> <while (!should_exit() && replay_file) >
│ ├──> [readAndAddSubscription:检查"sensor_combined"主题消息]
│ ├──> [nextDataMessage:读取内容"sensor_combined"主题消息内容]
│ ├──> [handleTopicDelay:根据发布时间,replay便宜时间,以及replay speedup等因素,调整uORB消息发布时间]
│ └──> [handleTopicUpdate:发布uORB消息]
├──> <for (auto &subscription : _subscriptions)>
│ ├──> <!subscription>
│ │ └──> continue
│ ├──> <subscription->compat>
│ │ ├──> delete subscription->compat;
│ │ └──> subscription->compat = nullptr;
│ └──> <subscription->orb_advert>
│ ├──> orb_unadvertise(subscription->orb_advert);
│ └──> subscription->orb_advert = nullptr;
├──> <!should_exit()>
│ └──> PX4_INFO("Replay done (published %u msgs, %.3lf s)", nr_published_messages, (double)hrt_elapsed_time(&_replay_start_time) / 1.e6);
├──> onExitMainLoop();
└──> <!should_exit()>
├──> replay_file.close();
└──> px4_shutdown_request();
4. 总结
整体看下来,也并不复杂,仅仅只是飞控姿态的回放。没有太多其他资料信息,比如:GPS,指令(GCS,RC),空气动力学模拟信息等。
如果能将这个黑匣子数据结合到模拟器上,进行重飞,那就更有意义了。
本文详细介绍了PX4的Replay模块,该模块用于回放飞行控制器的飞行姿态。它支持start/stop/status基本命令,并增加自定义命令如trystart和tryapplyparams。Replay模块根据指定的飞行日志文件,以设定的速度回放传感器数据,重现飞行过程。在启动时,它检查环境变量以获取日志文件并尝试应用参数。主要功能集中在Replay::run函数中,通过读取和发布订阅的uORB消息,特别是'sensor_combined'主题,来模拟飞行姿态。如果能够结合模拟器进行重飞,该模块的应用价值将进一步提升。
1万+

被折叠的 条评论
为什么被折叠?



