Skip to content

Commit

Permalink
PR IntelRealSense#34 from Nir: refactor AC trigger and fix exception …
Browse files Browse the repository at this point in the history
…on starting depth sensor
  • Loading branch information
maloel authored Jul 21, 2020
2 parents 54acff3 + 71bdef4 commit a4c9066
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 66 deletions.
147 changes: 85 additions & 62 deletions src/l500/ac-trigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ namespace ivcam2 {

void ac_trigger::enabler_option::set( float value )
{
if( value == query() )
{
return;
}

if( value != RS2_CAH_TRIGGER_NOW )
{
// When auto trigger is on in the environment, we control the timed activation
Expand All @@ -189,13 +194,13 @@ namespace ivcam2 {
try
{
if (_autocal->_dev.get_depth_sensor().is_streaming())
_autocal->start();
_autocal->_start();

super::set(value);
}
catch (std::exception const & e)
{
AC_LOG(ERROR, "EXCEPTION caught in access to device: " << e.what());
AC_LOG(ERROR, "EXCEPTION caught during start: " << e.what());
return;
}
// else start() will get called on stream start
Expand Down Expand Up @@ -379,7 +384,7 @@ namespace ivcam2 {


/*
Temporary (?) class used to direct AC logs to either console or a special log
Temporary (?) class used to direct CAH logs to either console or a special log
If RS2_DEBUG_DIR is defined in the environment, we try to create a log file in there
that has the name "<pid>.ac_log".
Expand Down Expand Up @@ -416,7 +421,7 @@ namespace ivcam2 {

_f.open( filename );
if( _f && _to_stdout )
write_out( to_string() << "-D- AC log is being written to: " << filename );
write_out( to_string() << "-D- CAH log is being written to: " << filename );
}

if( _f || _to_stdout )
Expand Down Expand Up @@ -552,8 +557,8 @@ namespace ivcam2 {
{
if( is_active() )
{
AC_LOG( ERROR, "Failed to trigger calibration: AC is already active" );
throw wrong_api_call_sequence_exception( "AC is already active" );
AC_LOG( ERROR, "Failed to trigger calibration: CAH is already active" );
throw wrong_api_call_sequence_exception( "CAH is already active" );
}
if( _retrier.get() || _recycler.get() )
{
Expand Down Expand Up @@ -755,9 +760,9 @@ namespace ivcam2 {
"Starting processing:"
<< " color #" << _cf.get_frame_number() << " " << _cf.get_profile()
<< " depth #" << _sf.get_frame_number() << ' ' << _sf.get_profile() );
stop_color_sensor_if_started();
_is_processing = true;
_retrier.reset();
stop_color_sensor_if_started();
if( _worker.joinable() )
{
AC_LOG( DEBUG, "Waiting for worker to join ..." );
Expand Down Expand Up @@ -872,7 +877,7 @@ namespace ivcam2 {
// All the rest of the codes are not end-states of the algo, so we don't expect
// to get here!
AC_LOG( ERROR,
"Unexpected status '" << status << "' received from AC algo; stopping!" );
"Unexpected status '" << status << "' received from CAH algo; stopping!" );
call_back( RS2_CALIBRATION_FAILED );
break;
}
Expand Down Expand Up @@ -915,6 +920,8 @@ namespace ivcam2 {
stop_color_sensor_if_started();
call_back( RS2_CALIBRATION_FAILED );
reset();
_retrier.reset();
_recycler.reset();
calibration_is_done();
}
}
Expand All @@ -937,7 +944,7 @@ namespace ivcam2 {

void ac_trigger::schedule_next_calibration()
{
// Trigger the next AC -- but only if we're "on", meaning this wasn't a manual calibration
// Trigger the next CAH -- but only if we're "on", meaning this wasn't a manual calibration
if( !auto_calibration_is_on() )
{
AC_LOG( DEBUG, "Calibration mechanism is not on; not scheduling next calibration" );
Expand All @@ -948,13 +955,21 @@ namespace ivcam2 {
schedule_next_temp_trigger();
}

void ac_trigger::schedule_next_time_trigger()
void ac_trigger::schedule_next_time_trigger( std::chrono::seconds n_seconds )
{
auto n_seconds = get_trigger_seconds();
if( n_seconds.count() )
start( n_seconds );
else
AC_LOG( DEBUG, "RS2_AC_TRIGGER_SECONDS is 0; no time trigger" );
if( ! n_seconds.count() )
{
n_seconds = get_trigger_seconds();
if (!n_seconds.count())
{
AC_LOG(DEBUG, "RS2_AC_TRIGGER_SECONDS is 0; no time trigger");
return;
}
}

AC_LOG( DEBUG, "Trigger in " << n_seconds.count() << " seconds..." );
// If there's already a trigger, this will simply override it
_next_trigger = retrier::start< next_trigger >( *this, n_seconds );
}

void ac_trigger::schedule_next_temp_trigger()
Expand Down Expand Up @@ -1095,70 +1110,78 @@ namespace ivcam2 {
}
}

void ac_trigger::start( std::chrono::seconds n_seconds )
void ac_trigger::start()
{
if( is_active() )
throw wrong_api_call_sequence_exception( "CAH is already active" );

if( !n_seconds.count() )
try
{
try
{
option & o = _dev.get_depth_sensor().get_option( RS2_OPTION_TRIGGER_CAMERA_ACCURACY_HEALTH );
if( o.query() != float( RS2_CAH_TRIGGER_AUTO ) )
{
// auto trigger is turned off
AC_LOG( DEBUG, "Turned off -- no trigger set" );
return;
}
}
catch( std::exception const & e )
option & o
= _dev.get_depth_sensor().get_option( RS2_OPTION_TRIGGER_CAMERA_ACCURACY_HEALTH );
if( o.query() != float( RS2_CAH_TRIGGER_AUTO ) )
{
AC_LOG( ERROR, "EXCEPTION caught in access to device: " << e.what() );
// auto trigger is turned off
AC_LOG( DEBUG, "Turned off -- no trigger set" );
return;
}
}
catch( std::exception const & e )
{
AC_LOG( ERROR, "EXCEPTION caught in access to device: " << e.what() );
return;
}

// Check if we want auto trigger
// Note: we arbitrarly choose the time before AC starts at 10 second -- enough time to
// make sure the user isn't going to fiddle with color sensor activity too much, because
// if color is off then AC will automatically turn it on!
if( get_trigger_seconds().count() )
n_seconds = std::chrono::seconds( 10 );
else if( get_temp_diff_trigger() && (_last_temp = read_temperature()) )
_temp_check = retrier::start< temp_check >( *this, std::chrono::seconds( 60 ) );
else
{
AC_LOG( DEBUG, "Auto trigger is disabled in environment" );
return; // no auto trigger
}
_start();
}

void ac_trigger::_start()
{
if( auto_calibration_is_on() )
throw wrong_api_call_sequence_exception( "CAH is already active" );

if (!is_auto_trigger_possible())
{
AC_LOG(DEBUG, "Auto trigger is disabled in environment");
return; // no auto trigger
}

_is_on = true;
if( n_seconds.count() )

// If we are already active then we don't need to do anything: another calibration will be
// triggered automatically at the end of the current one
if (is_active())
{
AC_LOG( DEBUG, "Trigger in " << n_seconds.count() << " seconds..." );
// If there's already a trigger, this will simply override it
_next_trigger = retrier::start< next_trigger >( *this, n_seconds );
return;
}

// Note: we arbitrarily choose the time before CAH starts at 10 second -- enough time to
// make sure the user isn't going to fiddle with color sensor activity too much, because
// if color is off then CAH will automatically turn it on!
if( get_trigger_seconds().count() )
schedule_next_time_trigger( std::chrono::seconds( 10 ) );
else if( _last_temp = read_temperature() )
schedule_next_temp_trigger();
}

void ac_trigger::stop()
{
_is_on = false;
if( _next_trigger )
if (is_active())
{
AC_LOG( DEBUG, "Cancelling next calibration" );
_next_trigger.reset();
cancel_current_calibration();
}
if( is_active() )
else
{
AC_LOG( DEBUG, "Cancelling current calibration" );
set_not_active(); // now inactive!
if (_next_trigger)
{
AC_LOG(DEBUG, "Cancelling next time trigger");
_next_trigger.reset();
}

if (_temp_check)
{
AC_LOG(DEBUG, "Cancelling next temp trigger");
_temp_check.reset();
}
}
stop_color_sensor_if_started();
_temp_check.reset();
_retrier.reset();
_recycler.reset();
reset();
}

void ac_trigger::reset()
Expand Down Expand Up @@ -1212,7 +1235,7 @@ namespace ivcam2 {
rs2::frame ac_trigger::depth_processing_block::process_frame( const rs2::frame_source & source,
const rs2::frame & f )
{
// AC can be triggered manually, too, so we do NOT check whether the option is on!
// CAH can be triggered manually, too, so we do NOT check whether the option is on!

auto fs = f.as< rs2::frameset >();
if( fs )
Expand Down Expand Up @@ -1263,7 +1286,7 @@ namespace ivcam2 {

rs2::frame ac_trigger::color_processing_block::process_frame( const rs2::frame_source& source, const rs2::frame& f )
{
// AC can be triggered manually, too, so we do NOT check whether the option is on!
// CAH can be triggered manually, too, so we do NOT check whether the option is on!

// Disregard framesets: we'll get those broken down into individual frames by generic_processing_block's on_frame
if( f.is< rs2::frameset >() )
Expand Down
10 changes: 6 additions & 4 deletions src/l500/ac-trigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ namespace ivcam2 {
ac_trigger( l500_device & dev, std::shared_ptr<hw_monitor> hwm );
~ac_trigger();

// Wait a certain amount of time before the next calibration happens. Can only happen if not
// already active!
void start( std::chrono::seconds n_seconds = std::chrono::seconds(0) );
// Called when depth sensor start. Triggers a calibration in a few seconds if auto
// calibration is turned on.
void start();

// Once triggered, we may want to cancel it... like when stopping the stream
void stop();
Expand Down Expand Up @@ -198,13 +198,15 @@ namespace ivcam2 {
double read_temperature();
void calibration_is_done();
void schedule_next_calibration();
void schedule_next_time_trigger();
void schedule_next_time_trigger( std::chrono::seconds n_seconds = std::chrono::seconds( 0 ) );
void schedule_next_temp_trigger();
void cancel_current_calibration();
void set_not_active() { _n_cycles = 0; }
void trigger_retry();
void trigger_special_frame();
void check_conditions();
void _start();


std::vector< callback > _callbacks;

Expand Down

0 comments on commit a4c9066

Please sign in to comment.