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);
1414 if (itsGUIhelper) itsGUIhelper->clearErrors();
1420void jevois::Engine::reportErrorInternal(std::string
const & err)
1426 if (itsGUIhelper->frameStarted() ==
false) {
unsigned short w,
h; itsGUIhelper->startFrame(w,
h); }
1428 else itsGUIhelper->reportError(err);
1429 itsGUIhelper->endFrame();
1436 if (itsCurrentMapping.ofmt != 0 && itsCurrentMapping.ofmt !=
JEVOISPRO_FMT_GUI && itsVideoErrors.load())
1441 if (itsVideoErrorImage.valid() ==
false) itsGadget->get(itsVideoErrorImage);
1452 if (itsVideoErrorImage.valid()) itsGadget->send(itsVideoErrorImage);
1457 itsVideoErrorImage.invalidate();
1469{
return itsModule; }
1472std::shared_ptr<jevois::IMU> jevois::Engine::imu()
const
1477{
return std::dynamic_pointer_cast<jevois::Camera>(itsCamera); }
1486 if (itsCurrentMapping.c2fmt) { w = itsCurrentMapping.c2w;
h = itsCurrentMapping.c2h; }
1487 else { w = itsCurrentMapping.cw;
h = itsCurrentMapping.ch; }
1490 '-' + camerasens::strget() +
'-' + std::to_string(w) +
'x' + std::to_string(
h) +
1491 '-' + cameralens::strget() +
".yaml";
1498 LINFO(
"Camera calibration loaded from [" << fname <<
']');
1503 LFATAL(
"Failed to read camera parameters from file [" << fname <<
']');
1506 reportError(
"Failed to read camera parameters from file [" + fname +
"] -- IGNORED");
1509 calib.
sensor = camerasens::get();
1510 calib.
lens = cameralens::get();
1511 calib.
w = w; calib.
h =
h;
1528 LINFO(
"Camera calibration saved to [" << fname <<
']');
1533{
return itsCurrentMapping; }
1537{
return itsMappings.size(); }
1542 if (idx >= itsMappings.size())
1543 LFATAL(
"Index " << idx <<
" out of range [0 .. " << itsMappings.size()-1 <<
']');
1545 return itsMappings[idx];
1552 if (iformat == 0 || iframe == 0)
return itsDefaultMappingIdx;
1565 LFATAL(
"No video mapping for iformat=" << iformat <<
", iframe=" << iframe <<
", interval=" << interval);
1575 LFATAL(
"No video mapping for iformat=" << iformat <<
", iframe=" << iframe <<
", interval=" << interval);
1581{
return itsMappings[itsDefaultMappingIdx]; }
1585{
return itsDefaultMappingIdx; }
1597 float oframespersec)
const
1600 if (m.
match(oformat, owidth, oheight, oframespersec))
return m;
1603 owidth <<
'x' << oheight <<
" @ " << oframespersec <<
" fps");
1607void jevois::Engine::foreachCamCtrl(std::function<
void(
struct v4l2_queryctrl & qc, std::set<int> & doneids)> && func)
1609 struct v4l2_queryctrl qc = { }; std::set<int> doneids;
1615 qc.id = cls | 0x900;
unsigned int old_id;
1618 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL; old_id = qc.id;
bool failed =
false;
1619 try { func(qc, doneids); }
catch (...) { failed =
true; }
1623 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1624 if (qc.id == old_id) { ++qc.id;
if (qc.id > 100 + (cls | 0x900 | V4L2_CTRL_FLAG_NEXT_CTRL))
break; }
1625 else if (failed)
break;
1631std::string jevois::Engine::camctrlname(
unsigned int id,
char const * longname)
const
1633 for (
size_t i = 0; i <
sizeof camcontrols /
sizeof camcontrols[0]; ++i)
1634 if (camcontrols[i].
id ==
id)
return camcontrols[i].shortname;
1637 return abbreviate(longname);
1641unsigned int jevois::Engine::camctrlid(std::string
const & shortname)
1643 for (
size_t i = 0; i <
sizeof camcontrols /
sizeof camcontrols[0]; ++i)
1644 if (shortname.compare(camcontrols[i].shortname) == 0)
return camcontrols[i].id;
1647 struct v4l2_queryctrl qc = { };
1653 qc.id = cls | 0x900;
1656 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
unsigned int old_id = qc.id;
bool failed =
false;
1659 itsCamera->queryControl(qc);
1660 if (abbreviate(
reinterpret_cast<char const *
>(qc.name)) == shortname)
return qc.id;
1662 catch (...) { failed =
true; }
1667 qc.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1668 if (qc.id == old_id) { ++qc.id;
if (qc.id > 100 + (cls | 0x900 | V4L2_CTRL_FLAG_NEXT_CTRL))
break; }
1669 else if (failed)
break;
1673 LFATAL(
"Could not find control [" << shortname <<
"] in the camera");
1677std::string jevois::Engine::camCtrlHelp(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
1680 itsCamera->queryControl(qc);
1681 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
1684 if (doneids.find(qc.id) != doneids.end())
return std::string();
else doneids.insert(qc.id);
1687 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
1688 itsCamera->getControl(ctrl);
1691 std::ostringstream ss;
1692 ss <<
"- " << camctrlname(qc.id,
reinterpret_cast<char const *
>(qc.name));
1696 case V4L2_CTRL_TYPE_INTEGER:
1697 ss <<
" [int] min=" << qc.minimum <<
" max=" << qc.maximum <<
" step=" << qc.step
1698 <<
" def=" << qc.default_value <<
" curr=" << ctrl.value;
1710 case V4L2_CTRL_TYPE_BOOLEAN:
1711 ss <<
" [bool] default=" << qc.default_value <<
" curr=" << ctrl.value;
1720 case V4L2_CTRL_TYPE_BUTTON:
1724 case V4L2_CTRL_TYPE_BITMASK:
1725 ss <<
" [bitmask] max=" << qc.maximum <<
" def=" << qc.default_value <<
" curr=" << ctrl.value;
1728 case V4L2_CTRL_TYPE_MENU:
1730 struct v4l2_querymenu querymenu = { };
1731 querymenu.id = qc.id;
1732 ss <<
" [menu] values ";
1733 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
1735 try { itsCamera->queryMenu(querymenu); }
catch (...) { strcpy((
char *)(querymenu.name),
"fixme"); }
1736 ss << querymenu.index <<
':' << querymenu.name <<
' ';
1738 ss <<
"curr=" << ctrl.value;
1743 ss <<
"[unknown type]";
1746 if (qc.flags & V4L2_CTRL_FLAG_DISABLED) ss <<
" [DISABLED]";
1752std::string jevois::Engine::camCtrlInfo(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
1755 itsCamera->queryControl(qc);
1756 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
1759 if (doneids.find(qc.id) != doneids.end())
return std::string();
else doneids.insert(qc.id);
1762 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
1763 itsCamera->getControl(ctrl);
1766 std::ostringstream ss;
1767 ss << camctrlname(qc.id,
reinterpret_cast<char const *
>(qc.name));
1769 if (qc.flags & V4L2_CTRL_FLAG_DISABLED) ss <<
" D ";
1773 case V4L2_CTRL_TYPE_INTEGER:
1774 ss <<
" I " << qc.minimum <<
' ' << qc.maximum <<
' ' << qc.step
1775 <<
' ' << qc.default_value <<
' ' << ctrl.value;
1786 case V4L2_CTRL_TYPE_BOOLEAN:
1787 ss <<
" B " << qc.default_value <<
' ' << ctrl.value;
1795 case V4L2_CTRL_TYPE_BUTTON:
1799 case V4L2_CTRL_TYPE_BITMASK:
1800 ss <<
" K " << qc.maximum <<
' ' << qc.default_value <<
' ' << ctrl.value;
1803 case V4L2_CTRL_TYPE_MENU:
1805 struct v4l2_querymenu querymenu = { };
1806 querymenu.id = qc.id;
1807 ss <<
" M " << qc.default_value <<
' ' << ctrl.value;
1808 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
1810 try { itsCamera->queryMenu(querymenu); }
catch (...) { strcpy((
char *)(querymenu.name),
"fixme"); }
1811 ss <<
' ' << querymenu.index <<
':' << querymenu.name <<
' ';
1823#ifdef JEVOIS_PLATFORM_A33
1825void jevois::Engine::startMassStorageMode()
1829 if (itsMassStorageMode.load()) {
LERROR(
"Already in mass-storage mode -- IGNORED");
return; }
1832 if (itsModule) { removeComponent(itsModule); itsModule.reset(); }
1833 if (itsLoader) itsLoader.reset();
1836 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1837 if (std::system(
"mount -o remount,ro /jevois"))
LERROR(
"Failed to remount /jevois read-only -- IGNORED");
1844 LINFO(
"Exported JEVOIS partition of microSD to host computer as virtual flash drive.");
1845 itsMassStorageMode.store(
true);
1849void jevois::Engine::stopMassStorageMode()
1852 LINFO(
"JeVois virtual USB drive ejected by host -- REBOOTING");
1860 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1861 if (std::system(
"sync"))
LERROR(
"Disk sync failed -- IGNORED");
1862#ifdef JEVOIS_PLATFORM_A33
1863 itsCheckingMassStorage.store(
false);
1865 itsRunning.store(
false);
1867#ifdef JEVOIS_PLATFORM_A33
1869 if ( ! std::ofstream(
"/proc/sys/kernel/sysrq").put(
'1'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1870 if ( ! std::ofstream(
"/proc/sysrq-trigger").put(
's'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1871 if ( ! std::ofstream(
"/proc/sysrq-trigger").put(
'b'))
LERROR(
"Cannot trigger hard reset -- please unplug me!");
1882 itsGadget->abortStream();
1883 itsCamera->abortStream();
1884 itsStreaming.store(
false);
1885 itsGadget->streamOff();
1886 itsCamera->streamOff();
1887 itsRunning.store(
false);
1893void jevois::Engine::cmdInfo(std::shared_ptr<UserInterface> s,
bool showAll, std::string
const & pfx)
1895 s->writeString(pfx,
"help - print this help message");
1896 s->writeString(pfx,
"help2 - print compact help message about current vision module only");
1897 s->writeString(pfx,
"info - show system information including CPU speed, load and temperature");
1898 s->writeString(pfx,
"setpar <name> <value> - set a parameter value");
1899 s->writeString(pfx,
"getpar <name> - get a parameter value(s)");
1900 s->writeString(pfx,
"runscript <filename> - run script commands in specified file");
1901 s->writeString(pfx,
"setcam <ctrl> <val> - set camera control <ctrl> to value <val>");
1902 s->writeString(pfx,
"getcam <ctrl> - get value of camera control <ctrl>");
1904 if (showAll || camreg::get())
1906 s->writeString(pfx,
"setcamreg <reg> <val> - set raw camera register <reg> to value <val>");
1907 s->writeString(pfx,
"getcamreg <reg> - get value of raw camera register <reg>");
1908 s->writeString(pfx,
"setimureg <reg> <val> - set raw IMU register <reg> to value <val>");
1909 s->writeString(pfx,
"getimureg <reg> - get value of raw IMU register <reg>");
1910 s->writeString(pfx,
"setimuregs <reg> <num> <val1> ... <valn> - set array of raw IMU register values");
1911 s->writeString(pfx,
"getimuregs <reg> <num> - get array of raw IMU register values");
1912 s->writeString(pfx,
"setdmpreg <reg> <val> - set raw DMP register <reg> to value <val>");
1913 s->writeString(pfx,
"getdmpreg <reg> - get value of raw DMP register <reg>");
1914 s->writeString(pfx,
"setdmpregs <reg> <num> <val1> ... <valn> - set array of raw DMP register values");
1915 s->writeString(pfx,
"getdmpregs <reg> <num> - get array of raw DMP register values");
1918 s->writeString(pfx,
"listmappings - list all available video mappings");
1919 s->writeString(pfx,
"setmapping <num> - select video mapping <num>, only possible while not streaming");
1920 s->writeString(pfx,
"setmapping2 <CAMmode> <CAMwidth> <CAMheight> <CAMfps> <Vendor> <Module> - set no-USB-out "
1921 "video mapping defined on the fly, while not streaming");
1922 s->writeString(pfx,
"reload - reload and reset the current module");
1924 if (showAll || itsCurrentMapping.ofmt == 0 || itsManualStreamon)
1926 s->writeString(pfx,
"streamon - start camera video streaming");
1927 s->writeString(pfx,
"streamoff - stop camera video streaming");
1930 s->writeString(pfx,
"ping - returns 'ALIVE'");
1931 s->writeString(pfx,
"serlog <string> - forward string to the serial port(s) specified by the serlog parameter");
1932 s->writeString(pfx,
"serout <string> - forward string to the serial port(s) specified by the serout parameter");
1937 s->writeString(pfx,
"caminfo - returns machine-readable info about camera parameters");
1938 s->writeString(pfx,
"cmdinfo [all] - returns machine-readable info about Engine commands");
1939 s->writeString(pfx,
"modcmdinfo - returns machine-readable info about Module commands");
1940 s->writeString(pfx,
"paraminfo [hot|mod|modhot] - returns machine-readable info about parameters");
1941 s->writeString(pfx,
"serinfo - returns machine-readable info about serial settings (serout serlog serstyle serprec serstamp)");
1942 s->writeString(pfx,
"fileget <filepath> - get a file from JeVois to the host. Use with caution!");
1943 s->writeString(pfx,
"fileput <filepath> - put a file from the host to JeVois. Use with caution!");
1946#ifdef JEVOIS_PLATFORM_A33
1947 s->writeString(pfx,
"usbsd - export the JEVOIS partition of the microSD card as a virtual USB drive");
1949 s->writeString(pfx,
"sync - commit any pending data write to microSD");
1950 s->writeString(pfx,
"date [date and time] - get or set the system date and time");
1952 s->writeString(pfx,
"!<string> - execute <string> as a Linux shell command. Use with caution!");
1953 s->writeString(pfx,
"shell <string> - execute <string> as a Linux shell command. Use with caution!");
1954 s->writeString(pfx,
"shellstart - execute all subsequent commands as Linux shell commands. Use with caution!");
1955 s->writeString(pfx,
"shellstop - stop executing all subsequent commands as Linux shell commands.");
1958 s->writeString(pfx,
"dnnget <key> - download and install a DNN from JeVois Model Converter");
1961#ifdef JEVOIS_PLATFORM
1962 s->writeString(pfx,
"restart - restart the JeVois smart camera");
1965#ifndef JEVOIS_PLATFORM_A33
1966 s->writeString(pfx,
"quit - quit this program");
1971void jevois::Engine::modCmdInfo(std::shared_ptr<UserInterface> s, std::string
const & pfx)
1975 std::stringstream css; itsModule->supportedCommands(css);
1976 for (std::string line; std::getline(css, line); ) s->writeString(pfx, line);
1990 if (str ==
"shellstop") { itsShellMode =
false;
return true; }
1994 for (std::string
const & r : rvec) s->writeString(pfx, r);
2010 switch (str.length())
2013 LDEBUG(
"Ignoring empty string");
return true;
2017 if (str[0] ==
'~') {
LDEBUG(
"Ignoring modem config command [~]");
return true; }
2021 if (str[0] ==
'#') { sendSerial(str,
true);
return true; }
2027 if (str[0] ==
'~') {
LDEBUG(
"Ignoring modem config command [" << str <<
']');
return true; }
2030 if (str[0] ==
'A' && str[1] ==
'T') {
LDEBUG(
"Ignoring AT command [" << str <<
']');
return true; }
2034 if (str[0] ==
'#') { sendSerial(str,
true);
return true; }
2037 std::string cmd, rem;
2040 cmd =
"shell"; rem = str.substr(1);
2045 size_t const idx = str.find(
' ');
2046 if (idx == str.npos) cmd = str;
2047 else { cmd = str.substr(0, idx);
if (idx < str.length()) rem = str.substr(idx+1); }
2054 s->writeString(pfx,
"GENERAL COMMANDS:");
2055 s->writeString(pfx,
"");
2056 cmdInfo(s,
false, pfx);
2057 s->writeString(pfx,
"");
2062 s->writeString(pfx,
"MODULE-SPECIFIC COMMANDS:");
2063 s->writeString(pfx,
"");
2065 s->writeString(pfx,
"");
2069 std::stringstream pss; constructHelpMessage(pss);
2070 for (std::string line; std::getline(pss, line); ) s->writeString(pfx, line);
2073 s->writeString(pfx,
"AVAILABLE CAMERA CONTROLS:");
2074 s->writeString(pfx,
"");
2076 foreachCamCtrl([
this,&pfx,&s](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2080 std::string hlp = camCtrlHelp(qc, doneids);
2081 if (hlp.empty() ==
false) s->writeString(pfx, hlp);
2088 if (cmd ==
"caminfo")
2091 foreachCamCtrl([
this,&pfx,&s](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2095 std::string hlp = camCtrlInfo(qc, doneids);
2096 if (hlp.empty() ==
false) s->writeString(pfx, hlp);
2103 if (cmd ==
"cmdinfo")
2105 bool showAll = (rem ==
"all") ?
true :
false;
2106 cmdInfo(s, showAll, pfx);
2111 if (cmd ==
"modcmdinfo")
2118 if (cmd ==
"paraminfo")
2120 std::map<std::string, std::string> categs;
2121 bool skipFrozen = (rem ==
"hot" || rem ==
"modhot") ?
true :
false;
2123 if (rem ==
"mod" || rem ==
"modhot")
2126 if (itsModule) itsModule->paramInfo(s, categs, skipFrozen, instanceName(), pfx);
2131 paramInfo(s, categs, skipFrozen,
"", pfx);
2138 if (cmd ==
"serinfo")
2140 std::string info = getParamStringUnique(
"serout") +
' ' + getParamStringUnique(
"serlog");
2142 info +=
' ' + mod->getParamStringUnique(
"serstyle") +
' ' + mod->getParamStringUnique(
"serprec") +
2143 ' ' + mod->getParamStringUnique(
"serstamp");
2144 else info +=
" - - -";
2146 s->writeString(pfx, info);
2157 std::stringstream css; itsModule->supportedCommands(css);
2158 s->writeString(pfx,
"MODULE-SPECIFIC COMMANDS:");
2159 s->writeString(pfx,
"");
2160 for (std::string line; std::getline(css, line); ) s->writeString(pfx, line);
2161 s->writeString(pfx,
"");
2164 s->writeString(pfx,
"MODULE PARAMETERS:");
2165 s->writeString(pfx,
"");
2168 std::unordered_map<std::string,
2169 std::unordered_map<std::string,
2170 std::vector<std::pair<std::string,
2173 itsModule->populateHelpMessage(
"", helplist);
2175 if (helplist.empty())
2176 s->writeString(pfx,
"None.");
2179 for (
auto const & c : helplist)
2182 s->writeString(pfx, c.first);
2185 for (
auto const & n : c.second)
2187 std::vector<std::string> tok =
jevois::split(n.first,
"[\\r\\n]+");
2189 for (
auto const & t : tok)
2194 auto const & v = n.second;
2197 if (v[0].second.empty())
2198 s->writeString(pfx, t);
2200 s->writeString(pfx, t +
" current=[" + v[0].second +
']');
2202 else if (v.size() > 1)
2204 std::string sss = t +
" current=";
2205 for (
auto const & pp : v)
2206 if (pp.second.empty() ==
false) sss +=
'[' + pp.first +
':' + pp.second +
"] ";
2207 s->writeString(pfx, sss);
2209 else s->writeString(pfx, t);
2215 s->writeString(pfx, t);
2218 s->writeString(pfx,
"");
2223 s->writeString(pfx,
"No module loaded.");
2235 if (itsModule) s->writeString(pfx,
"INFO: " + itsCurrentMapping.str());
2241 if (cmd ==
"setpar")
2243 size_t const remidx = rem.find(
' ');
2244 if (remidx != rem.npos)
2246 std::string
const desc = rem.substr(0, remidx);
2247 if (remidx < rem.length())
2249 std::string
const val = rem.substr(remidx+1);
2250 setParamString(desc, val);
2254 errmsg =
"Need to provide a parameter name and a parameter value in setpar";
2258 if (cmd ==
"getpar")
2260 auto vec = getParamString(rem);
2261 for (
auto const & p : vec) s->writeString(pfx, p.first +
' ' + p.second);
2266 if (cmd ==
"setcam")
2268 std::istringstream ss(rem); std::string ctrl;
int val; ss >> ctrl >> val;
2269 struct v4l2_control c = { }; c.id = camctrlid(ctrl); c.value = val;
2272 if (val == 0 && ctrl ==
"ispsensorpreset")
2274 c.value = 1; itsCamera->setControl(c);
2275 c.value = 0; itsCamera->setControl(c);
2277 else itsCamera->setControl(c);
2283 if (cmd ==
"getcam")
2285 struct v4l2_control c = { }; c.id = camctrlid(rem);
2286 itsCamera->getControl(c);
2287 s->writeString(pfx, rem +
' ' + std::to_string(c.value));
2292 if (cmd ==
"setcamreg")
2296 auto cam = std::dynamic_pointer_cast<jevois::Camera>(itsCamera);
2300 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2301 cam->writeRegister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2304 else errmsg =
"Not using a camera for video input";
2306 else errmsg =
"Access to camera registers is disabled, enable with: setpar camreg true";
2310 if (cmd ==
"getcamreg")
2314 auto cam = std::dynamic_pointer_cast<jevois::Camera>(itsCamera);
2317 unsigned int val = cam->readRegister(std::stoi(rem,
nullptr, 0));
2318 std::ostringstream os; os << std::hex << val;
2319 s->writeString(pfx, os.str());
2322 else errmsg =
"Not using a camera for video input";
2324 else errmsg =
"Access to camera registers is disabled, enable with: setpar camreg true";
2328 if (cmd ==
"setimureg")
2335 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2336 itsIMU->writeRegister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2339 else errmsg =
"No IMU driver loaded";
2341 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2345 if (cmd ==
"getimureg")
2351 unsigned int val = itsIMU->readRegister(std::stoi(rem,
nullptr, 0));
2352 std::ostringstream os; os << std::hex << val;
2353 s->writeString(pfx, os.str());
2356 else errmsg =
"No IMU driver loaded";
2358 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2362 if (cmd ==
"setimuregs")
2370 if (v.size() < 3) errmsg =
"Malformed arguments, need at least 3";
2373 unsigned short reg = std::stoi(v[0],
nullptr, 0);
2374 size_t num = std::stoi(v[1],
nullptr, 0);
2375 if (num > 32) errmsg =
"Maximum transfer size is 32 bytes";
2376 else if (num != v.size() - 2) errmsg =
"Incorrect number of data bytes, should pass " + v[1] +
" values.";
2379 unsigned char data[32];
2380 for (
size_t i = 2; i < v.size(); ++i) data[i-2] = std::stoi(v[i],
nullptr, 0) & 0xff;
2382 itsIMU->writeRegisterArray(reg, data, num);
2387 else errmsg =
"No IMU driver loaded";
2389 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2393 if (cmd ==
"getimuregs")
2399 std::istringstream ss(rem); std::string reg, num; ss >> reg >> num;
2400 int n = std::stoi(num,
nullptr, 0);
2402 if (n > 32) errmsg =
"Maximum transfer size is 32 bytes";
2405 unsigned char data[32];
2406 itsIMU->readRegisterArray(std::stoi(reg,
nullptr, 0), data, n);
2408 std::ostringstream os; os << std::hex;
2409 for (
int i = 0; i < n; ++i) os << (
unsigned int)(data[i]) <<
' ';
2410 s->writeString(pfx, os.str());
2414 else errmsg =
"No IMU driver loaded";
2416 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2420 if (cmd ==
"setdmpreg")
2427 std::istringstream ss(rem); std::string reg, val; ss >> reg >> val;
2428 itsIMU->writeDMPregister(std::stoi(reg,
nullptr, 0), std::stoi(val,
nullptr, 0));
2431 else errmsg =
"No IMU driver loaded";
2433 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2437 if (cmd ==
"getdmpreg")
2443 unsigned int val = itsIMU->readDMPregister(std::stoi(rem,
nullptr, 0));
2444 std::ostringstream os; os << std::hex << val;
2445 s->writeString(pfx, os.str());
2448 else errmsg =
"No IMU driver loaded";
2450 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2454 if (cmd ==
"setdmpregs")
2462 if (v.size() < 3) errmsg =
"Malformed arguments, need at least 3";
2465 unsigned short reg = std::stoi(v[0],
nullptr, 0);
2466 size_t num = std::stoi(v[1],
nullptr, 0);
2467 if (num > 32) errmsg =
"Maximum transfer size is 32 bytes";
2468 else if (num != v.size() - 2) errmsg =
"Incorrect number of data bytes, should pass " + v[1] +
" values.";
2471 unsigned char data[32];
2472 for (
size_t i = 2; i < v.size(); ++i) data[i-2] = std::stoi(v[i],
nullptr, 0) & 0xff;
2474 itsIMU->writeDMPregisterArray(reg, data, num);
2479 else errmsg =
"No IMU driver loaded";
2481 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2485 if (cmd ==
"getdmpregs")
2491 std::istringstream ss(rem); std::string reg, num; ss >> reg >> num;
2492 int n = std::stoi(num,
nullptr, 0);
2494 if (n > 32) errmsg =
"Maximum transfer size is 32 bytes";
2497 unsigned char data[32];
2498 itsIMU->readDMPregisterArray(std::stoi(reg,
nullptr, 0), data, n);
2500 std::ostringstream os; os << std::hex;
2501 for (
int i = 0; i < n; ++i) os << (
unsigned int)(data[i]) <<
' ';
2502 s->writeString(pfx, os.str());
2506 else errmsg =
"No IMU driver loaded";
2508 else errmsg =
"Access to IMU registers is disabled, enable with: setpar imureg true";
2512 if (cmd ==
"listmappings")
2514 s->writeString(pfx,
"AVAILABLE VIDEO MAPPINGS:");
2515 s->writeString(pfx,
"");
2516 for (
size_t idx = 0; idx < itsMappings.size(); ++idx)
2518 std::string idxstr = std::to_string(idx);
2519 if (idxstr.length() < 5) idxstr = std::string(5 - idxstr.length(),
' ') + idxstr;
2520 s->writeString(pfx, idxstr +
" - " + itsMappings[idx].str());
2526 if (cmd ==
"setmapping")
2528 size_t const idx = std::stoi(rem);
2530 if (itsStreaming.load() && itsCurrentMapping.ofmt)
2531 errmsg =
"Cannot set mapping while streaming: Stop your webcam program on the host computer first.";
2532 else if (idx >= itsMappings.size())
2533 errmsg =
"Requested mapping index " + std::to_string(idx) +
" out of range [0 .. " +
2534 std::to_string(itsMappings.size()-1) +
']';
2539 setFormatInternal(idx);
2542 catch (std::exception
const & e) { errmsg =
"Error parsing or setting mapping [" + rem +
"]: " + e.what(); }
2543 catch (...) { errmsg =
"Error parsing or setting mapping [" + rem +
']'; }
2548 if (cmd ==
"setmapping2")
2550 if (itsStreaming.load() && itsCurrentMapping.ofmt)
2551 errmsg =
"Cannot set mapping while streaming: Stop your webcam program on the host computer first.";
2557 setFormatInternal(m);
2560 catch (std::exception
const & e) { errmsg =
"Error parsing or setting mapping [" + rem +
"]: " + e.what(); }
2561 catch (...) { errmsg =
"Error parsing or setting mapping [" + rem +
']'; }
2566 if (cmd ==
"reload")
2568 setFormatInternal(itsCurrentMapping,
true);
2573 if (itsCurrentMapping.ofmt == 0 || itsCurrentMapping.ofmt ==
JEVOISPRO_FMT_GUI || itsManualStreamon)
2575 if (cmd ==
"streamon")
2578 itsCamera->streamOn();
2579 itsGadget->streamOn();
2580 itsStreaming.store(
true);
2584 if (cmd ==
"streamoff")
2587 itsGadget->abortStream();
2588 itsCamera->abortStream();
2590 itsStreaming.store(
false);
2592 itsGadget->streamOff();
2593 itsCamera->streamOff();
2601 s->writeString(pfx,
"ALIVE");
2606 if (cmd ==
"serlog")
2608 sendSerial(rem,
true);
2613 if (cmd ==
"serout")
2615 sendSerial(rem,
false);
2620#ifdef JEVOIS_PLATFORM_A33
2623 if (itsStreaming.load())
2625 errmsg =
"Cannot export microSD over USB while streaming: ";
2626 if (itsCurrentMapping.ofmt) errmsg +=
"Stop your webcam program on the host computer first.";
2627 else errmsg +=
"Issue a 'streamoff' command first.";
2631 startMassStorageMode();
2640 if (std::system(
"sync")) errmsg =
"Disk sync failed";
2648 s->writeString(pfx,
"date now " + dat.substr(0, dat.size()-1));
2653 if (cmd ==
"runscript")
2655 std::string
const fname = itsModule ? itsModule->absolutePath(rem).string() : rem;
2657 try { runScriptFromFile(fname, s,
true);
return true; }
2658 catch (...) { errmsg =
"Script " + fname +
" execution failed"; }
2666 for (std::string
const & r : rvec) s->writeString(pfx, r);
2671 if (cmd ==
"shellstart")
2673 itsShellMode =
true;
2680 if (cmd ==
"dnnget")
2682 if (rem.length() != 4 || std::regex_match(rem, std::regex(
"^[a-zA-Z0-9]+$")) ==
false)
2683 errmsg =
"Key must be a 4-character alphanumeric string, as emailed to you by the model converter.";
2687 s->writeString(pfx,
"Downloading custom DNN model " + rem +
" ...");
2688 std::string
const zip = rem +
".zip";
2692 for (std::string
const & r : rvec) s->writeString(pfx, r);
2696 if (ifs.is_open() ==
false)
2697 errmsg =
"Failed to download. Check network connectivity and available disk space.";
2701 s->writeString(pfx,
"Unpacking custom DNN model " + rem +
" ...");
2704 rvec =
jevois::split(ret,
"\n");
for (std::string
const & r : rvec) s->writeString(pfx, r);
2707 rvec =
jevois::split(ret,
"\n");
for (std::string
const & r : rvec) s->writeString(pfx, r);
2709 s->writeString(pfx,
"Reload your model zoo for changes to take effect.");
2718 if (cmd ==
"fileget")
2720 std::shared_ptr<jevois::Serial> ser = std::dynamic_pointer_cast<jevois::Serial>(s);
2722 errmsg =
"File transfer only supported over USB or Hard serial ports";
2725 std::string
const abspath = itsModule ? itsModule->absolutePath(rem).string() : rem;
2726 ser->fileGet(abspath);
2732 if (cmd ==
"fileput")
2734 std::shared_ptr<jevois::Serial> ser = std::dynamic_pointer_cast<jevois::Serial>(s);
2736 errmsg =
"File transfer only supported over USB or Hard serial ports";
2739 std::string
const abspath = itsModule ? itsModule->absolutePath(rem).string() : rem;
2740 ser->filePut(abspath);
2741 if (std::system(
"sync")) { }
2746#ifdef JEVOIS_PLATFORM
2748 if (cmd ==
"restart")
2750 s->writeString(pfx,
"Restart command received - bye-bye!");
2752 if (itsStreaming.load())
2753 s->writeString(pfx,
"ERR Video streaming is on - you should quit your video viewer before rebooting");
2755 if (std::system(
"sync")) s->writeString(pfx,
"ERR Disk sync failed -- IGNORED");
2757#ifdef JEVOIS_PLATFORM_A33
2761 if (std::system(
"sync")) s->writeString(pfx,
"ERR Disk sync failed -- IGNORED");
2771#ifndef JEVOIS_PLATFORM_A33
2775 s->writeString(pfx,
"Quit command received - bye-bye!");
2786 if (errmsg.size())
throw std::runtime_error(
"Command error [" + str +
"]: " + errmsg);
2797 std::ifstream ifs(filename);
2798 if (!ifs) {
if (throw_no_file)
LFATAL(
"Could not open file " << filename);
else return; }
2804 if (itsSerials.empty())
LFATAL(
"Need at least one active serial to run script");
2806 switch (serlog::get())
2808 case jevois::engine::SerPort::Hard:
2812 case jevois::engine::SerPort::USB:
2824 if (!ser) ser = itsSerials.front();
2829 for (std::string line; std::getline(ifs, line); )
2837 if (line.length() == 0 || line[0] ==
'#')
continue;
2842 bool parsed =
false;
2843 try { parsed = parseCommand(line, ser); }
2844 catch (std::exception
const & e)
2845 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": " + e.what()); }
2847 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": Bogus command ["+line+
"] ignored"); }
2849 if (parsed ==
false)
2853 try { itsModule->parseSerial(line, ser); }
2854 catch (std::exception
const & me)
2855 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum) +
": " + me.what()); }
2857 { ser->writeString(
"ERR " + filename +
':' + std::to_string(linenum)+
": Bogus command ["+line+
"] ignored"); }
2859 else ser->writeString(
"ERR Unsupported command [" + line +
"] and no module");
2871 ImGui::Columns(2,
"camctrl");
2873 foreachCamCtrl([
this](
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2875 try { camCtrlGUI(qc, doneids); }
catch (...) { }
2882void jevois::Engine::camCtrlGUI(
struct v4l2_queryctrl & qc, std::set<int> & doneids)
2885 itsCamera->queryControl(qc);
2886 qc.id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
2889 if (doneids.find(qc.id) != doneids.end())
return;
else doneids.insert(qc.id);
2892 struct v4l2_control ctrl = { }; ctrl.id = qc.id;
2893 itsCamera->getControl(ctrl);
2896 ImGui::AlignTextToFramePadding();
2897 ImGui::TextUnformatted(
reinterpret_cast<char const *
>(qc.name));
2898 ImGui::NextColumn();
2901 if (qc.flags & V4L2_CTRL_FLAG_DISABLED)
2903 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
2904 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
2908 static char wname[16]; snprintf(wname, 16,
"##c%d", ctrl.id);
2913 case V4L2_CTRL_TYPE_INTEGER:
2914 case V4L2_CTRL_TYPE_INTEGER_MENU:
2917 long range = long(qc.maximum) - long(qc.minimum);
2918 if (range > 1 && range < 5000)
2920 if (ImGui::SliderInt(wname, &ctrl.value, qc.minimum, qc.maximum)) itsCamera->setControl(ctrl);
2925 if (ImGui::InputInt(wname, &ctrl.value, qc.step, qc.step * 2)) itsCamera->setControl(ctrl);
2942 case V4L2_CTRL_TYPE_BOOLEAN:
2944 bool checked = (ctrl.value != 0);
2945 if (ImGui::Checkbox(wname, &checked)) { ctrl.value = checked ? 1 : 0; itsCamera->setControl(ctrl); }
2950 case V4L2_CTRL_TYPE_BUTTON:
2951 static char bname[16]; snprintf(bname, 16,
"Go##%d", ctrl.id);
2952 if (ImGui::Button(bname)) { ctrl.value = 1; itsCamera->setControl(ctrl); }
2955 case V4L2_CTRL_TYPE_BITMASK:
2959 case V4L2_CTRL_TYPE_MENU:
2961 struct v4l2_querymenu querymenu = { };
2962 querymenu.id = qc.id;
2963 char * items[qc.maximum - qc.minimum + 1];
2965 for (querymenu.index = qc.minimum; querymenu.index <= (
unsigned int)qc.maximum; ++querymenu.index)
2967 try { itsCamera->queryMenu(querymenu); }
catch (...) { strncpy((
char *)querymenu.name,
"fixme", 32); }
2968 items[querymenu.index] =
new char[32];
2969 strncpy(items[querymenu.index], (
char const *)querymenu.name, 32);
2972 int idx = ctrl.value - qc.minimum;
2973 if (ImGui::Combo(wname, &idx, items, qc.maximum - qc.minimum + 1))
2974 { ctrl.value = qc.minimum + idx; itsCamera->setControl(ctrl); }
2976 for (
int i = qc.minimum; i <= qc.maximum; ++i)
delete [] items[i];
2986 static char rname[16]; snprintf(rname, 16,
"Reset##%d", ctrl.id);
2988 if (ImGui::Button(rname)) { ctrl.value = qc.default_value; itsCamera->setControl(ctrl); }
2992 if (qc.flags & V4L2_CTRL_FLAG_DISABLED)
2994 ImGui::PopItemFlag();
2995 ImGui::PopStyleVar();
2999 ImGui::NextColumn();
3009 std::lock_guard<std::mutex> _(itsPyRegMtx);
3010 auto itr = itsPythonRegistry.find(pyinst);
3011 if (itr != itsPythonRegistry.end())
LFATAL(
"Trying to register twice -- ABORT");
3012 itsPythonRegistry.insert(std::make_pair(pyinst, comp));
3019 std::lock_guard<std::mutex> _(itsPyRegMtx);
3020 auto itr = itsPythonRegistry.begin(), stop = itsPythonRegistry.end();
3021 while (itr != stop)
if (itr->second == comp) itr = itsPythonRegistry.erase(itr);
else ++itr;
3027 LDEBUG(std::hex << pyinst);
3028 std::lock_guard<std::mutex> _(itsPyRegMtx);
3029 auto itr = itsPythonRegistry.find(pyinst);
3030 if (itr == itsPythonRegistry.end())
LFATAL(
"Python instance not registered -- ABORT");
3039 if (strncmp(name,
"jevois", 6) == 0) cv::parallel::setParallelForBackend(itsOpenCVparallelAPI);
3040 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 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.