40 auto v = std::strtol( s.data(), &p_end, 10 );
42 throw std::out_of_range(
"out of range" );
43 if( p_end != s.data() + s.length() )
44 throw std::invalid_argument(
"extra characters" );
57 if( ch ==
'1' || ch ==
'T' )
59 if( ch ==
'0' || ch ==
'F' )
64 if( s ==
"true" || s ==
"TRUE" || s ==
"on" || s ==
"ON" )
66 if( s ==
"false" || s ==
"FALSE" || s ==
"off" || s ==
"OFF" )
69 throw std::invalid_argument(
"invalid boolean value '" + s +
'\'' );
81 env_var(
char const *
name,
T default_value, std::function<
bool(
T ) > checker =
nullptr )
83 auto lpsz = getenv( name );
84 _is_set = (lpsz !=
nullptr);
90 if( checker && ! checker( _value ) )
91 throw std::invalid_argument(
"does not check" );
93 catch( std::exception
const &
e )
96 "Environment variable \"" << name <<
"\" is set, but its value (\"" 97 << lpsz <<
"\") is invalid (" << e.what()
98 <<
"); using default of \"" << default_value
104 _value = default_value;
110 operator T()
const {
return _value; }
119 std::time_t
now = std::time(
nullptr );
120 auto ptm = localtime( &now );
122 strftime( buf,
sizeof( buf ), format_string, ptm );
131 =
env_var< int >(
"RS2_AC_SF_RETRY_SECONDS", 2, [](
int n ) {
return n > 0; } );
144 [](
int n ) {
return n >= 0; } );
146 return std::chrono::seconds( n_seconds );
159 if(
auto vsp = dynamic_cast< const librealsense::video_stream_profile * >( spi ) )
160 os <<
' ' << vsp->get_width() <<
'x' << vsp->get_height();
161 os <<
" " << spi->get_framerate() <<
"fps";
193 ac_trigger::enabler_option::enabler_option( std::shared_ptr< ac_trigger >
const & autocal )
211 if( value ==
query() )
218 throw std::runtime_error(
"device no longer exists" );
230 if (ac->_dev.get_depth_sensor().is_streaming())
235 catch (std::exception
const &
e)
237 AC_LOG(ERROR,
"EXCEPTION caught during start: " << e.what());
253 bool is_depth_streaming(
false);
255 is_depth_streaming = ac->_dev.get_depth_sensor().is_streaming();
257 if( is_depth_streaming )
259 AC_LOG(
DEBUG,
"Triggering manual calibration..." );
274 throw std::runtime_error(
"device no longer exists" );
279 ac->_dev.get_depth_sensor().reset_calibration();
290 std::weak_ptr<ac_trigger>
_ac;
296 : _ac( ac.shared_from_this() )
297 , _name( name ? name :
"retrier" )
299 static unsigned id = 0;
304 std::shared_ptr <ac_trigger>
get_ac()
const {
return _ac.lock(); }
313 return _prefix( get_name(),
get_id() );
327 template <
class T = retrier >
329 std::chrono::seconds n_seconds,
330 const char *
name =
nullptr )
332 T *
r =
new T( trigger,
name );
333 auto id = r->get_id();
334 name = r->get_name();
335 AC_LOG(
DEBUG, r->prefix() << n_seconds.count() <<
" seconds starting" );
336 auto pr = std::shared_ptr< T >(
r );
337 std::weak_ptr< T > weak{ pr };
339 std::this_thread::sleep_for( n_seconds );
340 auto pr = weak.lock();
341 if( pr && pr->get_id() ==
id )
346 auto ac = ( (
retrier *)pr.get() )->get_ac();
348 ( (
retrier *)pr.get() )->retry( *ac );
350 catch( std::exception
const &
e )
353 AC_LOG( ERROR,
"EXCEPTION caught: " << e.what() );
359 << n_seconds.count() <<
" seconds are up; nothing needed" );
368 :
retrier( ac, name ? name :
"next trigger" )
394 :
retrier( ac, name ? name :
"temp check" )
412 auto d_temp = current_temp - trigger.
_last_temp;
417 AC_LOG(
DEBUG,
"Delta since last successful calibration is " << d_temp <<
" degrees Celsius; triggering..." );
458 if( AttachConsole( ATTACH_PARENT_PROCESS ) || AllocConsole() )
464 if( ! filename.empty() )
466 filename +=
".ac_log";
468 _f_main.open( filename );
469 if( _f_main && _to_stdout )
470 write_out(
to_string() <<
"-D- CAH main log is being written to: " << filename );
482 char const dir_sep =
'\\';
484 char const dir_sep =
'/';
486 if( ! path.empty() && path.back() != dir_sep )
496 auto dir_ = getenv(
"RS2_DEBUG_DIR" );
509 _active_dir = get_debug_path_base();
510 if( _active_dir.empty() )
512 add_dir_sep( _active_dir );
515 auto status = _mkdir( _active_dir.c_str() );
517 auto status = mkdir( _active_dir.c_str(), 0700 );
523 "Failed (" << status <<
") to create directory for AC frame data in: " << _active_dir );
535 if( ! set_active_dir() )
538 if( _f_main || _to_stdout )
540 _f_active.open( filename );
543 else if( _to_stdout )
544 write_out(
to_string() <<
"-D- CAH active log is being written to: " << filename );
552 _f_active.setstate( std::ios_base::failbit );
561 #ifdef BUILD_EASYLOGGINGPP 563 char const * raw = wrapper.el_msg.message().c_str();
566 std::ostringstream ss;
567 ss <<
"-" <<
"DIWE"[
severity] <<
"- ";
573 _f_active << text << std::endl;
575 _f_main << text << std::endl;
585 HANDLE stdOut = GetStdHandle( STD_OUTPUT_HANDLE );
586 if( stdOut !=
NULL && stdOut != INVALID_HANDLE_VALUE )
589 WriteFile( stdOut, s.c_str(), (DWORD)s.length(), &written,
NULL );
590 WriteFile( stdOut,
"\n", 1, &written,
NULL );
640 AC_LOG( ERROR,
"Retry attempted but we're not active; ignoring" );
645 AC_LOG( ERROR,
"Failed to receive stable RGB frame; cancelling calibration" );
670 AC_LOG( ERROR,
"Too many retries; aborting" );
680 AC_LOG(
DEBUG,
"Waiting for RGB stability before asking for special frame" );
696 auto hwm =
_hwm.lock();
699 AC_LOG( ERROR,
"Hardware monitor is inaccessible - calibration not triggered" );
704 catch( std::exception
const &
e )
706 AC_LOG( ERROR,
"EXCEPTION caught: " << e.what() );
718 AC_LOG( ERROR,
"Failed to trigger calibration: CAH is already active" );
723 AC_LOG( ERROR,
"Bad inactive state: one of retrier or recycler is set!" );
724 throw std::runtime_error(
"bad inactive state" );
745 AC_LOG(
INFO,
"Camera Accuracy Health check is now active (HUM temp is " <<
_temp <<
" dec C)" );
752 AC_LOG(
DEBUG,
"Waiting for RGB stability before asking for special frame" );
757 AC_LOG(
DEBUG,
"Sending GET_SPECIAL_FRAME (cycle 1)" );
772 AC_LOG( ERROR,
"No color sensor in device; cannot run AC?!" );
777 auto rgb_profile =
depth_sensor.is_color_sensor_needed();
788 =
color_sensor->start_stream_for_calibration( { rgb_profile } );
790 catch( std::exception
const &
e )
792 AC_LOG( ERROR,
"EXCEPTION caught: " << e.what() );
809 catch (std::exception& ex)
811 AC_LOG(ERROR,
"caught exception in closing color sensor: " << ex.what());
815 AC_LOG(ERROR,
"unknown exception in closing color sensor");
826 AC_LOG( ERROR,
"Special frame received while is_active() is false" );
836 AC_LOG( ERROR,
"already processing; ignoring special frame!" );
842 AC_LOG( ERROR,
"no IR frame found; ignoring special frame!" );
849 AC_LOG( ERROR,
"no depth frame found; ignoring special frame!" );
875 if( time < std::chrono::milliseconds( 1000 ) )
879 AC_LOG(
DEBUG,
"RGB frame #" << number <<
" is our first stable frame" );
886 " backlight compensation= " 922 AC_LOG(
DEBUG,
"no color frame received; maybe color stream isn't on?" );
943 "Starting processing:" 958 AC_LOG(
DEBUG,
"Calibration algo has started ..." );
964 float dsm_x_scale, dsm_y_scale, dsm_x_offset, dsm_y_offset;
968 auto hwm =
_hwm.lock();
970 throw std::runtime_error(
"HW monitor is inaccessible - stopping algo" );
985 catch( std::exception
const &
e )
992 "dsm registers= x[" <<
AC_F_PREC << dsm_x_scale <<
' ' << dsm_y_scale
993 <<
"] +[" << dsm_x_offset <<
' ' << dsm_y_offset
1004 auto should_continue = [&]()
1008 AC_LOG(
DEBUG,
"Stopping algo: not processing any more" );
1009 throw std::runtime_error(
"stopping algo: not processing any more" );
1031 if( ! debug_dir.empty() )
1049 AC_LOG(
DEBUG,
"Algo finished (with " << status <<
"), but stop() was detected; notifying of failure..." );
1074 AC_LOG( ERROR,
"Too many retry cycles; quitting" );
1082 =
env_var< int >( is_manual ?
"RS2_AC_INVALID_RETRY_SECONDS_MANUAL" 1083 :
"RS2_AC_INVALID_RETRY_SECONDS_AUTO",
1085 [](
int n ) {
return n > 0; } );
1097 "Unexpected status '" << status <<
"' received from CAH algo; stopping!" );
1102 catch( std::exception &
e )
1104 AC_LOG( ERROR,
"EXCEPTION in calibration algo: " << e.what() );
1109 catch( std::exception & e )
1111 AC_LOG( ERROR,
"EXCEPTION in FAILED callback: " << e.what() );
1115 AC_LOG( ERROR,
"EXCEPTION in FAILED callback!" );
1120 AC_LOG( ERROR,
"Unknown EXCEPTION in calibration algo!!!" );
1125 catch( std::exception & e )
1127 AC_LOG( ERROR,
"EXCEPTION in FAILED callback: " << e.what() );
1131 AC_LOG( ERROR,
"EXCEPTION in FAILED callback!" );
1175 AC_LOG(
WARNING,
"Camera Accuracy Health has finished unsuccessfully" );
1177 AC_LOG(
INFO,
"Camera Accuracy Health has finished" );
1197 AC_LOG(
DEBUG,
"Calibration mechanism is not on; not scheduling next calibration" );
1207 if( ! n_seconds.count() )
1210 if (!n_seconds.count())
1212 AC_LOG(
DEBUG,
"RS2_AC_TRIGGER_SECONDS is 0; no time trigger");
1218 _next_trigger = retrier::start< next_trigger >( *
this, n_seconds );
1228 _temp_check = retrier::start< temp_check >( *
this, std::chrono::seconds( 60 ) );
1232 AC_LOG(
DEBUG,
"RS2_AC_TEMP_DIFF is 0; no temperature change trigger" );
1246 bool is_streaming =
false;
1251 catch( std::exception
const &
e )
1253 AC_LOG( ERROR,
"EXCEPTION caught: " << e.what() );
1255 if( ! is_streaming )
1257 AC_LOG( ERROR,
"Not streaming; stopping" );
1264 auto alt_ir_is_on =
false;
1271 catch( std::exception
const & e )
1278 if( ! invalid_reason.empty() )
1279 invalid_reason +=
", ";
1280 invalid_reason +=
to_string() <<
"alternate IR is on";
1285 auto thermal_table_valid =
true;
1290 catch( std::exception
const & e )
1293 thermal_table_valid =
false;
1296 if( ! thermal_table_valid )
1302 if( ! invalid_reason.empty() )
1303 invalid_reason +=
", ";
1304 invalid_reason +=
to_string() <<
"temperature (" <<
_temp <<
") too low (<32)";
1306 else if(
_temp > 46. )
1308 if( ! invalid_reason.empty() )
1309 invalid_reason +=
", ";
1310 invalid_reason +=
to_string() <<
"temperature (" <<
_temp <<
") too high (>46)";
1319 float raw_digital_gain = digital_gain.query();
1321 float raw_apd =
apd.query();
1329 if( ! invalid_reason.empty() )
1330 invalid_reason +=
", ";
1332 <<
"receiver gain(" << raw_apd <<
") of 18 is expected with low digital gain(SHORT)";
1339 if( ! invalid_reason.empty() )
1340 invalid_reason +=
", ";
1342 <<
"receiver gain(" << raw_apd <<
") of 9 is expected with high digital gain(LONG)";
1347 if( ! invalid_reason.empty() )
1348 invalid_reason +=
", ";
1349 invalid_reason +=
to_string() <<
"invalid (" << raw_digital_gain <<
") digital gain preset";
1353 if( ! invalid_reason.empty() )
1356 AC_LOG(
DEBUG,
"Invalid conditions for CAH: " << invalid_reason );
1359 AC_LOG(
DEBUG,
"RS2_AC_DISABLE_CONDITIONS is on; continuing anyway" );
1376 catch( std::exception
const &
e )
1378 AC_LOG( ERROR,
"EXCEPTION caught in access to device: " << e.what() );
1392 AC_LOG(
DEBUG,
"Auto trigger is disabled in environment" );
1444 AC_LOG(
DEBUG,
"Algo is processing; signalling stop" );
1450 std::shared_ptr< ac_trigger > autocal
1453 , _autocal{ autocal }
1467 return 0x5F ==
mode;
1491 auto df = fs.get_depth_frame();
1492 if( autocal && autocal->is_expecting_special_frame() &&
is_special_frame( df ) )
1495 autocal->set_special_frame( f );
1519 if( results.empty() )
1527 std::shared_ptr< ac_trigger > autocal
1546 autocal->set_color_frame( f );
std::string prefix() const
std::weak_ptr< ac_trigger > _autocal
rs2::frame prepare_output(const rs2::frame_source &source, rs2::frame input, std::vector< rs2::frame > results) override
static const textual_icon lock
std::vector< callback > _callbacks
const char * rs2_format_to_string(rs2_format format)
std::shared_ptr< temp_check > _temp_check
static std::ostream & operator<<(std::ostream &os, stream_profile const &sp)
temp_check(ac_trigger &ac, const char *name)
static int get_retry_sf_seconds()
std::function< void(const option &)> _record_action
GLenum GLuint GLenum severity
void trigger_calibration(calibration_type type)
GLuint const GLchar * name
std::weak_ptr< ac_trigger > _autocal
rs2_dsm_params const & get_dsm_params() const
bool should_process(const rs2::frame &frame) override
reset_option(std::shared_ptr< ac_trigger > const &autocal)
rs2_extrinsics const & get_extrinsics() const
void log_to_callback(rs2_log_severity min_severity, log_callback_ptr callback)
rs2_metadata_type get_frame_metadata(rs2_frame_metadata_value frame_metadata) const
depth_processing_block(std::shared_ptr< ac_trigger > autocal)
virtual l500_color_sensor * get_color_sensor()=0
GLsizei const GLchar *const * path
stream_profile get_profile() const
rs2_intrinsics _thermal_intr
bool check_color_depth_sync()
next_trigger(ac_trigger &ac, const char *name)
static double get_temp_diff_trigger()
void trigger_special_frame()
void schedule_next_calibration()
bool _need_to_wait_for_color_sensor_stability
void convert(rs2_format source, std::string &target)
const void * get_data() const
bool supports_frame_metadata(rs2_frame_metadata_value frame_metadata) const
GLsizei const GLchar *const * string
ac_trigger(l500_device &dev, std::shared_ptr< hw_monitor > hwm)
static bool is_auto_trigger_possible()
calibration_type _calibration_type
option & get_option(rs2_option id) override
virtual float query() const =0
void stop_color_sensor_if_started()
rs2_intrinsics get_raw_intrinsics(uint32_t width, uint32_t height) const
bool auto_calibration_is_on() const
status
Defines return codes that SDK interfaces use. Negative values indicate errors, a zero value indicates...
rs2::frame process_frame(const rs2::frame_source &source, const rs2::frame &f) override
depth_frame get_depth_frame() const
GLenum GLuint GLenum GLsizei const GLchar * buf
static std::string convert(std::string const &s)
env_var(char const *name, T default_value, std::function< bool(T) > checker=nullptr)
void set(float value) override
std::atomic_bool _is_processing
algo::thermal_loop::l500::thermal_calibration_table get_thermal_table() const
rs2_intrinsics const & get_raw_intrinsics() const
static std::string _prefix(std::string const &name, unsigned id)
std::vector< uint16_t > _last_yuy_data
static std::string now_string(char const *format_string="%T")
static std::shared_ptr< T > start(ac_trigger &trigger, std::chrono::seconds n_seconds, const char *name=nullptr)
void retry(ac_trigger &trigger) override
retrier(ac_trigger &ac, char const *name)
rs2_calibration_status optimize(std::function< void(rs2_calibration_status)> call_back=nullptr)
bool should_process(const rs2::frame &frame) override
void calibration_is_done()
ac_logger(bool to_stdout=false)
static bool is_special_frame(rs2::depth_frame const &f)
std::weak_ptr< ac_trigger > _autocal
l500_depth_sensor & get_depth_sensor()
frame allocate_composite_frame(std::vector< frame > frames) const
std::shared_ptr< next_trigger > _next_trigger
static std::string get_debug_path_base()
void on_log(rs2_log_severity severity, rs2_log_message const &msg) noexceptoverride
struct rs2_log_message rs2_log_message
void cancel_current_calibration()
void schedule_next_temp_trigger()
std::shared_ptr< ac_trigger > get_ac() const
char const * get_name() const
void set_color_frame(rs2::frame const &)
float query() const override
static void write_out(std::string const &s)
bool is_streaming() const override
#define AC_LOG(TYPE, MSG)
double read_temperature()
rs2_calibration_status _last_status_sent
stream_profile_interface * get_from_profile() const
stream_profile_interface * _to_profile
librealsense::stream_profile_interface * profile
bool is_processing() const
std::string const & get_active_dir() const
void start_color_sensor_if_needed()
GLenum GLenum GLenum input
void schedule_next_time_trigger(std::chrono::seconds n_seconds=std::chrono::seconds(0))
ac_logger & get_ac_logger()
void set_special_frame(rs2::frameset const &)
const rs2_stream_profile * get() const
static bool is_auto_trigger_default()
#define RS2_API_FULL_VERSION_STR
static bool convert(std::string const &s)
rs2_intrinsics read_intrinsics_from_camera(l500_device &dev, const rs2::stream_profile &profile)
void retry(ac_trigger &trigger) override
std::weak_ptr< ac_trigger > _autocal
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
rs2_digital_gain _digital_gain
GLsizei GLsizei GLchar * source
std::vector< algo::depth_to_rgb_calibration::yuy_t > & get_last_successful_frame_data()
rs2_digital_gain
digital gain for RS2_OPTION_DIGITAL_GAIN option.
void read_fw_table(hw_monitor &hwm, int table_id, T *ptable, table_header *pheader=nullptr, std::function< void() > init=nullptr)
stream_profile_interface * get_to_profile() const
const int get_data_size() const
std::shared_ptr< retrier > _retrier
video_frame get_infrared_frame(const size_t index=0) const
void call_back(rs2_calibration_status status)
void write_data_to(std::string const &dir)
static std::chrono::seconds get_trigger_seconds()
stream_profile_interface * _from_profile
rs2_dsm_params _dsm_params
static int convert(std::string const &s)
std::weak_ptr< hw_monitor > _hwm
virtual void set(float value) override
void read_fw_register(hw_monitor &hwm, T *preg, int const baseline_address)
unsigned long long get_frame_number() const
rs2_log_severity
Severity of the librealsense logger.
std::shared_ptr< retrier > _recycler
static const int table_id
rs2_intrinsics const & get_thermal_intrinsics() const
#define AC_LOG_PREFIX_LEN
std::weak_ptr< ac_trigger > _ac
static void add_dir_sep(std::string &path)
ivcam2::extended_temperatures get_temperatures() const
virtual void set(float value) override
std::chrono::high_resolution_clock::time_point _rgb_sensor_start
rs2::frame process_frame(const rs2::frame_source &source, const rs2::frame &f) override
color_processing_block(std::shared_ptr< ac_trigger > autocal)
virtual void retry(ac_trigger &trigger)
rs2_digital_gain digital_gain
std::string to_string(T value)