You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.1 KiB
177 lines
5.1 KiB
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#include "common/visionipc.h"
|
|
#include "common/swaglog.h"
|
|
|
|
#include "extractor.h"
|
|
|
|
#ifdef DSP
|
|
#include "dsp/gen/calculator.h"
|
|
#else
|
|
#include "turbocv.h"
|
|
#endif
|
|
|
|
#include <zmq.h>
|
|
#include <capnp/serialize.h>
|
|
#include "cereal/gen/cpp/log.capnp.h"
|
|
|
|
#ifndef PATH_MAX
|
|
#include <linux/limits.h>
|
|
#endif
|
|
|
|
volatile int do_exit = 0;
|
|
|
|
static void set_do_exit(int sig) {
|
|
do_exit = 1;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int err;
|
|
printf("starting orbd\n");
|
|
|
|
#ifdef DSP
|
|
char my_path[PATH_MAX+1];
|
|
ssize_t len = readlink("/proc/self/exe", my_path, sizeof(my_path));
|
|
assert(len > 5);
|
|
my_path[len-5] = '\0';
|
|
LOGW("running from %s with PATH_MAX %d", my_path, PATH_MAX);
|
|
|
|
char adsp_path[PATH_MAX+1];
|
|
snprintf(adsp_path, PATH_MAX, "ADSP_LIBRARY_PATH=%s/dsp/gen", my_path);
|
|
assert(putenv(adsp_path) == 0);
|
|
|
|
uint32_t test_leet = 0;
|
|
assert(calculator_init(&test_leet) == 0);
|
|
assert(test_leet == 0x1337);
|
|
LOGW("orbd init complete");
|
|
#else
|
|
init_gpyrs();
|
|
#endif
|
|
|
|
signal(SIGINT, (sighandler_t) set_do_exit);
|
|
signal(SIGTERM, (sighandler_t) set_do_exit);
|
|
|
|
void *ctx = zmq_ctx_new();
|
|
|
|
void *orb_features_sock = zmq_socket(ctx, ZMQ_PUB);
|
|
assert(orb_features_sock);
|
|
zmq_bind(orb_features_sock, "tcp://*:8058");
|
|
|
|
void *orb_features_summary_sock = zmq_socket(ctx, ZMQ_PUB);
|
|
assert(orb_features_summary_sock);
|
|
zmq_bind(orb_features_summary_sock, "tcp://*:8062");
|
|
|
|
struct orb_features *features = (struct orb_features *)malloc(sizeof(struct orb_features));
|
|
int last_frame_id = 0;
|
|
|
|
VisionStream stream;
|
|
while (!do_exit) {
|
|
VisionStreamBufs buf_info;
|
|
err = visionstream_init(&stream, VISION_STREAM_YUV, true, &buf_info);
|
|
if (err) {
|
|
printf("visionstream connect fail\n");
|
|
usleep(100000);
|
|
continue;
|
|
}
|
|
uint64_t timestamp_last_eof = 0;
|
|
while (!do_exit) {
|
|
VIPCBuf *buf;
|
|
VIPCBufExtra extra;
|
|
buf = visionstream_get(&stream, &extra);
|
|
if (buf == NULL) {
|
|
printf("visionstream get failed\n");
|
|
break;
|
|
}
|
|
|
|
uint64_t start = nanos_since_boot();
|
|
#ifdef DSP
|
|
int ret = calculator_extract_and_match((uint8_t *)buf->addr, ORBD_HEIGHT*ORBD_WIDTH, (uint8_t *)features, sizeof(struct orb_features));
|
|
#else
|
|
int ret = extract_and_match_gpyrs((uint8_t *) buf->addr, features);
|
|
#endif
|
|
uint64_t end = nanos_since_boot();
|
|
LOGD("total(%d): %6.2f ms to get %4d features on %d", ret, (end-start)/1000000.0, features->n_corners, extra.frame_id);
|
|
assert(ret == 0);
|
|
|
|
if (last_frame_id+1 != extra.frame_id) {
|
|
LOGW("dropped frame!");
|
|
}
|
|
|
|
last_frame_id = extra.frame_id;
|
|
|
|
if (timestamp_last_eof == 0) {
|
|
timestamp_last_eof = extra.timestamp_eof;
|
|
continue;
|
|
}
|
|
|
|
int match_count = 0;
|
|
|
|
// *** send OrbFeatures ***
|
|
{
|
|
// create capnp message
|
|
capnp::MallocMessageBuilder msg;
|
|
cereal::Event::Builder event = msg.initRoot<cereal::Event>();
|
|
event.setLogMonoTime(nanos_since_boot());
|
|
|
|
auto orb_features = event.initOrbFeatures();
|
|
|
|
// set timestamps
|
|
orb_features.setTimestampEof(extra.timestamp_eof);
|
|
orb_features.setTimestampLastEof(timestamp_last_eof);
|
|
|
|
// init descriptors for send
|
|
kj::ArrayPtr<capnp::byte> descriptorsPtr = kj::arrayPtr((uint8_t *)features->des, ORBD_DESCRIPTOR_LENGTH * features->n_corners);
|
|
orb_features.setDescriptors(descriptorsPtr);
|
|
|
|
auto xs = orb_features.initXs(features->n_corners);
|
|
auto ys = orb_features.initYs(features->n_corners);
|
|
auto octaves = orb_features.initOctaves(features->n_corners);
|
|
auto matches = orb_features.initMatches(features->n_corners);
|
|
|
|
// copy out normalized keypoints
|
|
for (int i = 0; i < features->n_corners; i++) {
|
|
xs.set(i, features->xy[i][0] * 1.0f / ORBD_WIDTH - 0.5f);
|
|
ys.set(i, features->xy[i][1] * 1.0f / ORBD_HEIGHT - 0.5f);
|
|
octaves.set(i, features->octave[i]);
|
|
matches.set(i, features->matches[i]);
|
|
match_count += features->matches[i] != -1;
|
|
}
|
|
|
|
auto words = capnp::messageToFlatArray(msg);
|
|
auto bytes = words.asBytes();
|
|
zmq_send(orb_features_sock, bytes.begin(), bytes.size(), 0);
|
|
}
|
|
|
|
// *** send OrbFeaturesSummary ***
|
|
|
|
{
|
|
// create capnp message
|
|
capnp::MallocMessageBuilder msg;
|
|
cereal::Event::Builder event = msg.initRoot<cereal::Event>();
|
|
event.setLogMonoTime(nanos_since_boot());
|
|
|
|
auto orb_features_summary = event.initOrbFeaturesSummary();
|
|
|
|
orb_features_summary.setTimestampEof(extra.timestamp_eof);
|
|
orb_features_summary.setTimestampLastEof(timestamp_last_eof);
|
|
orb_features_summary.setFeatureCount(features->n_corners);
|
|
orb_features_summary.setMatchCount(match_count);
|
|
orb_features_summary.setComputeNs(end-start);
|
|
|
|
auto words = capnp::messageToFlatArray(msg);
|
|
auto bytes = words.asBytes();
|
|
zmq_send(orb_features_summary_sock, bytes.begin(), bytes.size(), 0);
|
|
}
|
|
|
|
timestamp_last_eof = extra.timestamp_eof;
|
|
}
|
|
}
|
|
visionstream_destroy(&stream);
|
|
return 0;
|
|
}
|
|
|
|
|