st/prober: Load tracking config from json and use new settings struct

This commit is contained in:
Jakob Bornecrantz 2020-04-08 12:27:41 +01:00 committed by Jakob Bornecrantz
parent a11aa689a7
commit 2063bc30b8
7 changed files with 273 additions and 9 deletions

View file

@ -0,0 +1 @@
prober: Load tracking config from json and use new settings struct.

View file

@ -6,6 +6,7 @@ set(PROBER_INCLUDES)
set(PROBER_SOURCE_FILES
p_documentation.h
p_dump.c
p_json.c
p_prober.c
p_prober.h
p_tracking.c

View file

@ -4,6 +4,7 @@
prober_sources = [
'p_documentation.h',
'p_dump.c',
'p_json.c',
'p_prober.c',
'p_prober.h',
'p_tracking.c',

View file

@ -0,0 +1,178 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Code to manage the settings file.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup st_prober
*/
#include "util/u_file.h"
#include "util/u_json.h"
#include "util/u_debug.h"
#include "p_prober.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
char *
read_content(FILE *file)
{
// Go to the end of the file.
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
// Return back to the start of the file.
fseek(file, 0L, SEEK_SET);
char *buffer = (char *)calloc(file_size + 1, sizeof(char));
if (buffer == NULL) {
return NULL;
}
// Do the actual reading.
size_t ret = fread(buffer, sizeof(char), file_size, file);
if (ret != file_size) {
free(buffer);
return NULL;
}
return buffer;
}
cJSON *
p_json_open_or_create_main_file(void)
{
FILE *file = u_file_open_file_in_config_dir("config_v0.json", "r");
if (file == NULL) {
fprintf(stderr, "Could not open the file!\n");
return NULL;
}
char *str = read_content(file);
fclose(file);
if (str == NULL) {
fprintf(stderr, "Could not read the contents of the file!\n");
return NULL;
}
cJSON *ret = cJSON_Parse(str);
if (ret == NULL) {
fprintf(stderr, "Failed to parse JSON:\n%s\n#######\n", str);
fprintf(stderr, "'%s'\n", cJSON_GetErrorPtr());
}
free(str);
return ret;
}
static cJSON *
get_obj(cJSON *json, const char *name)
{
cJSON *item = cJSON_GetObjectItemCaseSensitive(json, name);
if (item == NULL) {
fprintf(stderr, "Failed to find node '%s'!\n", name);
}
return item;
}
XRT_MAYBE_UNUSED static bool
get_obj_bool(cJSON *json, const char *name, bool *out_bool)
{
cJSON *item = get_obj(json, name);
if (item == NULL) {
return false;
}
if (!u_json_get_bool(item, out_bool)) {
fprintf(stderr, "Failed to parse '%s'!\n", name);
return false;
}
return true;
}
static bool
get_obj_int(cJSON *json, const char *name, int *out_int)
{
cJSON *item = get_obj(json, name);
if (item == NULL) {
return false;
}
if (!u_json_get_int(item, out_int)) {
fprintf(stderr, "Failed to parse '%s'!\n", name);
return false;
}
return true;
}
static bool
get_obj_str(cJSON *json, const char *name, char *array, size_t array_size)
{
cJSON *item = get_obj(json, name);
if (item == NULL) {
return false;
}
if (!u_json_get_string_into_array(item, array, array_size)) {
fprintf(stderr, "Failed to parse '%s'!\n", name);
return false;
}
return true;
}
bool
p_json_get_tracking_settings(cJSON *root, struct xrt_settings_tracking *s)
{
if (root == NULL) {
return false;
}
cJSON *t = cJSON_GetObjectItemCaseSensitive(root, "tracking");
if (t == NULL) {
fprintf(stderr, "No tracking node!\n");
return false;
}
char tmp[16];
int ver = -1;
bool bad = false;
bad |= !get_obj_int(t, "version", &ver);
if (bad || ver >= 1) {
fprintf(stderr, "Missing or unknown version tag '%i'\n", ver);
return false;
}
bad |= !get_obj_str(t, "camera_name", s->camera_name,
sizeof(s->camera_name));
bad |= !get_obj_int(t, "camera_mode", &s->camera_mode);
bad |= !get_obj_str(t, "camera_type", tmp, sizeof(tmp));
bad |= !get_obj_str(t, "calibration_path", s->calibration_path,
sizeof(s->calibration_path));
if (bad) {
return false;
}
if (strcmp(tmp, "regular_mono") == 0) {
s->camera_type = XRT_SETTINGS_CAMERA_TYPE_REGULAR_MONO;
} else if (strcmp(tmp, "regular_sbs") == 0) {
s->camera_type = XRT_SETTINGS_CAMERA_TYPE_REGULAR_SBS;
} else if (strcmp(tmp, "ps4") == 0) {
s->camera_type = XRT_SETTINGS_CAMERA_TYPE_PS4;
} else if (strcmp(tmp, "leap_motion") == 0) {
s->camera_type = XRT_SETTINGS_CAMERA_TYPE_LEAP_MOTION;
} else {
fprintf(stderr, "Unknown camera type '%s'\n", tmp);
return false;
}
return true;
}

View file

@ -9,6 +9,7 @@
#include "util/u_var.h"
#include "util/u_misc.h"
#include "util/u_json.h"
#include "util/u_debug.h"
#include "os/os_hid.h"
#include "p_prober.h"
@ -327,6 +328,8 @@ initialize(struct prober *p, struct xrt_prober_entry_lists *lists)
int ret;
p->json.root = p_json_open_or_create_main_file();
ret = collect_entries(p);
if (ret != 0) {
teardown(p);
@ -444,6 +447,11 @@ teardown(struct prober *p)
#ifdef XRT_HAVE_LIBUSB
p_libusb_teardown(p);
#endif
if (p->json.root != NULL) {
cJSON_Delete(p->json.root);
p->json.root = NULL;
}
}

View file

@ -13,6 +13,7 @@
#include "xrt/xrt_config_os.h"
#include "xrt/xrt_compiler.h"
#include "xrt/xrt_prober.h"
#include "xrt/xrt_settings.h"
#ifdef XRT_HAVE_LIBUSB
#include <libusb-1.0/libusb.h>
@ -130,6 +131,11 @@ struct prober
struct xrt_prober_entry_lists *lists;
struct
{
cJSON *root;
} json;
#ifdef XRT_HAVE_LIBUSB
struct
{
@ -167,6 +173,18 @@ struct prober
*
*/
/*!
* Load the JSON config file.
*/
cJSON *
p_json_open_or_create_main_file(void);
/*!
* Extract tracking settings from the JSON.
*/
bool
p_json_get_tracking_settings(cJSON *root, struct xrt_settings_tracking *s);
/*!
* Dump the given device to stdout.
*/

View file

@ -40,6 +40,12 @@ struct p_factory
// Owning prober.
struct prober *p;
// Has the settings be loaded.
bool setting_ok;
// Settings for this tracking system.
struct xrt_settings_tracking settings;
//! Shared tracking origin.
struct xrt_tracking_origin origin;
@ -93,8 +99,7 @@ on_video_device(struct xrt_prober *xp,
return;
}
// Hardcoded to PS4 camera.
if (strcmp(name, "USB Camera-OV580") != 0) {
if (strcmp(name, fact->settings.camera_name) != 0) {
return;
}
@ -105,6 +110,11 @@ on_video_device(struct xrt_prober *xp,
static void
p_factory_ensure_frameserver(struct p_factory *fact)
{
// No settings loaded.
if (!fact->setting_ok) {
return;
}
// Already created.
if (fact->xfs != NULL) {
return;
@ -118,11 +128,19 @@ p_factory_ensure_frameserver(struct p_factory *fact)
return;
}
// Now load the calibration data.
if (!t_stereo_camera_calibration_load_v1_hack(&fact->data)) {
// Open the calibration file.
FILE *file = fopen(fact->settings.calibration_path, "rb");
if (file == NULL) {
return;
}
// Parse the calibration data from the file.
if (!t_stereo_camera_calibration_load_v1(file, &fact->data)) {
fclose(file);
return;
}
fclose(file);
struct xrt_frame_sink *xsink = NULL;
struct xrt_frame_sink *xsinks[4] = {0};
struct xrt_colour_rgb_f32 rgb[2] = {{1.f, 0.f, 0.f}, {1.f, 0.f, 1.f}};
@ -152,12 +170,34 @@ p_factory_ensure_frameserver(struct p_factory *fact)
// Hardcoded quirk sink.
struct u_sink_quirk_params qp;
U_ZERO(&qp);
qp.stereo_sbs = true;
qp.ps4_cam = true;
switch (fact->settings.camera_type) {
case XRT_SETTINGS_CAMERA_TYPE_REGULAR_MONO:
qp.stereo_sbs = false;
qp.ps4_cam = false;
qp.leap_motion = false;
break;
case XRT_SETTINGS_CAMERA_TYPE_REGULAR_SBS:
qp.stereo_sbs = true;
qp.ps4_cam = false;
qp.leap_motion = false;
break;
case XRT_SETTINGS_CAMERA_TYPE_PS4:
qp.stereo_sbs = true;
qp.ps4_cam = true;
qp.leap_motion = false;
break;
case XRT_SETTINGS_CAMERA_TYPE_LEAP_MOTION:
qp.stereo_sbs = true;
qp.ps4_cam = false;
qp.leap_motion = true;
break;
}
u_sink_quirk_create(&fact->xfctx, xsink, &qp, &xsink);
// Start the stream now.
xrt_fs_stream_start(fact->xfs, xsink, 1);
xrt_fs_stream_start(fact->xfs, xsink, fact->settings.camera_mode);
}
#endif
@ -173,8 +213,13 @@ p_factory_create_tracked_psmv(struct xrt_tracking_factory *xfact,
struct xrt_device *xdev,
struct xrt_tracked_psmv **out_xtmv)
{
#ifdef XRT_HAVE_OPENCV
struct p_factory *fact = p_factory(xfact);
if (!fact->setting_ok) {
return -1;
}
#ifdef XRT_HAVE_OPENCV
struct xrt_tracked_psmv *xtmv = NULL;
p_factory_ensure_frameserver(fact);
@ -201,8 +246,13 @@ p_factory_create_tracked_psvr(struct xrt_tracking_factory *xfact,
struct xrt_device *xdev,
struct xrt_tracked_psvr **out_xtvr)
{
#ifdef XRT_HAVE_OPENCV
struct p_factory *fact = p_factory(xfact);
if (!fact->setting_ok) {
return -1;
}
#ifdef XRT_HAVE_OPENCV
struct xrt_tracked_psvr *xtvr = NULL;
p_factory_ensure_frameserver(fact);
@ -254,6 +304,13 @@ p_tracking_init(struct prober *p)
// Finally set us as the tracking factory.
p->base.tracking = &fact->base;
fact->setting_ok =
p_json_get_tracking_settings(p->json.root, &fact->settings);
if (!fact->setting_ok) {
fprintf(stderr, "Failed to load settings!\n");
}
return 0;
}