Skip to content

Commit 527fe81

Browse files
cfremlingclaude
andcommitted
Add acquisition automation modes and fine-tune pipeline
Properly rebased against main, preserving all existing functionality (can_expose wait, channel activate/deactivate, camerad ZMQ handler). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8597f3c commit 527fe81

19 files changed

Lines changed: 5074 additions & 44 deletions

Config/sequencerd.cfg.in

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ CALIB_DOOR__SHUTDOWN=close
107107
# Virtual Slit Mode slit offset positions
108108
# units are arcseconds
109109
#
110-
VIRTUAL_SLITW_ACQUIRE=0.5 # slit width during acquire
110+
VIRTUAL_SLITW_ACQUIRE=0.4 # slit width during acquire
111111
VIRTUAL_SLITO_ACQUIRE=-3.0 # slit offset for acquiring target
112112
VIRTUAL_SLITO_EXPOSE=3.0 # slit offset for science exposure
113113

@@ -155,11 +155,15 @@ TCS_PREAUTH_TIME=10 # seconds before end of exposure to notify
155155

156156
# ACAM Target acquisition
157157
#
158-
ACQUIRE_TIMEOUT=90 # seconds before ACAM acquisition sequence aborts on failure to acquire (REQUIRED!)
158+
ACQUIRE_TIMEOUT=120 # seconds before ACAM acquisition sequence aborts on failure to acquire (REQUIRED!)
159159
ACQUIRE_RETRYS=5 # max number of retrys before acquisition fails (optional, can be left blank to disable)
160160
ACQUIRE_OFFSET_THRESHOLD=0.5 # computed offset below this threshold (in arcsec) defines successful acquisition
161161
ACQUIRE_MIN_REPEAT=2 # minimum number of sequential successful acquires
162162
ACQUIRE_TCS_MAX_OFFSET=60 # the maximum allowable offset sent to the TCS, in arcsec
163+
ACQ_AUTOMATIC_MODE=1 # 1=legacy, 2=semi-auto, 3=auto
164+
ACQ_FINE_TUNE_CMD=ngps_acq # command to run after guiding for final fine tune
165+
ACQ_FINE_TUNE_LOG=1 # log fine tune output to /data/<datedir>/logs/ngps_acq_<datedir>.log (0/1)
166+
ACQ_OFFSET_SETTLE=3 # seconds to wait after automatic offset
163167

164168
# Calibration Settings
165169
# CAL_TARGET=(name caldoor calcover U G R I lampthar lampfear lampbluc lampredc lolamp hilamp mod1 mod2 ... mod6)

Config/slicecamd.cfg.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ SUB_ENDPOINT="tcp://127.0.0.1:@MESSAGE_BROKER_PUB_PORT@"
2222
#
2323
TCSD_PORT=@TCSD_BLK_PORT@
2424
ACAMD_PORT=@ACAMD_BLK_PORT@
25+
# AUTOACQ_ARGS defines defaults for slicecamd in-process ngps_acq.
26+
# This line intentionally includes all supported ngps_acq options.
27+
AUTOACQ_ARGS="--frame-mode stream --input /tmp/slicecam.fits --goal-x 150.0 --goal-y 115.5 --bg-x1 80 --bg-x2 165 --bg-y1 30 --bg-y2 210 --pixel-origin 1 --max-dist 40 --snr 3 --min-adj 4 --centroid-hw 4 --centroid-sigma 1.2 --loop 1 --cadence-sec 4 --prec-arcsec 0.4 --goal-arcsec 0.3 --gain 1.0 --dry-run 0 --tcs-set-units 0 --verbose 1 --debug 1 --use-putonslit 1 --adaptive 1 --adaptive-bright 40000 --adaptive-bright-goal 10000"
2528

2629
# ANDOR=( <name> [emulate] <sn> <scale> <hflip> <vflip> <rot> <temp> <hbin> <vbin> )
2730
# For each slice camera specify:

acamd/acam_interface.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,11 @@ namespace Acam {
14531453
this->motion.get_current_coverpos() :
14541454
"not_connected" );
14551455

1456+
std::string mode = this->target.acquire_mode_string();
1457+
jmessage_out["ACAM_ACQUIRE_MODE"] = mode;
1458+
jmessage_out["ACAM_GUIDING"] = ( mode == "guiding" );
1459+
jmessage_out["ACAM_ACQUIRING"] = ( mode == "acquiring" );
1460+
14561461
try {
14571462
this->publisher->publish( jmessage_out );
14581463
}
@@ -5522,12 +5527,8 @@ logwrite( function, message.str() );
55225527
retstring = message.str();
55235528

55245529
if ( this->target.acquire_mode == Acam::TARGET_GUIDE ) {
5525-
this->target.acquire_mode = Acam::TARGET_ACQUIRE;
5526-
this->target.nacquired = 0;
5527-
this->target.attempts = 0;
5528-
this->target.sequential_failures = 0;
5529-
this->target.timeout_time = std::chrono::steady_clock::now()
5530-
+ std::chrono::duration<double>(this->target.timeout);
5530+
// Keep GUIDE mode; just reset filtering so the new goal takes effect quickly.
5531+
this->target.reset_offset_params();
55315532
}
55325533

55335534
return NO_ERROR;

common/message_keys.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Topic {
1414
inline const std::string TARGETINFO = "tcsd";
1515
inline const std::string SLITD = "slitd";
1616
inline const std::string CAMERAD = "camerad";
17+
inline const std::string SEQ_PROGRESS = "seq_progress";
1718
}
1819

1920
namespace Key {
@@ -23,4 +24,16 @@ namespace Key {
2324
namespace Camerad {
2425
inline const std::string READY = "ready";
2526
}
27+
28+
namespace SeqProgress {
29+
inline const std::string ONTARGET = "ontarget";
30+
inline const std::string FINE_TUNE_ACTIVE = "fine_tune_active";
31+
inline const std::string OFFSET_ACTIVE = "offset_active";
32+
inline const std::string OFFSET_SETTLE = "offset_settle";
33+
inline const std::string OFFSET_RA = "offset_ra";
34+
inline const std::string OFFSET_DEC = "offset_dec";
35+
inline const std::string OBSID = "obsid";
36+
inline const std::string TARGET_STATE = "target_state";
37+
inline const std::string EVENT = "event";
38+
}
2639
}

common/ngps_acq_embed.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @file ngps_acq_embed.h
3+
* @brief in-process API for NGPS auto-acquire logic
4+
*/
5+
6+
#pragma once
7+
8+
#include <stddef.h>
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
typedef struct ngps_acq_hooks {
15+
void *user;
16+
17+
int (*tcs_set_native_units)( void *user, int dry_run, int verbose );
18+
int (*tcs_move_arcsec)( void *user, double dra_arcsec, double ddec_arcsec,
19+
int dry_run, int verbose );
20+
int (*scam_putonslit_deg)( void *user,
21+
double slit_ra_deg, double slit_dec_deg,
22+
double cross_ra_deg, double cross_dec_deg,
23+
int dry_run, int verbose );
24+
int (*acam_query_state)( void *user, char *state, size_t state_sz, int verbose );
25+
int (*scam_framegrab_one)( void *user, const char *outpath, int verbose );
26+
int (*scam_set_exptime)( void *user, double exptime_sec, int dry_run, int verbose );
27+
int (*scam_set_avgframes)( void *user, int avgframes, int dry_run, int verbose );
28+
int (*is_stop_requested)( void *user );
29+
void (*log_message)( void *user, const char *line );
30+
} ngps_acq_hooks_t;
31+
32+
void ngps_acq_set_hooks( const ngps_acq_hooks_t *hooks );
33+
void ngps_acq_clear_hooks( void );
34+
void ngps_acq_request_stop( int stop_requested );
35+
int ngps_acq_run_from_argv( int argc, char **argv );
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif

common/sequencerd_commands.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifndef SEQEUNCERD_COMMANDS_H
99
#define SEQEUNCERD_COMMANDS_H
1010
const std::string SEQUENCERD_ABORT = "abort";
11+
const std::string SEQUENCERD_ACQMODE = "acqmode";
1112
const std::string SEQUENCERD_CONFIG = "config";
1213
const std::string SEQUENCERD_DOTYPE = "do";
1314
const std::string SEQUENCERD_EXIT = "exit";
@@ -47,6 +48,7 @@ const std::vector<std::string> SEQUENCERD_SYNTAX = {
4748
SEQUENCERD_TCS+" ...",
4849
"",
4950
SEQUENCERD_ABORT,
51+
SEQUENCERD_ACQMODE+" [ ? | <mode> ]",
5052
SEQUENCERD_CONFIG,
5153
SEQUENCERD_DOTYPE+" [ one | all ]",
5254
SEQUENCERD_EXIT,

common/slicecamd_commands.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma once
1111

1212
const std::string SLICECAMD_AVGFRAMES= "avgframes"; ///< set/get camera binning
13+
const std::string SLICECAMD_AUTOACQ = "autoacq"; ///< run/monitor in-process auto-acquire logic
1314
const std::string SLICECAMD_BIN = "bin"; ///< set/get camera binning
1415
const std::string SLICECAMD_CLOSE = "close"; ///< *** close connection to all devices
1516
const std::string SLICECAMD_CONFIG = "config"; ///< reload configuration, apply what can be applied
@@ -69,6 +70,7 @@ const std::vector<std::string> SLICECAMD_SYNTAX = {
6970
SLICECAMD_SPEED+" [ ? | <hori> <vert> ]",
7071
SLICECAMD_TEMP+" [ ? | <setpoint> ]",
7172
" OTHER:",
73+
SLICECAMD_AUTOACQ+" [ ? | start [--log-file <path>] [<args>] | stop | status ]",
7274
SLICECAMD_PUTONSLIT+" [ ? | <slitra> <slitdec> <crossra> <crossdec> ]",
7375
SLICECAMD_SAVEFRAMES+" [ ? | <nsave> <nskip> ]",
7476
SLICECAMD_SHUTDOWN+" [ ? ]",

run/seq-progress

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
#
3+
# Launch the sequencer progress popup GUI
4+
#
5+
6+
SCRIPT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)"
7+
export NGPS_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
8+
9+
CONFIG="${NGPS_ROOT}/Config/sequencerd.cfg"
10+
exec "${NGPS_ROOT}/bin/seq_progress_gui" --config "${CONFIG}" --poll-ms 10000

0 commit comments

Comments
 (0)