mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
t/euroc: Allow euroc recorder to start and stop recordings in the same session
This commit is contained in:
parent
cdcb4fbc57
commit
14c1ecc96e
|
@ -42,11 +42,11 @@ using std::filesystem::create_directories;
|
|||
struct euroc_recorder
|
||||
{
|
||||
struct xrt_frame_node node;
|
||||
string path; //!< Destination path for the dataset
|
||||
string path_prefix; //!< Path for the dataset without datetime suffix
|
||||
string path; //!< Full path of the current dataset being recorded or empty string if none
|
||||
int cam_count = -1;
|
||||
|
||||
bool recording; //!< Whether samples are being recorded
|
||||
bool files_created; //!< Whether the dataset directory structure has been created
|
||||
struct u_var_button recording_btn; //!< UI button to start/stop `recording`
|
||||
|
||||
bool use_jpg; //! Whether or not we should save images as .jpg files
|
||||
|
@ -84,14 +84,8 @@ struct euroc_recorder
|
|||
*/
|
||||
|
||||
static void
|
||||
euroc_recorder_try_mkfiles(struct euroc_recorder *er)
|
||||
euroc_recorder_mkfiles(struct euroc_recorder *er)
|
||||
{
|
||||
// Create directory structure and files only once
|
||||
if (er->files_created) {
|
||||
return;
|
||||
}
|
||||
er->files_created = true;
|
||||
|
||||
string path = er->path;
|
||||
|
||||
create_directories(path + "/mav0/imu0");
|
||||
|
@ -348,30 +342,15 @@ euroc_recorder_create(struct xrt_frame_context *xfctx, const char *record_path,
|
|||
{
|
||||
struct euroc_recorder *er = new euroc_recorder{};
|
||||
|
||||
er->recording = record_from_start;
|
||||
er->cam_count = cam_count;
|
||||
er->path_prefix = record_path == nullptr ? "euroc_recording" : record_path;
|
||||
er->path = record_path == nullptr ? "" : record_path;
|
||||
|
||||
struct xrt_frame_node *xfn = &er->node;
|
||||
xfn->break_apart = euroc_recorder_node_break_apart;
|
||||
xfn->destroy = euroc_recorder_node_destroy;
|
||||
xrt_frame_context_add(xfctx, xfn);
|
||||
|
||||
// Determine dataset path
|
||||
if (record_path != nullptr) {
|
||||
er->path = record_path;
|
||||
} else {
|
||||
time_t seconds = os_realtime_get_ns() / U_1_000_000_000;
|
||||
constexpr size_t size = sizeof("YYYYMMDDHHmmss");
|
||||
char datetime[size] = {0};
|
||||
(void)strftime(datetime, size, "%Y%m%d%H%M%S", localtime(&seconds));
|
||||
string default_path = string{"euroc_recording_"} + datetime;
|
||||
er->path = default_path;
|
||||
}
|
||||
|
||||
if (record_from_start) {
|
||||
euroc_recorder_try_mkfiles(er);
|
||||
}
|
||||
|
||||
er->use_jpg = debug_get_bool_option_euroc_recorder_use_jpg();
|
||||
|
||||
// Setup sink pipeline
|
||||
|
@ -408,23 +387,69 @@ euroc_recorder_create(struct xrt_frame_context *xfctx, const char *record_path,
|
|||
er->writer_gt_sink.push_pose = euroc_recorder_save_gt;
|
||||
|
||||
xrt_slam_sinks *public_sinks = &er->cloner_queues;
|
||||
|
||||
if (record_from_start) {
|
||||
euroc_recorder_start(public_sinks);
|
||||
}
|
||||
|
||||
return public_sinks;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
euroc_recorder_start(struct xrt_slam_sinks *er_sinks)
|
||||
{
|
||||
euroc_recorder *er = container_of(er_sinks, euroc_recorder, cloner_queues);
|
||||
|
||||
if (er->recording) {
|
||||
U_LOG_W("We are already recording; unable to start.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create dataset directories with current datetime suffix
|
||||
time_t seconds = os_realtime_get_ns() / U_1_000_000_000;
|
||||
constexpr size_t size = sizeof("YYYYMMDDHHmmss");
|
||||
char datetime[size] = {0};
|
||||
(void)strftime(datetime, size, "%Y%m%d%H%M%S", localtime(&seconds));
|
||||
string default_path = er->path_prefix + "_" + datetime;
|
||||
er->path = default_path;
|
||||
|
||||
euroc_recorder_mkfiles(er);
|
||||
er->recording = true;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
euroc_recorder_stop(struct xrt_slam_sinks *er_sinks)
|
||||
{
|
||||
euroc_recorder *er = container_of(er_sinks, euroc_recorder, cloner_queues);
|
||||
|
||||
if (!er->recording) {
|
||||
U_LOG_W("We are already not recording; unable to stop.");
|
||||
return;
|
||||
}
|
||||
|
||||
er->path = "";
|
||||
er->recording = false;
|
||||
euroc_recorder_flush(er);
|
||||
}
|
||||
|
||||
static void
|
||||
euroc_recorder_btn_cb(void *ptr)
|
||||
{
|
||||
euroc_recorder *er = (euroc_recorder *)ptr;
|
||||
euroc_recorder_try_mkfiles(er);
|
||||
er->recording = !er->recording;
|
||||
(void)snprintf(er->recording_btn.label, sizeof(er->recording_btn.label),
|
||||
er->recording ? "Stop recording" : "Record EuRoC dataset");
|
||||
|
||||
if (er->recording) {
|
||||
euroc_recorder_stop(&er->cloner_queues);
|
||||
(void)snprintf(er->recording_btn.label, sizeof(er->recording_btn.label), "Record EuRoC dataset");
|
||||
} else {
|
||||
euroc_recorder_start(&er->cloner_queues);
|
||||
(void)snprintf(er->recording_btn.label, sizeof(er->recording_btn.label), "Stop recording");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
euroc_recorder_add_ui(struct xrt_slam_sinks *public_sinks, void *root, const char *prefix)
|
||||
euroc_recorder_add_ui(struct xrt_slam_sinks *er_sinks, void *root, const char *prefix)
|
||||
{
|
||||
euroc_recorder *er = container_of(public_sinks, euroc_recorder, cloner_queues);
|
||||
euroc_recorder *er = container_of(er_sinks, euroc_recorder, cloner_queues);
|
||||
er->recording_btn.cb = euroc_recorder_btn_cb;
|
||||
er->recording_btn.ptr = er;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Create SLAM sinks to record samples in EuRoC format.
|
||||
* Create SLAM sinks to record samples in EuRoC format.
|
||||
*
|
||||
* @param xfctx Frame context for the sinks.
|
||||
* @param record_path Directory name to save the dataset or NULL for a default based on the current datetime.
|
||||
|
@ -33,6 +33,23 @@ extern "C" {
|
|||
struct xrt_slam_sinks *
|
||||
euroc_recorder_create(struct xrt_frame_context *xfctx, const char *record_path, int cam_count, bool record_from_start);
|
||||
|
||||
/*!
|
||||
* Start recording samples sent to the recorder sinks.
|
||||
*
|
||||
* @param er The recorder sinks returned by @ref euroc_recorder_create
|
||||
*/
|
||||
void
|
||||
euroc_recorder_start(struct xrt_slam_sinks *er_sinks);
|
||||
|
||||
/*!
|
||||
* Stop recording samples sent to the recorder sinks. You can start and
|
||||
* stop as many times as you like.
|
||||
*
|
||||
* @param er The recorder sinks returned by @ref euroc_recorder_create
|
||||
*/
|
||||
void
|
||||
euroc_recorder_stop(struct xrt_slam_sinks *er_sinks);
|
||||
|
||||
/*!
|
||||
* Add EuRoC recorder UI button to start recording after creation.
|
||||
*
|
||||
|
@ -41,7 +58,7 @@ euroc_recorder_create(struct xrt_frame_context *xfctx, const char *record_path,
|
|||
* @param prefix Prefix in case you have multiple recorders, otherwise pass an empty string
|
||||
*/
|
||||
void
|
||||
euroc_recorder_add_ui(struct xrt_slam_sinks *er, void *root, const char *prefix);
|
||||
euroc_recorder_add_ui(struct xrt_slam_sinks *er_sinks, void *root, const char *prefix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue