58#include <imgui_internal.h>
62#ifndef V4L2_CTRL_CLASS_DETECT
63#define V4L2_CTRL_CLASS_DETECT 0x00a30000
69 struct shortcontrol {
unsigned int id;
char const *
const shortname; };
74 static shortcontrol camcontrols[] = {
76 { V4L2_CID_BRIGHTNESS,
"brightness" },
77 { V4L2_CID_CONTRAST,
"contrast" },
78 { V4L2_CID_SATURATION,
"saturation" },
79 { V4L2_CID_HUE,
"hue" },
80 { V4L2_CID_AUDIO_VOLUME,
"audiovol" },
81 { V4L2_CID_AUDIO_BALANCE,
"audiobal" },
82 { V4L2_CID_AUDIO_BASS,
"audiobass" },
83 { V4L2_CID_AUDIO_TREBLE,
"audiotreble" },
84 { V4L2_CID_AUDIO_MUTE,
"audiomute" },
85 { V4L2_CID_AUDIO_LOUDNESS,
"audioloudness" },
86 { V4L2_CID_BLACK_LEVEL,
"blacklevel" },
87 { V4L2_CID_AUTO_WHITE_BALANCE,
"autowb" },
88 { V4L2_CID_DO_WHITE_BALANCE,
"dowb" },
89 { V4L2_CID_RED_BALANCE,
"redbal" },
90 { V4L2_CID_BLUE_BALANCE,
"bluebal" },
91 { V4L2_CID_GAMMA,
"gamma" },
92 { V4L2_CID_WHITENESS,
"whiteness" },
93 { V4L2_CID_EXPOSURE,
"exposure" },
94 { V4L2_CID_AUTOGAIN,
"autogain" },
95 { V4L2_CID_GAIN,
"gain" },
96 { V4L2_CID_HFLIP,
"hflip" },
97 { V4L2_CID_VFLIP,
"vflip" },
98 { V4L2_CID_POWER_LINE_FREQUENCY,
"powerfreq" },
99 { V4L2_CID_HUE_AUTO,
"autohue" },
100 { V4L2_CID_WHITE_BALANCE_TEMPERATURE,
"wbtemp" },
101 { V4L2_CID_SHARPNESS,
"sharpness" },
102 { V4L2_CID_BACKLIGHT_COMPENSATION,
"backlight" },
103 { V4L2_CID_CHROMA_AGC,
"chromaagc" },
104 { V4L2_CID_COLOR_KILLER,
"colorkiller" },
105 { V4L2_CID_COLORFX,
"colorfx" },
106 { V4L2_CID_AUTOBRIGHTNESS,
"autobrightness" },
107 { V4L2_CID_BAND_STOP_FILTER,
"bandfilter" },
108 { V4L2_CID_ROTATE,
"rotate" },
109 { V4L2_CID_BG_COLOR,
"bgcolor" },
110 { V4L2_CID_CHROMA_GAIN,
"chromagain" },
111 { V4L2_CID_ILLUMINATORS_1,
"illum1" },
112 { V4L2_CID_ILLUMINATORS_2,
"illum2" },
113 { V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
"mincapbuf" },
114 { V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
"minoutbuf" },
115 { V4L2_CID_ALPHA_COMPONENT,
"alphacompo" },
120 { V4L2_CID_EXPOSURE_AUTO,
"autoexp" },
121 { V4L2_CID_EXPOSURE_ABSOLUTE,
"absexp" },
122 { V4L2_CID_EXPOSURE_AUTO_PRIORITY,
"exppri" },
123 { V4L2_CID_PAN_RELATIVE,
"panrel" },
124 { V4L2_CID_TILT_RELATIVE,
"tiltrel" },
125 { V4L2_CID_PAN_RESET,
"panreset" },
126 { V4L2_CID_TILT_RESET,
"tiltreset" },
127 { V4L2_CID_PAN_ABSOLUTE,
"panabs" },
128 { V4L2_CID_TILT_ABSOLUTE,
"tiltabs" },
129 { V4L2_CID_FOCUS_ABSOLUTE,
"focusabs" },
130 { V4L2_CID_FOCUS_RELATIVE,
"focusrel" },
131 { V4L2_CID_FOCUS_AUTO,
"focusauto" },
132 { V4L2_CID_ZOOM_ABSOLUTE,
"zoomabs" },
133 { V4L2_CID_ZOOM_RELATIVE,
"zoomrel" },
134 { V4L2_CID_ZOOM_CONTINUOUS,
"zoomcontinuous" },
135 { V4L2_CID_PRIVACY,
"privacy" },
136 { V4L2_CID_IRIS_ABSOLUTE,
"irisabs" },
137 { V4L2_CID_IRIS_RELATIVE,
"irisrel" },
140#ifndef V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE
141#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20)
162 { V4L2_CID_FLASH_LED_MODE,
"flashled" },
163 { V4L2_CID_FLASH_STROBE_SOURCE,
"flashstrobesrc" },
164 { V4L2_CID_FLASH_STROBE,
"flashstrobe" },
165 { V4L2_CID_FLASH_STROBE_STOP,
"flashstrobestop" },
166 { V4L2_CID_FLASH_STROBE_STATUS,
"flashstrovestat" },
167 { V4L2_CID_FLASH_TIMEOUT,
"flashtimeout" },
168 { V4L2_CID_FLASH_INTENSITY,
"flashintens" },
169 { V4L2_CID_FLASH_TORCH_INTENSITY,
"flashtorch" },
170 { V4L2_CID_FLASH_INDICATOR_INTENSITY,
"flashindintens" },
171 { V4L2_CID_FLASH_FAULT,
"flashfault" },
172 { V4L2_CID_FLASH_CHARGE,
"flashcharge" },
173 { V4L2_CID_FLASH_READY,
"flashready" },
176 { V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
"jpegchroma" },
177 { V4L2_CID_JPEG_RESTART_INTERVAL,
"jpegrestartint" },
178 { V4L2_CID_JPEG_COMPRESSION_QUALITY,
"jpegcompression" },
179 { V4L2_CID_JPEG_ACTIVE_MARKER,
"jpegmarker" },
204 std::string abbreviate(std::string
const & longname)
206 std::string name(longname);
207 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
208 name.erase(std::remove_if(name.begin(), name.end(), [](
int c) { return !std::isalnum(c); }), name.end());
215namespace jevois {
namespace engine {
static std::atomic<size_t> frameNumber(0); } }
217size_t jevois::frameNum()
218{
return jevois::engine::frameNumber.load(); }
222 jevois::
Manager(instance), itsMappings(), itsRunning(false), itsStreaming(false), itsStopMainLoop(false),
223 itsShellMode(false), itsTurbo(false), itsManualStreamon(false), itsVideoErrors(false),
224 itsNumSerialSent(0), itsRequestedFormat(-2)
228#ifdef JEVOIS_PLATFORM_A33
230 itsCheckingMassStorage.store(
false); itsMassStorageMode.store(
false);
232 while (itsCheckingMassStorage.load() ==
false) std::this_thread::sleep_for(std::chrono::milliseconds(5));
235 jevois::engine::frameNumber.store(0);
245 jevois::
Manager(argc, argv, instance), itsMappings(), itsRunning(false), itsStreaming(false),
246 itsStopMainLoop(false), itsShellMode(false), itsTurbo(false), itsManualStreamon(false), itsVideoErrors(false),
247 itsNumSerialSent(0), itsRequestedFormat(-2)
251#ifdef JEVOIS_PLATFORM_A33
253 itsCheckingMassStorage.store(
false); itsMassStorageMode.store(
false);
255 while (itsCheckingMassStorage.load() ==
false) std::this_thread::sleep_for(std::chrono::milliseconds(5));
258 jevois::engine::frameNumber.store(0);
272 for (std::list<std::shared_ptr<UserInterface> >::iterator itr = itsSerials.begin(); itr != itsSerials.end(); ++itr)
273 if ((*itr)->instanceName() ==
"serial") itr = itsSerials.erase(itr);
274 removeComponent(
"serial",
false);
277 if (newval.empty() ==
false)
280 std::shared_ptr<jevois::UserInterface> s;
281 if (newval ==
"stdio")
282 s = addComponent<jevois::StdioInterface>(
"serial");
289 if (serialmonitors::get())
296 s->setParamVal(
"devname", newval);
299 itsSerials.push_back(s);
300 LINFO(
"Using [" << newval <<
"] hardware (4-pin connector) serial port");
303 else LINFO(
"No hardware (4-pin connector) serial port used");
312 for (std::list<std::shared_ptr<UserInterface> >::iterator itr = itsSerials.begin(); itr != itsSerials.end(); ++itr)
313 if ((*itr)->instanceName() ==
"usbserial") itr = itsSerials.erase(itr);
314 removeComponent(
"usbserial",
false);
317 if (newval.empty() ==
false)
324 std::shared_ptr<jevois::UserInterface> s;
325 if (serialmonitors::get())
330 std::shared_ptr<jevois::UserInterface> s =
333 s->setParamVal(
"devname", newval);
334 itsSerials.push_back(s);
335 LINFO(
"Using [" << newval <<
"] USB serial port");
338 else LINFO(
"No USB serial port used");
345 std::ofstream ofs(
"/sys/devices/system/cpu/cpu2/cpufreq/scaling_governor");
347 std::ofstream ofs(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
349 if (ofs.is_open() ==
false)
351#ifdef JEVOIS_PLATFORM
352 LERROR(
"Cannot set cpu frequency governor mode -- IGNORED");
359 case engine::CPUmode::PowerSave: ofs <<
"powersave" << std::endl;
break;
360 case engine::CPUmode::Conservative: ofs <<
"conservative" << std::endl;
break;
361 case engine::CPUmode::OnDemand: ofs <<
"ondemand" << std::endl;
break;
362 case engine::CPUmode::Interactive: ofs <<
"interactive" << std::endl;
break;
363 case engine::CPUmode::Performance: ofs <<
"performance" << std::endl;
break;
371 std::ofstream ofs(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
372 if (ofs.is_open() ==
false)
374#ifdef JEVOIS_PLATFORM
375 LERROR(
"Cannot set cpu frequency governor mode -- IGNORED");
382 case engine::CPUmode::PowerSave: ofs <<
"powersave" << std::endl;
break;
383 case engine::CPUmode::Conservative: ofs <<
"conservative" << std::endl;
break;
384 case engine::CPUmode::OnDemand: ofs <<
"ondemand" << std::endl;
break;
385 case engine::CPUmode::Interactive: ofs <<
"interactive" << std::endl;
break;
386 case engine::CPUmode::Performance: ofs <<
"performance" << std::endl;
break;
395 std::ofstream ofs(
"/sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq");
397 std::ofstream ofs(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
400 if (ofs.is_open() ==
false)
402#ifdef JEVOIS_PLATFORM
403 LERROR(
"Cannot set cpu max frequency -- IGNORED");
408 ofs << newval * 1000U << std::endl;
414 itsVideoErrors.store(newval);
426 itsGUIhelper = addComponent<jevois::GUIhelper>(
"gui", conslock::get());
427 auto s = addComponent<jevois::GUIconsole>(
"guiconsole");
428 itsSerials.push_back(s);
429 LINFO(
"GUI enabled.");
432 else if (itsGUIhelper)
434 for (
auto itr = itsSerials.begin(); itr != itsSerials.end(); ++itr)
435 if ((*itr)->instanceName() ==
"guiconsole") { itsSerials.erase(itr);
break; }
436 removeComponent(
"guiconsole",
false);
437 removeComponent(itsGUIhelper);
438 itsGUIhelper.reset();
439 LINFO(
"GUI disabled.");
446 std::ofstream ofs(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
448 if (ofs.is_open() ==
false)
450#ifdef JEVOIS_PLATFORM
451 LERROR(
"Cannot set cpu max frequency -- IGNORED");
456 ofs << newval * 1000U << std::endl;
463 if (newval == 0.0F) itsDemoReset =
true;
467void jevois::Engine::runDemoStep()
469 if (! itsGUIhelper)
return;
471 int constexpr fade = 30;
472 int constexpr msg = 90;
473 int constexpr tmax = 15;
482 static size_t modidx = 0;
483 static int fade_out = 0, show_msg = 0, fade_in = 0;
484 static std::chrono::time_point<std::chrono::steady_clock> mod_load_time;
485 std::chrono::time_point<std::chrono::steady_clock>
const now = std::chrono::steady_clock::now();
492 if (fs.isOpened() ==
false)
495 cv::FileNode fn = fs.root();
496 for (cv::FileNodeIterator gfit = fn.begin(); gfit != fn.end(); ++gfit)
498 cv::FileNode item = *gfit;
499 if (! item.isMap())
continue;
502 for(cv::FileNodeIterator fit = item.begin(); fit != item.end(); ++fit)
504 cv::FileNode param = *fit;
506 std::string k = param.name();
507 if (k ==
"demomapping")
509 std::string
const vmstr = (std::string)param;
511 int idx = 0; dd.mapping_idx = -1;
513 {
if (vm.
isSameAs(m)) dd.mapping_idx = idx;
else ++idx; });
514 if (dd.mapping_idx == -1) {
LERROR(
"Video mapping not found for [" << vmstr <<
"] -- SKIPPED");
break; }
516 else if (k ==
"demotitle")
517 dd.title = (std::string)param;
518 else if (k ==
"demomsg")
519 dd.msg = (std::string)param;
523 switch (param.type())
525 case cv::FileNode::INT: v = std::to_string((
int)param);
break;
526 case cv::FileNode::REAL: v = std::to_string((
float)param);
break;
527 case cv::FileNode::STRING: v = (std::string)param;
break;
528 default:
LERROR(
"Invalid demo parameter for [" << item.name() <<
"]: " << k <<
" type " << param.type());
531 if (dd.mapping_idx != -1) dd.params.emplace_back(std::make_pair(k, v));
535 itsDemoData.emplace_back(std::move(dd));
538 if (itsDemoData.empty())
540 else LINFO(
"Loaded demo information with " << itsDemoData.size() <<
" demo modules.");
543 fade_out = 0; show_msg = msg * 3; fade_in = 0; mod_load_time = now; modidx = 0;
544 itsGUIhelper->demoBanner(
"Welcome to JeVois-Pro!",
"This demo will cycle through a few machine vision algorithms.");
545 itsDemoReset =
false;
550 if (itsNextDemoRequested)
552 ++modidx;
if (modidx >= itsDemoData.size()) modidx = 0;
553 fade_out = 0; show_msg = msg; fade_in = 0; mod_load_time = now;
554 itsNextDemoRequested =
false;
558 if (show_msg == msg || itsGUIhelper->idle() ==
false)
559 itsGUIhelper->demoBanner(itsDemoData[modidx].title, itsDemoData[modidx].msg);
563 itsGUIhelper->twirl::set(tmax);
567 LINFO(
"Loading demo: " << itsDemoData[modidx].title);
568 requestSetFormat(itsDemoData[modidx].mapping_idx);
574 if (show_msg == 0) fade_in = fade;
580 for (
auto const & pp : itsDemoData[modidx].params)
581 try { setParamString(pp.first, pp.second); }
582 catch (...) {
LERROR(
"Failed to set param [" << pp.first <<
"] to [" << pp.second <<
"] -- IGNORED"); }
587 itsGUIhelper->twirl::set(
float(tmax * fade_in - tmax) /
float(fade));
588 if (--fade_in == 0 && itsGUIhelper->idle()) itsGUIhelper->demoBanner();
595 itsGUIhelper->twirl::set(tmax -
float(tmax * fade_out - tmax) /
float(fade));
596 if (--fade_out == 0) show_msg = msg;
601 std::chrono::duration<float>
const elapsed = now - mod_load_time;
602 if (elapsed.count() > demomode::get())
605 ++modidx;
if (modidx >= itsDemoData.size()) modidx = 0;
611{ itsNextDemoRequested =
true; }
618 if (! itsGUIhelper)
return;
620 itsGUIhelper->twirl::set(0.0F);
621 itsGUIhelper->demoBanner();
631 std::ifstream ifs(paramcfg);
if (ifs.is_open()) setParamsFromStream(ifs, paramcfg);
646 itsMappings = jevois::loadVideoMappings(camerasens::get(), itsDefaultMappingIdx,
true, usegui);
647 LINFO(
"Loaded " << itsMappings.size() <<
" vision processing modes.");
662 serialmonitors::freeze(
true);
664 serialdev::freeze(
true);
665 usbserialdev::freeze(
true);
666 for (
auto & s : itsSerials) s->freezeAllParams(
true);
667 cameradev::freeze(
true);
668 imudev::freeze(
true);
669 cameranbuf::freeze(
true);
670 camturbo::freeze(
true);
671 gadgetdev::freeze(
true);
672 gadgetnbuf::freeze(
true);
673 itsTurbo = camturbo::get();
674 multicam::freeze(
true);
675 quietcmd::freeze(
true);
676 python::freeze(
true);
680 jevois::CameraSensor camsens = camerasens::get();
681#ifdef JEVOIS_PLATFORM_PRO
682 if (camsens == jevois::CameraSensor::any)
685 size_t idx = 0;
while (idx < str.length() && std::isalnum(str[idx])) ++idx;
686 str = str.substr(0, idx);
687 camerasens::strset(str);
688 camsens = camerasens::get();
689 LINFO(
"Camera sensor selected from device tree: " << camsens);
692 camerasens::freeze(
true);
693 LINFO(
"Using camera sensor: " << camsens <<
" with lens: " << cameralens::get());
700 conslock::freeze(
true);
701 watchdog::freeze(
true);
708 reloadVideoMappings();
716 LINFO(
"Initalizing Python...");
721 std::string
const camdev = cameradev::get();
724 LINFO(
"Starting camera device " << camdev);
726#ifdef JEVOIS_PLATFORM_A33
728 std::ofstream ofs(
"/sys/module/vfe_v4l2/parameters/turbo");
731 if (itsTurbo) ofs <<
"1" << std::endl;
else ofs <<
"0" << std::endl;
734 else LERROR(
"Could not access VFE turbo parameter -- IGNORED");
738 itsCamera.reset(
new jevois::Camera(camdev, camsens, cameranbuf::get()));
740#ifndef JEVOIS_PLATFORM
742 camreg::set(
false); camreg::freeze(
true);
743 imureg::set(
false); imureg::freeze(
true);
749#ifdef JEVOIS_PLATFORM_A33
751 itsIMU.reset(
new jevois::IMUi2c(std::dynamic_pointer_cast<jevois::Camera>(itsCamera)));
755#ifdef JEVOIS_PLATFORM_PRO
759 }
catch (...) {
LERROR(
"Sensor should have an IMU but we failed to initialize it."); }
763 LINFO(
"Using movie input " << camdev <<
" -- issue a 'streamon' to start processing.");
768 camreg::freeze(
true);
773 int midx = videomapping::get();
776 videomapping::freeze(
true);
778 if (midx >=
int(itsMappings.size()))
779 {
LERROR(
"Mapping index " << midx <<
" out of range -- USING DEFAULT"); midx = -1; }
781 if (midx < 0) midx = itsDefaultMappingIdx;
784 std::string
const gd = gadgetdev::get();
787 LINFO(
"Using no USB video output.");
790 itsManualStreamon =
true;
794 LINFO(
"Loading USB video driver " << gd);
796 itsGadget.reset(
new jevois::Gadget(gd, itsCamera.get(),
this, gadgetnbuf::get(), multicam::get()));
798 else if (gd.empty() ==
false)
800 LINFO(
"Saving output video to file " << gd);
803 itsManualStreamon =
true;
812 LINFO(
"Using OpenGL + ImGui display for video output");
817 LINFO(
"Using OpenGL display for video output");
822 LINFO(
"Using OpenCV display for video output");
826 itsManualStreamon =
true;
830 itsRunning.store(
true);
848 itsRunning.store(
false);
850#ifdef JEVOIS_PLATFORM_A33
852 itsCheckingMassStorage.store(
false);
858 if (itsModule) removeComponent(itsModule);
869#ifdef JEVOIS_PLATFORM_A33
871 if (itsCheckMassStorageFut.valid())
880#ifdef JEVOIS_PLATFORM_A33
881void jevois::Engine::checkMassStorage()
883 itsCheckingMassStorage.store(
true);
885 while (itsCheckingMassStorage.load())
891 std::ifstream ifs(
"/sys/devices/platform/sunxi_usb_udc/gadget/lun0/mass_storage_in_use");
894 int inuse; ifs >> inuse;
895 if (itsMassStorageMode.load())
897 if (inuse == 0) stopMassStorageMode();
904 std::this_thread::sleep_for(std::chrono::milliseconds(500));
915 if (itsCamera) itsCamera->streamOn();
916 if (itsGadget) itsGadget->streamOn();
917 itsStreaming.store(
true);
926 if (itsGadget) itsGadget->abortStream();
927 if (itsCamera) itsCamera->abortStream();
930 LDEBUG(
"Stopping main loop...");
931 itsStopMainLoop.store(
true);
932 while (itsStopMainLoop.load() && itsRunning.load()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
933 LDEBUG(
"Main loop stopped.");
937 if (itsGadget) itsGadget->streamOff();
938 if (itsCamera) itsCamera->streamOff();
945 itsRequestedFormat.store(idx);
953 LDEBUG(
"Set format number " << idx <<
" start...");
955 if (idx >= itsMappings.size())
956 LFATAL(
"Requested mapping index " << idx <<
" out of range [0 .. " << itsMappings.size()-1 <<
']');
959 setFormatInternal(idx);
960 LDEBUG(
"Set format number " << idx <<
" done");
964void jevois::Engine::setFormatInternal(
size_t idx)
970 setFormatInternal(m);
980 itsModuleConstructionError =
"Unknown error while starting module " + m.
modulename +
" ...";
982#ifdef JEVOIS_PLATFORM_A33
983 if (itsMassStorageMode.load())
984 LFATAL(
"Cannot setup video streaming while in mass-storage mode. Eject the USB drive on your host computer first.");
992 LDEBUG(
"Removing current module " << itsModule->className() <<
": " << itsModule->descriptor());
993 try { removeComponent(itsModule); itsModule.reset();
LDEBUG(
"Current module removed."); }
1001 try { itsCamera->setFormat(m); }
1005 itsModuleConstructionError =
"Camera did not accept format:\n\n" + m.
cstrall() +
1006 "\n\nCheck videomappings.cfg and camera sensor specifications.";
1010 LDEBUG(
"Setting gadget format: " << m.
ostr());
1011 try { itsGadget->setFormat(m); }
1015 itsModuleConstructionError =
"Gadget did not accept format:\n\n" + m.
ostr() +
1016 "\n\nCheck videomappings.cfg for any unsupported output formats.";
1022 itsCurrentMapping = m;
1025 jevois::engine::frameNumber.store(0);
1033 std::string
const sopath = m.
sopath(
true);
1036 if (python::get() ==
false)
LFATAL(
"Python disabled, delete BOOT:nopython and restart to enable python");
1047 if (itsLoader.get() ==
nullptr || itsLoader->sopath() != sopath)
1049 LINFO(
"Instantiating dynamic loader for " << sopath);
1055 auto version_major = itsLoader->load<int()>(m.
modulename +
"_version_major");
1056 auto version_minor = itsLoader->load<int()>(m.
modulename +
"_version_minor");
1058 LERROR(
"Module " << m.
modulename <<
" in file " << sopath <<
" was build for JeVois v" << version_major() <<
'.'
1059 << version_minor() <<
", but running framework is v" <<
JEVOIS_VERSION_STRING <<
" -- TRYING ANYWAY");
1062 auto create = itsLoader->load<std::shared_ptr<jevois::Module>(std::string
const &)>(m.
modulename +
"_create");
1069 boost::unique_lock<boost::shared_mutex> ulck(itsSubMtx);
1072 itsSubComponents.push_back(itsModule);
1073 itsModule->itsParent =
this;
1074 itsModule->setPath(sopath.substr(0, sopath.rfind(
'/')));
1078 if (itsInitialized) itsModule->runPreInit();
1081 std::ifstream ifs(paramcfg);
if (ifs.is_open()) itsModule->setParamsFromStream(ifs, paramcfg);
1083 if (itsInitialized) { itsModule->setInitialized(); itsModule->runPostInit(); }
1086 std::shared_ptr<jevois::UserInterface> ser;
1087 for (
auto & s : itsSerials)
1088 if (s->type() ==
jevois::UserInterface::Type::USB || s->type() ==
jevois::UserInterface::Type::GUI)
1093 LINFO(
"Module [" << m.
modulename <<
"] loaded, initialized, and ready.");
1094 itsModuleConstructionError.clear();
1100 LERROR(
"Module [" << m.
modulename <<
"] startup error and not operational.");
1119 for (
auto & s : itsSerials)
1124 while (itsRunning.load())
1126 bool dosleep =
true;
1130 itsWatchdog->reset();
1135 int rf = itsRequestedFormat.load();
1139 itsRequestedFormat.store(-2);
1144 if (rf != -1 && itsStreaming.load())
1147 if (itsGadget) itsGadget->abortStream();
1148 if (itsCamera) itsCamera->abortStream();
1150 if (itsGadget) itsGadget->streamOff();
1151 if (itsCamera) itsCamera->streamOff();
1152 itsStreaming.store(
false);
1160 setFormatInternal(itsCurrentMapping,
true);
1166 if (itsGUIhelper) itsGUIhelper->resetstate( (rf != -1) );
1170 if (rf != -1 && itsCurrentMapping.ofmt != 0)
1174 if (itsCamera) itsCamera->streamOn();
1175 if (itsGadget) itsGadget->streamOn();
1176 itsStreaming.store(
true);
1182 if (itsGUIhelper && itsStreaming.load() ==
false)
1186 if (itsCamera) itsCamera->streamOn();
1187 if (itsGadget) itsGadget->streamOn();
1188 itsStreaming.store(
true);
1194 reportErrorInternal();
1199 if (itsGadget) itsGadget->abortStream();
1200 if (itsCamera) itsCamera->abortStream();
1202 if (itsGadget) itsGadget->streamOff();
1203 if (itsCamera) itsCamera->streamOff();
1204 itsStreaming.store(
false);
1212 if (demomode::get()) runDemoStep();
1216 if (itsStreaming.load())
1221 if (itsModuleConstructionError.empty() ==
false)
1224 reportErrorInternal(itsModuleConstructionError);
1239 switch (itsCurrentMapping.ofmt)
1248 if (itsGUIhelper) itsGUIhelper->headlessDisplay();
1272 catch (...) { reportErrorInternal(); }
1278 ++ jevois::engine::frameNumber;
1279 itsNumSerialSent.store(0);
1283 if (itsStopMainLoop.load())
1285 itsStreaming.store(
false);
1286 LDEBUG(
"-- Main loop stopped --");
1287 itsStopMainLoop.store(
false);
1292 LDEBUG(
"No processing module loaded or not streaming... Sleeping...");
1293 std::this_thread::sleep_for(std::chrono::milliseconds(25));
1298 for (
auto & s : itsSerials)
1302 std::string str;
int received = 0;
1304 while (s->readSome(str))
1306 bool parsed =
false;
bool success =
false;
1309 if ((++received % 10) == 0)
1310 reportError(
"Warning: high rate of serial inputs on port: " + s->instanceName() +
". \n\n"
1311 "This may adversely affect JeVois framerate.");
1319 pfx = JEVOIS_JVINV_PREFIX;
1320 str = str.substr(pfx.length());
1327 try { parsed = parseCommand(str, s, pfx);
success = parsed; }
1328 catch (std::exception
const & e)
1329 { s->writeString(pfx, std::string(
"ERR ") + e.what()); parsed =
true; }
1331 { s->writeString(pfx,
"ERR Unknown error"); parsed =
true; }
1333 if (parsed ==
false)
1338 try { itsModule->parseSerial(str, s);
success =
true; }
1339 catch (std::exception
const & me) { s->writeString(pfx, std::string(
"ERR ") + me.what()); }
1340 catch (...) { s->writeString(pfx,
"ERR Command [" + str +
"] not recognized by Engine or Module"); }
1342 else s->writeString(pfx,
"ERR Unsupported command [" + str +
"] and no module");
1346 if (
success && quietcmd::get() ==
false && itsShellMode ==
false) s->writeString(pfx,
"OK");
1359 size_t slim = serlimit::get();
1360 if (islog ==
false && slim)
1362 if (itsNumSerialSent.load() >= slim)
return;
1367 jevois::engine::SerPort p = islog ? serlog::get() : serout::get();
1370 case jevois::engine::SerPort::None:
1373 case jevois::engine::SerPort::All:
1374 for (
auto & s : itsSerials)
1378 case jevois::engine::SerPort::Hard:
1379 for (
auto & s : itsSerials)
1384 case jevois::engine::SerPort::USB:
1385 for (
auto & s : itsSerials)
1393 if (itsGUIhelper && ((islog && itsGUIhelper->serlogEnabled()) || (!islog && itsGUIhelper->seroutEnabled())))
1394 for (
auto & s : itsSerials)
1404 if (itsGUIhelper) itsGUIhelper->reportError(err);
1413 if (itsGUIhelper) itsGUIhelper->reportError(info);
1423 if (itsGUIhelper) itsGUIhelper->clearErrors();
1429void jevois::Engine::reportErrorInternal(std::string
const & err)
1435 if (itsGUIhelper->frameStarted() ==
false) {
unsigned short w,
h; itsGUIhelper->startFrame(w,
h); }
1437 else itsGUIhelper->reportError(err);
1438 itsGUIhelper->endFrame();
1445 if (itsCurrentMapping.ofmt != 0 && itsCurrentMapping.ofmt !=
JEVOISPRO_FMT_GUI && itsVideoErrors.load())
1450 if (itsVideoErrorImage.valid() ==
false) itsGadget->get(itsVideoErrorImage);
1461 if (itsVideoErrorImage.valid()) itsGadget->send(itsVideoErrorImage);
1466 itsVideoErrorImage.invalidate();
1478{
return itsModule; }
1481std::shared_ptr<jevois::IMU> jevois::Engine::imu()
const
1486{
return std::dynamic_pointer_cast<jevois::Camera>(itsCamera); }
1495 if (itsCurrentMapping.c2fmt) { w = itsCurrentMapping.c2w;
h = itsCurrentMapping.c2h; }
1496 else { w = itsCurrentMapping.cw;
h = itsCurrentMapping.ch; }
1499 '-' + camerasens::strget() +
'-' + std::to_string(w) +
'x' + std::to_string(
h) +
1500 '-' + cameralens::strget() +
".yaml";
1507 LINFO(
"Camera calibration loaded from [" << fname <<
']');
1512 LFATAL(
"Failed to read camera parameters from file [" << fname <<
']');
1515 reportError(
"Failed to read camera parameters from file [" + fname +
"] -- IGNORED");
1518 calib.
sensor = camerasens::get();
1519 calib.
lens = cameralens::get();
1520 calib.
w = w; calib.
h =
h;
1537 LINFO(
"Camera calibration saved to [" << fname <<
']');
1542{
return itsCurrentMapping; }
1546{
return itsMappings.size(); }
1551 if (idx >= itsMappings.size())
1552 LFATAL(
"Index " << idx <<
" out of range [0 .. " << itsMappings.size()-1 <<
']');
1554 return itsMappings[idx];
1561 if (iformat == 0 || iframe == 0)
return itsDefaultMappingIdx;
1574 LFATAL(
"No video mapping for iformat=" << iformat <<
", iframe=" << iframe <<
", interval=" << interval);
1584 LFATAL(
"No video mapping for iformat=" << iformat <<
", iframe=" << iframe <<
", interval=" << interval);
1590{
return itsMappings[itsDefaultMappingIdx]; }
1594{
return itsDefaultMappingIdx; }
1606 float oframespersec)
const
1609 if (m.
match(oformat, owidth, oheight, oframespersec))
return m;
1612 owidth <<
'x' << oheight <<
" @ " << oframespersec <<
" fps");
1616void jevois::Engine::foreachCamCtrl(std::function<
void(
struct v4l2_queryctrl & qc, std::set<int> & doneids)> && func)
1618 struct v4l2_queryctrl qc = { }; std::set<int> doneids;
1624 qc.id = cls | 0x900;
unsigned int old_id;
1627 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL; old_id = qc.id;
bool failed =
false;
1628 try { func(qc, doneids); }
catch (...) { failed =
true; }
1632 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1633 if (qc.id == old_id) { ++qc.id;
if (qc.id > 100 + (cls | 0x900 | V4L2_CTRL_FLAG_NEXT_CTRL))
break; }
1634 else if (failed)
break;
1640std::string jevois::Engine::camctrlname(
unsigned int id,
char const * longname)
const
1642 for (
size_t i = 0; i <
sizeof camcontrols /
sizeof camcontrols[0]; ++i)
1643 if (camcontrols[i].
id ==
id)
return camcontrols[i].shortname;
1646 return abbreviate(longname);
1650unsigned int jevois::Engine::camctrlid(std::string
const & shortname)
1652 for (
size_t i = 0; i <
sizeof camcontrols /
sizeof camcontrols[0]; ++i)
1653 if (shortname.compare(camcontrols[i].shortname) == 0)
return camcontrols[i].id;
1656 struct v4l2_queryctrl qc = { };
1662 qc.id = cls | 0x900;
1665 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
unsigned int old_id = qc.id;
bool failed =
false;
1668 itsCamera->queryControl(qc);
1669 if (abbreviate(
reinterpret_cast<char const *
>(qc.name)) == shortname)
return qc.id;
1671 catch (...) { failed =
true; }
1676 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1677 if (qc.id == old_id) { ++qc.id;
if (qc.id > 100 + (cls | 0x900 | V4L2_CTRL_FLAG_NEXT_CTRL))
break; }
1678 else if (failed)
break;
1682 LFATAL(
"Could not find control [" << shortname <<
"] in the camera");
1686std::string jevois::Engine::camCtrlHelp(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
1689 itsCamera->queryControl(qc);
1690 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
1693 if (doneids.find(qc.id) != doneids.end())
return std::string();
else doneids.insert(qc.id);
1696 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
1697 itsCamera->getControl(ctrl);
1700 std::ostringstream ss;
1701 ss <<
"- " << camctrlname(qc.id,
reinterpret_cast<char const *
>(qc.name));
1705 case V4L2_CTRL_TYPE_INTEGER:
1706 ss <<
" [int] min=" << qc.minimum <<
" max=" << qc.maximum <<
" step=" << qc.step
1707 <<
" def=" << qc.default_value <<
" curr=" << ctrl.value;
1719 case V4L2_CTRL_TYPE_BOOLEAN:
1720 ss <<
" [bool] default=" << qc.default_value <<
" curr=" << ctrl.value;
1729 case V4L2_CTRL_TYPE_BUTTON:
1733 case V4L2_CTRL_TYPE_BITMASK:
1734 ss <<
" [bitmask] max=" << qc.maximum <<
" def=" << qc.default_value <<
" curr=" << ctrl.value;
1737 case V4L2_CTRL_TYPE_MENU:
1739 struct v4l2_querymenu querymenu = { };
1740 querymenu.id = qc.id;
1741 ss <<
" [menu] values ";
1742 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
1744 try { itsCamera->queryMenu(querymenu); }
catch (...) { strcpy((
char *)(querymenu.name),
"fixme"); }
1745 ss << querymenu.index <<
':' << querymenu.name <<
' ';
1747 ss <<
"curr=" << ctrl.value;
1752 ss <<
"[unknown type]";
1755 if (qc.flags & V4L2_CTRL_FLAG_DISABLED) ss <<
" [DISABLED]";
1761std::string jevois::Engine::camCtrlInfo(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
1764 itsCamera->queryControl(qc);
1765 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
1768 if (doneids.find(qc.id) != doneids.end())
return std::string();
else doneids.insert(qc.id);
1771 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
1772 itsCamera->getControl(ctrl);
1775 std::ostringstream ss;
1776 ss << camctrlname(qc.id,
reinterpret_cast<char const *
>(qc.name));
1778 if (qc.flags & V4L2_CTRL_FLAG_DISABLED) ss <<
" D ";
1782 case V4L2_CTRL_TYPE_INTEGER:
1783 ss <<
" I " << qc.minimum <<
' ' << qc.maximum <<
' ' << qc.step
1784 <<
' ' << qc.default_value <<
' ' << ctrl.value;
1795 case V4L2_CTRL_TYPE_BOOLEAN:
1796 ss <<
" B " << qc.default_value <<
' ' << ctrl.value;
1804 case V4L2_CTRL_TYPE_BUTTON:
1808 case V4L2_CTRL_TYPE_BITMASK:
1809 ss <<
" K " << qc.maximum <<
' ' << qc.default_value <<
' ' << ctrl.value;
1812 case V4L2_CTRL_TYPE_MENU:
1814 struct v4l2_querymenu querymenu = { };
1815 querymenu.id = qc.id;
1816 ss <<
" M " << qc.default_value <<
' ' << ctrl.value;
1817 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
1819 try { itsCamera->queryMenu(querymenu); }
catch (...) { strcpy((
char *)(querymenu.name),
"fixme"); }
1820 ss <<
' ' << querymenu.index <<
':' << querymenu.name <<
' ';
1832#ifdef JEVOIS_PLATFORM_A33
1834void jevois::Engine::startMassStorageMode()
1838 if (itsMassStorageMode.load()) {
LERROR(
"Already in mass-storage mode -- IGNORED");
return; }
1841 if (itsModule) { removeComponent(itsModule); itsModule.reset(); }
1842 if (itsLoader) itsLoader.reset();
1845 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1846 if (std::system(
"mount -o remount,ro /jevois"))
LERROR(
"Failed to remount /jevois read-only -- IGNORED");
1853 LINFO(
"Exported JEVOIS partition of microSD to host computer as virtual flash drive.");
1854 itsMassStorageMode.store(
true);
1858void jevois::Engine::stopMassStorageMode()
1861 LINFO(
"JeVois virtual USB drive ejected by host -- REBOOTING");
1869 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1870 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1871#ifdef JEVOIS_PLATFORM_A33
1872 itsCheckingMassStorage.store(
false);
1874 itsRunning.store(
false);
1876#ifdef JEVOIS_PLATFORM_A33
1878 if ( ! std::ofstream(
"/proc/sys/kernel/sysrq").put(
'1'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1879 if ( ! std::ofstream(
"/proc/sysrq-trigger").put(
's'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1880 if ( ! std::ofstream(
"/proc/sysrq-trigger").put(
'b'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1891 itsGadget->abortStream();
1892 itsCamera->abortStream();
1893 itsStreaming.store(
false);
1894 itsGadget->streamOff();
1895 itsCamera->streamOff();
1896 itsRunning.store(
false);
1902void jevois::Engine::cmdInfo(std::shared_ptr<UserInterface> s,
bool showAll, std::string
const & pfx)
1904 s->writeString(pfx,
"help - print this help message");
1905 s->writeString(pfx,
"help2 - print compact help message about current vision module only");
1906 s->writeString(pfx,
"info - show system information including CPU speed, load and temperature");
1907 s->writeString(pfx,
"setpar <name> <value> - set a parameter value");
1908 s->writeString(pfx,
"getpar <name> - get a parameter value(s)");
1909 s->writeString(pfx,
"runscript <filename> - run script commands in specified file");
1910 s->writeString(pfx,
"setcam <ctrl> <val> - set camera control <ctrl> to value <val>");
1911 s->writeString(pfx,
"getcam <ctrl> - get value of camera control <ctrl>");
1913 if (showAll || camreg::get())
1915 s->writeString(pfx,
"setcamreg <reg> <val> - set raw camera register <reg> to value <val>");
1916 s->writeString(pfx,
"getcamreg <reg> - get value of raw camera register <reg>");
1917 s->writeString(pfx,
"setimureg <reg> <val> - set raw IMU register <reg> to value <val>");
1918 s->writeString(pfx,
"getimureg <reg> - get value of raw IMU register <reg>");
1919 s->writeString(pfx,
"setimuregs <reg> <num> <val1> ... <valn> - set array of raw IMU register values");
1920 s->writeString(pfx,
"getimuregs <reg> <num> - get array of raw IMU register values");
1921 s->writeString(pfx,
"setdmpreg <reg> <val> - set raw DMP register <reg> to value <val>");
1922 s->writeString(pfx,
"getdmpreg <reg> - get value of raw DMP register <reg>");
1923 s->writeString(pfx,
"setdmpregs <reg> <num> <val1> ... <valn> - set array of raw DMP register values");
1924 s->writeString(pfx,
"getdmpregs <reg> <num> - get array of raw DMP register values");
1927 s->writeString(pfx,
"listmappings - list all available video mappings");
1928 s->writeString(pfx,
"setmapping <num> - select video mapping <num>, only possible while not streaming");
1929 s->writeString(pfx,
"setmapping2 <CAMmode> <CAMwidth> <CAMheight> <CAMfps> <Vendor> <Module> - set no-USB-out "
1930 "video mapping defined on the fly, while not streaming");
1931 s->writeString(pfx,
"reload - reload and reset the current module");
1933 if (showAll || itsCurrentMapping.ofmt == 0 || itsManualStreamon)
1935 s->writeString(pfx,
"streamon - start camera video streaming");
1936 s->writeString(pfx,
"streamoff - stop camera video streaming");
1939 s->writeString(pfx,
"ping - returns 'ALIVE'");
1940 s->writeString(pfx,
"serlog <string> - forward string to the serial port(s) specified by the serlog parameter");
1941 s->writeString(pfx,
"serout <string> - forward string to the serial port(s) specified by the serout parameter");
1946 s->writeString(pfx,
"caminfo - returns machine-readable info about camera parameters");
1947 s->writeString(pfx,
"cmdinfo [all] - returns machine-readable info about Engine commands");
1948 s->writeString(pfx,
"modcmdinfo - returns machine-readable info about Module commands");
1949 s->writeString(pfx,
"paraminfo [hot|mod|modhot] - returns machine-readable info about parameters");
1950 s->writeString(pfx,
"serinfo - returns machine-readable info about serial settings (serout serlog serstyle serprec serstamp)");
1951 s->writeString(pfx,
"fileget <filepath> - get a file from JeVois to the host. Use with caution!");
1952 s->writeString(pfx,
"fileput <filepath> - put a file from the host to JeVois. Use with caution!");
1955#ifdef JEVOIS_PLATFORM_A33
1956 s->writeString(pfx,
"usbsd - export the JEVOIS partition of the microSD card as a virtual USB drive");
1958 s->writeString(pfx,
"sync - commit any pending data write to microSD");
1959 s->writeString(pfx,
"date [date and time] - get or set the system date and time");
1961 s->writeString(pfx,
"!<string> - execute <string> as a Linux shell command. Use with caution!");
1962 s->writeString(pfx,
"shell <string> - execute <string> as a Linux shell command. Use with caution!");
1963 s->writeString(pfx,
"shellstart - execute all subsequent commands as Linux shell commands. Use with caution!");
1964 s->writeString(pfx,
"shellstop - stop executing all subsequent commands as Linux shell commands.");
1967 s->writeString(pfx,
"dnnget <key> - download and install a DNN from JeVois Model Converter");
1970#ifdef JEVOIS_PLATFORM
1971 s->writeString(pfx,
"restart - restart the JeVois smart camera");
1974#ifndef JEVOIS_PLATFORM_A33
1975 s->writeString(pfx,
"quit - quit this program");
1980void jevois::Engine::modCmdInfo(std::shared_ptr<UserInterface> s, std::string
const & pfx)
1984 std::stringstream css; itsModule->supportedCommands(css);
1985 for (std::string line; std::getline(css, line); ) s->writeString(pfx, line);
1999 if (str ==
"shellstop") { itsShellMode =
false;
return true; }
2003 for (std::string
const & r : rvec) s->writeString(pfx, r);
2019 switch (str.length())
2022 LDEBUG(
"Ignoring empty string");
return true;
2026 if (str[0] ==
'~') {
LDEBUG(
"Ignoring modem config command [~]");
return true; }
2030 if (str[0] ==
'#') { sendSerial(str,
true);
return true; }
2036 if (str[0] ==
'~') {
LDEBUG(
"Ignoring modem config command [" << str <<
']');
return true; }
2039 if (str[0] ==
'A' && str[1] ==
'T') {
LDEBUG(
"Ignoring AT command [" << str <<
']');
return true; }
2043 if (str[0] ==
'#') { sendSerial(str,
true);
return true; }
2046 std::string cmd, rem;
2049 cmd =
"shell"; rem = str.substr(1);
2054 size_t const idx = str.find(
' ');
2055 if (idx == str.npos) cmd = str;
2056 else { cmd = str.substr(0, idx);
if (idx < str.length()) rem = str.substr(idx+1); }
2063 s->writeString(pfx,
"GENERAL COMMANDS:");
2064 s->writeString(pfx,
"");
2065 cmdInfo(s,
false, pfx);
2066 s->writeString(pfx,
"");
2071 s->writeString(pfx,
"MODULE-SPECIFIC COMMANDS:");
2072 s->writeString(pfx,
"");
2074 s->writeString(pfx,
"");
2078 std::stringstream pss; constructHelpMessage(pss);
2079 for (std::string line; std::getline(pss, line); ) s->writeString(pfx, line);
2082 s->writeString(pfx,
"AVAILABLE CAMERA CONTROLS:");
2083 s->writeString(pfx,
"");
2085 foreachCamCtrl([
this,&pfx,&s](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2089 std::string hlp = camCtrlHelp(qc, doneids);
2090 if (hlp.empty() ==
false) s->writeString(pfx, hlp);
2097 if (cmd ==
"caminfo")
2100 foreachCamCtrl([
this,&pfx,&s](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2104 std::string hlp = camCtrlInfo(qc, doneids);
2105 if (hlp.empty() ==
false) s->writeString(pfx, hlp);
2112 if (cmd ==
"cmdinfo")
2114 bool showAll = (rem ==
"all") ?
true :
false;
2115 cmdInfo(s, showAll, pfx);
2120 if (cmd ==
"modcmdinfo")
2127 if (cmd ==
"paraminfo")
2129 std::map<std::string, std::string> categs;
2130 bool skipFrozen = (rem ==
"hot" || rem ==
"modhot") ?
true :
false;
2132 if (rem ==
"mod" || rem ==
"modhot")
2135 if (itsModule) itsModule->paramInfo(s, categs, skipFrozen, instanceName(), pfx);
2140 paramInfo(s, categs, skipFrozen,
"", pfx);
2147 if (cmd ==
"serinfo")
2149 std::string info = getParamStringUnique(
"serout") +
' ' + getParamStringUnique(
"serlog");
2151 info +=
' ' + mod->getParamStringUnique(
"serstyle") +
' ' + mod->getParamStringUnique(
"serprec") +
2152 ' ' + mod->getParamStringUnique(
"serstamp");
2153 else info +=
" - - -";
2155 s->writeString(pfx, info);
2166 std::stringstream css; itsModule->supportedCommands(css);
2167 s->writeString(pfx,
"MODULE-SPECIFIC COMMANDS:");
2168 s->writeString(pfx,
"");
2169 for (std::string line; std::getline(css, line); ) s->writeString(pfx, line);
2170 s->writeString(pfx,
"");
2173 s->writeString(pfx,
"MODULE PARAMETERS:");
2174 s->writeString(pfx,
"");
2177 std::unordered_map<std::string,
2178 std::unordered_map<std::string,
2179 std::vector<std::pair<std::string,
2182 itsModule->populateHelpMessage(
"", helplist);
2184 if (helplist.empty())
2185 s->writeString(pfx,
"None.");
2188 for (
auto const & c : helplist)
2191 s->writeString(pfx, c.first);
2194 for (
auto const & n : c.second)
2196 std::vector<std::string> tok =
jevois::split(n.first,
"[\\r\\n]+");
2198 for (
auto const & t : tok)
2203 auto const & v = n.second;
2206 if (v[0].second.empty())
2207 s->writeString(pfx, t);
2209 s->writeString(pfx, t +
" current=[" + v[0].second +
']');
2211 else if (v.size() > 1)
2213 std::string sss = t +
" current=";
2214 for (
auto const & pp : v)
2215 if (pp.second.empty() ==
false) sss +=
'[' + pp.first +
':' + pp.second +
"] ";
2216 s->writeString(pfx, sss);
2218 else s->writeString(pfx, t);
2224 s->writeString(pfx, t);
2227 s->writeString(pfx,
"");
2232 s->writeString(pfx,
"No module loaded.");
2244 if (itsModule) s->writeString(pfx,
"INFO: " + itsCurrentMapping.str());
2250 if (cmd ==
"setpar")
2252 size_t const remidx = rem.find(
' ');
2253 if (remidx != rem.npos)
2255 std::string
const desc = rem.substr(0, remidx);
2256 if (remidx < rem.length())
2258 std::string
const val = rem.substr(remidx+1);
2259 setParamString(desc, val);
2263 errmsg =
"Need to provide a parameter name and a parameter value in setpar";
2267 if (cmd ==
"getpar")
2269 auto vec = getParamString(rem);
2270 for (
auto const & p : vec) s->writeString(pfx, p.first +
' ' + p.second);
2275 if (cmd ==
"setcam")
2277 std::istringstream ss(rem); std::string ctrl;
int val; ss >> ctrl >> val;
2278 struct v4l2_control c = { }; c.id = camctrlid(ctrl); c.value = val;
2281 if (val == 0 && ctrl ==
"ispsensorpreset")
2283 c.value = 1; itsCamera->setControl(c);
2284 c.value = 0; itsCamera->setControl(c);
2286 else itsCamera->setControl(c);
2292 if (cmd ==
"getcam")
2294 struct v4l2_control c = { }; c.id = camctrlid(rem);
2295 itsCamera->getControl(c);
2296 s->writeString(pfx, rem +
' ' + std::to_string(c.value));
2301 if (cmd ==
"setcamreg")
2305 auto cam = std::dynamic_pointer_cast<jevois::Camera>(itsCamera);
2309 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2310 cam->writeRegister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2313 else errmsg =
"Not using a camera for video input";
2315 else errmsg =
"Access to camera registers is disabled, enable with: setpar camreg true";
2319 if (cmd ==
"getcamreg")
2323 auto cam = std::dynamic_pointer_cast<jevois::Camera>(itsCamera);
2326 unsigned int val = cam->readRegister(std::stoi(rem,
nullptr, 0));
2327 std::ostringstream os; os << std::hex << val;
2328 s->writeString(pfx, os.str());
2331 else errmsg =
"Not using a camera for video input";
2333 else errmsg =
"Access to camera registers is disabled, enable with: setpar camreg true";
2337 if (cmd ==
"setimureg")
2344 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2345 itsIMU->writeRegister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2348 else errmsg =
"No IMU driver loaded";
2350 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2354 if (cmd ==
"getimureg")
2360 unsigned int val = itsIMU->readRegister(std::stoi(rem,
nullptr, 0));
2361 std::ostringstream os; os << std::hex << val;
2362 s->writeString(pfx, os.str());
2365 else errmsg =
"No IMU driver loaded";
2367 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2371 if (cmd ==
"setimuregs")
2379 if (v.size() < 3) errmsg =
"Malformed arguments, need at least 3";
2382 unsigned short reg = std::stoi(v[0],
nullptr, 0);
2383 size_t num = std::stoi(v[1],
nullptr, 0);
2384 if (num > 32) errmsg =
"Maximum transfer size is 32 bytes";
2385 else if (num != v.size() - 2) errmsg =
"Incorrect number of data bytes, should pass " + v[1] +
" values.";
2388 unsigned char data[32];
2389 for (
size_t i = 2; i < v.size(); ++i) data[i-2] = std::stoi(v[i],
nullptr, 0) & 0xff;
2391 itsIMU->writeRegisterArray(reg, data, num);
2396 else errmsg =
"No IMU driver loaded";
2398 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2402 if (cmd ==
"getimuregs")
2408 std::istringstream ss(rem); std::string reg, num; ss >> reg >> num;
2409 int n = std::stoi(num,
nullptr, 0);
2411 if (n > 32) errmsg =
"Maximum transfer size is 32 bytes";
2414 unsigned char data[32];
2415 itsIMU->readRegisterArray(std::stoi(reg,
nullptr, 0), data, n);
2417 std::ostringstream os; os << std::hex;
2418 for (
int i = 0; i < n; ++i) os << (
unsigned int)(data[i]) <<
' ';
2419 s->writeString(pfx, os.str());
2423 else errmsg =
"No IMU driver loaded";
2425 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2429 if (cmd ==
"setdmpreg")
2436 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2437 itsIMU->writeDMPregister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2440 else errmsg =
"No IMU driver loaded";
2442 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2446 if (cmd ==
"getdmpreg")
2452 unsigned int val = itsIMU->readDMPregister(std::stoi(rem,
nullptr, 0));
2453 std::ostringstream os; os << std::hex << val;
2454 s->writeString(pfx, os.str());
2457 else errmsg =
"No IMU driver loaded";
2459 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2463 if (cmd ==
"setdmpregs")
2471 if (v.size() < 3) errmsg =
"Malformed arguments, need at least 3";
2474 unsigned short reg = std::stoi(v[0],
nullptr, 0);
2475 size_t num = std::stoi(v[1],
nullptr, 0);
2476 if (num > 32) errmsg =
"Maximum transfer size is 32 bytes";
2477 else if (num != v.size() - 2) errmsg =
"Incorrect number of data bytes, should pass " + v[1] +
" values.";
2480 unsigned char data[32];
2481 for (
size_t i = 2; i < v.size(); ++i) data[i-2] = std::stoi(v[i],
nullptr, 0) & 0xff;
2483 itsIMU->writeDMPregisterArray(reg, data, num);
2488 else errmsg =
"No IMU driver loaded";
2490 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2494 if (cmd ==
"getdmpregs")
2500 std::istringstream ss(rem); std::string reg, num; ss >> reg >> num;
2501 int n = std::stoi(num,
nullptr, 0);
2503 if (n > 32) errmsg =
"Maximum transfer size is 32 bytes";
2506 unsigned char data[32];
2507 itsIMU->readDMPregisterArray(std::stoi(reg,
nullptr, 0), data, n);
2509 std::ostringstream os; os << std::hex;
2510 for (
int i = 0; i < n; ++i) os << (
unsigned int)(data[i]) <<
' ';
2511 s->writeString(pfx, os.str());
2515 else errmsg =
"No IMU driver loaded";
2517 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2521 if (cmd ==
"listmappings")
2523 s->writeString(pfx,
"AVAILABLE VIDEO MAPPINGS:");
2524 s->writeString(pfx,
"");
2525 for (
size_t idx = 0; idx < itsMappings.size(); ++idx)
2527 std::string idxstr = std::to_string(idx);
2528 if (idxstr.length() < 5) idxstr = std::string(5 - idxstr.length(),
' ') + idxstr;
2529 s->writeString(pfx, idxstr +
" - " + itsMappings[idx].str());
2535 if (cmd ==
"setmapping")
2537 size_t const idx = std::stoi(rem);
2539 if (itsStreaming.load() && itsCurrentMapping.ofmt)
2540 errmsg =
"Cannot set mapping while streaming: Stop your webcam program on the host computer first.";
2541 else if (idx >= itsMappings.size())
2542 errmsg =
"Requested mapping index " + std::to_string(idx) +
" out of range [0 .. " +
2543 std::to_string(itsMappings.size()-1) +
']';
2548 setFormatInternal(idx);
2551 catch (std::exception
const & e) { errmsg =
"Error parsing or setting mapping [" + rem +
"]: " + e.what(); }
2552 catch (...) { errmsg =
"Error parsing or setting mapping [" + rem +
']'; }
2557 if (cmd ==
"setmapping2")
2559 if (itsStreaming.load() && itsCurrentMapping.ofmt)
2560 errmsg =
"Cannot set mapping while streaming: Stop your webcam program on the host computer first.";
2566 setFormatInternal(m);
2569 catch (std::exception
const & e) { errmsg =
"Error parsing or setting mapping [" + rem +
"]: " + e.what(); }
2570 catch (...) { errmsg =
"Error parsing or setting mapping [" + rem +
']'; }
2575 if (cmd ==
"reload")
2577 setFormatInternal(itsCurrentMapping,
true);
2582 if (itsCurrentMapping.ofmt == 0 || itsCurrentMapping.ofmt ==
JEVOISPRO_FMT_GUI || itsManualStreamon)
2584 if (cmd ==
"streamon")
2587 itsCamera->streamOn();
2588 itsGadget->streamOn();
2589 itsStreaming.store(
true);
2593 if (cmd ==
"streamoff")
2596 itsGadget->abortStream();
2597 itsCamera->abortStream();
2599 itsStreaming.store(
false);
2601 itsGadget->streamOff();
2602 itsCamera->streamOff();
2610 s->writeString(pfx,
"ALIVE");
2615 if (cmd ==
"serlog")
2617 sendSerial(rem,
true);
2622 if (cmd ==
"serout")
2624 sendSerial(rem,
false);
2629#ifdef JEVOIS_PLATFORM_A33
2632 if (itsStreaming.load())
2634 errmsg =
"Cannot export microSD over USB while streaming: ";
2635 if (itsCurrentMapping.ofmt) errmsg +=
"Stop your webcam program on the host computer first.";
2636 else errmsg +=
"Issue a 'streamoff' command first.";
2640 startMassStorageMode();
2649 if (std::system(
"sync")) errmsg =
"Disk sync failed";
2657 s->writeString(pfx,
"date now " + dat.substr(0, dat.size()-1));
2662 if (cmd ==
"runscript")
2664 std::string
const fname = itsModule ? itsModule->absolutePath(rem).string() : rem;
2666 try { runScriptFromFile(fname, s,
true);
return true; }
2667 catch (...) { errmsg =
"Script " + fname +
" execution failed"; }
2675 for (std::string
const & r : rvec) s->writeString(pfx, r);
2680 if (cmd ==
"shellstart")
2682 itsShellMode =
true;
2689 if (cmd ==
"dnnget")
2691 if (rem.length() != 4 || std::regex_match(rem, std::regex(
"^[a-zA-Z0-9]+$")) ==
false)
2692 errmsg =
"Key must be a 4-character alphanumeric string, as emailed to you by the model converter.";
2696 s->writeString(pfx,
"Downloading custom DNN model " + rem +
" ...");
2697 std::string
const zip = rem +
".zip";
2701 for (std::string
const & r : rvec) s->writeString(pfx, r);
2705 if (ifs.is_open() ==
false)
2706 errmsg =
"Failed to download. Check network connectivity and available disk space.";
2710 s->writeString(pfx,
"Unpacking custom DNN model " + rem +
" ...");
2713 rvec =
jevois::split(ret,
"\n");
for (std::string
const & r : rvec) s->writeString(pfx, r);
2716 rvec =
jevois::split(ret,
"\n");
for (std::string
const & r : rvec) s->writeString(pfx, r);
2718 s->writeString(pfx,
"Reload your model zoo for changes to take effect.");
2727 if (cmd ==
"fileget")
2729 std::shared_ptr<jevois::Serial> ser = std::dynamic_pointer_cast<jevois::Serial>(s);
2731 errmsg =
"File transfer only supported over USB or Hard serial ports";
2734 std::string
const abspath = itsModule ? itsModule->absolutePath(rem).string() : rem;
2735 ser->fileGet(abspath);
2741 if (cmd ==
"fileput")
2743 std::shared_ptr<jevois::Serial> ser = std::dynamic_pointer_cast<jevois::Serial>(s);
2745 errmsg =
"File transfer only supported over USB or Hard serial ports";
2748 std::string
const abspath = itsModule ? itsModule->absolutePath(rem).string() : rem;
2749 ser->filePut(abspath);
2750 if (std::system(
"sync")) { }
2755#ifdef JEVOIS_PLATFORM
2757 if (cmd ==
"restart")
2759 s->writeString(pfx,
"Restart command received - bye-bye!");
2761 if (itsStreaming.load())
2762 s->writeString(pfx,
"ERR Video streaming is on - you should quit your video viewer before rebooting");
2764 if (std::system(
"sync")) s->writeString(pfx,
"ERR Disk sync failed -- IGNORED");
2766#ifdef JEVOIS_PLATFORM_A33
2770 if (std::system(
"sync")) s->writeString(pfx,
"ERR Disk sync failed -- IGNORED");
2780#ifndef JEVOIS_PLATFORM_A33
2784 s->writeString(pfx,
"Quit command received - bye-bye!");
2795 if (errmsg.size())
throw std::runtime_error(
"Command error [" + str +
"]: " + errmsg);
2806 std::ifstream ifs(filename);
2807 if (!ifs) {
if (throw_no_file)
LFATAL(
"Could not open file " << filename);
else return; }
2813 if (itsSerials.empty())
LFATAL(
"Need at least one active serial to run script");
2815 switch (serlog::get())
2817 case jevois::engine::SerPort::Hard:
2821 case jevois::engine::SerPort::USB:
2833 if (!ser) ser = itsSerials.front();
2838 for (std::string line; std::getline(ifs, line); )
2846 if (line.length() == 0 || line[0] ==
'#')
continue;
2851 bool parsed =
false;
2852 try { parsed = parseCommand(line, ser); }
2853 catch (std::exception
const & e)
2854 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": " + e.what()); }
2856 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": Bogus command ["+line+
"] ignored"); }
2858 if (parsed ==
false)
2862 try { itsModule->parseSerial(line, ser); }
2863 catch (std::exception
const & me)
2864 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": " + me.what()); }
2866 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum)+
": Bogus command ["+line+
"] ignored"); }
2868 else ser->writeString(
"ERR Unsupported command [" + line +
"] and no module");
2880 ImGui::Columns(2,
"camctrl");
2882 foreachCamCtrl([
this](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2884 try { camCtrlGUI(qc, doneids); }
catch (...) { }
2891void jevois::Engine::camCtrlGUI(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2894 itsCamera->queryControl(qc);
2895 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
2898 if (doneids.find(qc.id) != doneids.end())
return;
else doneids.insert(qc.id);
2901 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
2902 itsCamera->getControl(ctrl);
2905 ImGui::AlignTextToFramePadding();
2906 ImGui::TextUnformatted(
reinterpret_cast<char const *
>(qc.name));
2907 ImGui::NextColumn();
2910 if (qc.flags & V4L2_CTRL_FLAG_DISABLED)
2912 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
2913 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
2917 static char wname[16]; snprintf(wname, 16,
"##c%d", ctrl.id);
2922 case V4L2_CTRL_TYPE_INTEGER:
2923 case V4L2_CTRL_TYPE_INTEGER_MENU:
2926 long range = long(qc.maximum) - long(qc.minimum);
2927 if (range > 1 && range < 5000)
2929 if (ImGui::SliderInt(wname, &ctrl.value, qc.minimum, qc.maximum)) itsCamera->setControl(ctrl);
2934 if (ImGui::InputInt(wname, &ctrl.value, qc.step, qc.step * 2)) itsCamera->setControl(ctrl);
2951 case V4L2_CTRL_TYPE_BOOLEAN:
2953 bool checked = (ctrl.value != 0);
2954 if (ImGui::Checkbox(wname, &checked)) { ctrl.value = checked ? 1 : 0; itsCamera->setControl(ctrl); }
2959 case V4L2_CTRL_TYPE_BUTTON:
2960 static char bname[16]; snprintf(bname, 16,
"Go##%d", ctrl.id);
2961 if (ImGui::Button(bname)) { ctrl.value = 1; itsCamera->setControl(ctrl); }
2964 case V4L2_CTRL_TYPE_BITMASK:
2968 case V4L2_CTRL_TYPE_MENU:
2970 struct v4l2_querymenu querymenu = { };
2971 querymenu.id = qc.id;
2972 char * items[qc.maximum - qc.minimum + 1];
2974 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
2976 try { itsCamera->queryMenu(querymenu); }
catch (...) { strncpy((
char *)querymenu.name,
"fixme", 32); }
2977 items[querymenu.index] =
new char[32];
2978 strncpy(items[querymenu.index], (
char const *)querymenu.name, 32);
2981 int idx = ctrl.value - qc.minimum;
2982 if (ImGui::Combo(wname, &idx, items, qc.maximum - qc.minimum + 1))
2983 { ctrl.value = qc.minimum + idx; itsCamera->setControl(ctrl); }
2985 for (
int i = qc.minimum; i <= qc.maximum; ++i)
delete [] items[i];
2995 static char rname[16]; snprintf(rname, 16,
"Reset##%d", ctrl.id);
2997 if (ImGui::Button(rname)) { ctrl.value = qc.default_value; itsCamera->setControl(ctrl); }
3001 if (qc.flags & V4L2_CTRL_FLAG_DISABLED)
3003 ImGui::PopItemFlag();
3004 ImGui::PopStyleVar();
3008 ImGui::NextColumn();
3018 std::lock_guard<std::mutex> _(itsPyRegMtx);
3019 auto itr = itsPythonRegistry.find(pyinst);
3020 if (itr != itsPythonRegistry.end())
LFATAL(
"Trying to register twice -- ABORT");
3021 itsPythonRegistry.insert(std::make_pair(pyinst, comp));
3028 std::lock_guard<std::mutex> _(itsPyRegMtx);
3029 auto itr = itsPythonRegistry.begin(), stop = itsPythonRegistry.end();
3030 while (itr != stop)
if (itr->second == comp) itr = itsPythonRegistry.erase(itr);
else ++itr;
3036 LDEBUG(std::hex << pyinst);
3037 std::lock_guard<std::mutex> _(itsPyRegMtx);
3038 auto itr = itsPythonRegistry.find(pyinst);
3039 if (itr == itsPythonRegistry.end())
LFATAL(
"Python instance not registered -- ABORT");
3048 if (strncmp(name,
"jevois", 6) == 0) cv::parallel::setParallelForBackend(itsOpenCVparallelAPI);
3049 else cv::parallel::setParallelForBackend(name);
#define JEVOIS_USBSD_FILE
Disk partition or file that we can export over USB using Engine command 'usbsd'.
#define JEVOIS_CUSTOM_DNN_URL
URL where custom converted DNN models can be downloaded:
#define JEVOIS_MODULE_PARAMS_FILENAME
Relative name of optinal default parameters to load for each Module.
#define JEVOIS_VERSION_STRING
Software version, as string.
#define JEVOIS_USBSD_SYS
Sysfs location to change the exported partition or file over USB using Engine command 'usbsd".
#define JEVOIS_CUSTOM_DNN_PATH
Directory where custom DNN models are stored:
#define JEVOIS_VERSION_MINOR
#define JEVOIS_CONFIG_PATH
Base path for config files.
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
#define JEVOIS_VERSION_MAJOR
Variables set by CMake.
#define JEVOISPRO_DEMO_DATA_FILE
Location of the jevois-pro demo data definition file.
#define JEVOIS_ENGINE_INIT_SCRIPT
Location of the engine init script file.
#define JEVOIS_MODULE_SCRIPT_FILENAME
Relative name of an Engine script to load for each Module.
#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE
#define V4L2_CTRL_CLASS_DETECT
#define JEVOISPRO_FMT_GUI
JeVois-Pro zero-copy display of camera input frame (to be used as output mode in VideoMapping)
Helper class for camera calibration, which allows some modules to compute 3D locations of objects.
void save(std::string const &fname) const
Save to file.
jevois::CameraLens lens
Camera lens.
int h
Image width and height (camera resolution)
jevois::CameraSensor sensor
Camera sensor.
void load(std::string const &fname)
Load from file.
JeVois camera driver class - grabs frames from a Video4Linux camera sensor.
A component of a model hierarchy.
std::string const & instanceName() const
The instance name of this component.
Class to open shared object (.so) files and load functions contained in them.
Component * getPythonComponent(void *pyinst) const
Get the component registered with a given python instance.
void requestSetFormat(int idx)
Use this to request a format change from within process()
void streamOn()
Start streaming on video from camera, processing, and USB.
void drawCameraGUI()
Draw all camera controls into our GUI.
void nextDemo()
When in demo mode, switch to next demo.
void reboot()
Request a reboot.
void preInit() override
Override of Manager::preInit()
void onParamChange(engine::serialdev const ¶m, std::string const &newval) override
Parameter callback.
void saveCameraCalibration(CameraCalibration const &calib, std::string const &stem="calibration")
Helper to save an OpenCV camera matrix and distortion coeffs for the current running module.
size_t numVideoMappings() const
Return the number of video mappings.
std::shared_ptr< Module > module() const
Get a pointer to our current module (may be null)
void abortDemo()
When in demo mode, abort demo mode.
size_t getDefaultVideoMappingIdx() const
Allow access to the default video mapping index.
void setFormat(size_t idx)
Callback for when the user selects a new output video format.
void reportInfo(std::string const &info)
void unRegisterPythonComponent(Component *comp)
Unregister a component as linked to some python code, used by dynamic params created in python.
void setOpenCVthreading(char const *name="jevois")
Set OpenCV parallel threading framework.
void sendSerial(std::string const &str, bool islog=false)
Send a string to all serial ports.
void streamOff()
Stop streaming on video from camera, processing, and USB.
void runScriptFromFile(std::string const &filename, std::shared_ptr< UserInterface > ser, bool throw_no_file)
Run a script from file.
void quit()
Terminate the program.
bool parseCommand(std::string const &str, std::shared_ptr< UserInterface > s, std::string const &pfx="")
Parse a user command received over serial port.
int mainLoop()
Main loop: grab, process, send over USB. Should be called by main application thread.
VideoMapping const & getVideoMapping(size_t idx) const
Allow access to our video mappings which are parsed from file at construction.
size_t getVideoMappingIdx(unsigned int iformat, unsigned int iframe, unsigned int interval) const
Get the video mapping index for a given UVC iformat, iframe and interval.
VideoMapping const & getCurrentVideoMapping() const
Get the current video mapping.
void registerPythonComponent(Component *comp, void *pyinst)
Register a component as linked to some python code, used by dynamic params created in python.
CameraCalibration loadCameraCalibration(std::string const &stem="calibration", bool do_throw=false)
Helper to load an OpenCV camera matrix and distortion coeffs for the current running module.
VideoMapping const & findVideoMapping(unsigned int oformat, unsigned int owidth, unsigned int oheight, float oframespersec) const
Find the VideoMapping that has the given output specs, or throw if not found.
void reloadVideoMappings()
Re-load video mappings from videomappings.cfg.
void postInit() override
Override of Manager::postInit()
std::shared_ptr< Camera > camera() const
Get a pointer to our Camera (may be null, especially if not using a camera but, eg,...
VideoMapping const & getDefaultVideoMapping() const
Allow access to the default video mapping.
void clearErrors()
Clear all errors currently displayed in the JeVois-Pro GUI.
void foreachVideoMapping(std::function< void(VideoMapping const &m)> &&func)
Run a function on every video mapping.
void reportError(std::string const &err)
JeVois gadget driver - exposes a uvcvideo interface to host computer connected over USB.
IMU with I2C interface shared with camera sensor, such as ICM20948 on JeVois-A33 AR0135 camera sensor...
IMU with SPI interface, such as the ICM20948 IMU on the JeVois-Pro IMX290 camera sensor board.
Manager of a hierarchy of Component objects.
void postInit() override
Checks for the –help flag.
void preInit() override
Calls parseCommandLine()
Video output to a movie file, using OpenCV video encoding.
Exception-safe wrapper around a raw image to be sent over USB.
Wrapper module to allow users to develop new modules written in Python.
Base class for a module that supports standardized serial messages.
void sendSerialMarkStop()
Send a message MARK STOP to indicate the end of processing.
void sendSerialMarkStart()
Send a message MARK START to indicate the beginning of processing.
Video output to local screen.
Video output to local screen with basic GUI.
Video output to local screen.
No-op VideoOutput derivative for when there is no video output.
bool sensorHasIMU(CameraSensor s)
Check whether sensor has an IMU (inertial measurement unit)
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level.
#define JEVOIS_TIMED_LOCK(mtx)
Helper macro to create a timed_lock_guard object.
void logSetEngine(Engine *e)
Set an Engine so that all log messages will be forwarded to its serial ports.
std::string getSysInfoCPU()
Get CPU info: frequency, thermal, load.
std::string warnAndIgnoreException(std::string const &prefix="")
Convenience function to catch an exception, issue some LERROR (depending on type),...
#define JEVOIS_TRACE(level)
Trace object.
std::string getSysInfoMem()
Get memory info.
std::string getSysInfoVersion()
Get O.S. version info.
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
void setEngine(jevois::Engine *e)
Initialize Python, numpy, and allow python modules to send serial outputs through the JeVois Engine.
std::string strip(std::string const &str)
Strip white space (including CR, LF, tabs, etc) from the end of a string.
std::string getFileString(char const *fname, int skip=0)
Read one line from a file and return it as a string.
std::string system(std::string const &cmd, bool errtoo=true)
Execute a command and grab stdout output to a string.
bool stringStartsWith(std::string const &str, std::string const &prefix)
Return true if str starts with prefix (including if both strings are equal)
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
std::vector< std::string > split(std::string const &input, std::string const ®ex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
std::string to_string(T const &val)
Convert from type to string.
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async_little(Function &&f, Args &&... args)
Async execution using a thread pool.
Main namespace for all JeVois classes and functions.
void drawErrorImage(std::string const &errmsg, RawImage &videoerrimg)
Display an error message into a RawImage.
Simple struct to hold video mapping definitions for the processing Engine.
std::string modulename
Name of the Module that will process this mapping.
std::string ostr() const
Convenience function to print out FCC WxH @ fps, for the output (UVC) format.
std::string str() const
Convenience function to print out the whole mapping in a human-friendly way.
std::string cstrall() const
Convenience function to print out FCC WxH @ fps plus possibly second stream, for the input (camera) f...
bool ispython
True if the module is written in Python; affects behavior of sopath() only.
float ofps
output frame rate in frames/sec
bool isSameAs(VideoMapping const &other) const
Equality operator for specs and also vendor or module name.
unsigned int uvcformat
USB-UVC format number (1-based)
static float uvcToFps(unsigned int interval)
Convert from USB/UVC interval to fps.
unsigned int uvcframe
USB UVC frame number (1-based)
std::string sopath(bool delete_old_versions=false) const
Return the full absolute path and file name of the module's .so or .py file.
bool match(unsigned int oformat, unsigned int owidth, unsigned int oheight, float oframespersec) const
Return true if this VideoMapping's output format is a match to the given output parameters.