Skip to content

Commit a48136b

Browse files
committed
fix socksend and use socksend in github workflow, add UTR_RR mode
1 parent e18bf10 commit a48136b

7 files changed

Lines changed: 63 additions & 68 deletions

File tree

.github/workflows/emulator-integration.yml

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
mkdir -p ${{github.workspace}}/build
4040
cd ${{github.workspace}}/build
4141
cmake -DCONTROLLER=archon -DINSTR=hispec_tracking_camera -DDETECTOR_TYPE=Hxrg ..
42-
make camerad emulator -j$(nproc)
42+
make camerad emulator socksend -j$(nproc)
4343
4444
- name: CryoScope synthetic test
4545
run: |
@@ -48,38 +48,16 @@ jobs:
4848
bin/camerad --foreground --config Config/cryoscope/cryoscope.cfg &
4949
sleep 3
5050
51-
python3 << 'EOF'
52-
import socket, sys
51+
send() { bin/socksend -p 3031 -t 60 "$1"; }
5352
54-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
55-
s.settimeout(120)
56-
s.connect(('localhost', 3031))
57-
58-
def cmd(c):
59-
s.sendall((c + '\n').encode())
60-
data = b''
61-
while True:
62-
try:
63-
chunk = s.recv(4096)
64-
if not chunk: break
65-
data += chunk
66-
if b'\n' in data: break
67-
except socket.timeout:
68-
break
69-
return data.decode().strip()
70-
71-
failed = False
72-
for c in ['open', 'load', 'power on', 'mode VIDEORXR', 'exptime 0.1',
73-
'exposuremode SINGLE', 'expose 1']:
74-
resp = cmd(c)
75-
status = 'OK' if 'DONE' in resp else 'FAIL'
76-
print(f' {status}: {c} -> {resp}')
77-
if status == 'FAIL':
78-
failed = True
79-
80-
s.close()
81-
sys.exit(1 if failed else 0)
82-
EOF
53+
send "open"
54+
send "load"
55+
send "power on"
56+
send "mode VIDEORXR"
57+
send "exptime 0.1"
58+
resp=$(send "expose 1")
59+
echo "expose -> $resp"
60+
echo "$resp" | grep -q "DONE" || exit 1
8361
8462
pkill -f 'bin/camerad' || true
8563
pkill -f 'bin/emulator' || true
@@ -95,38 +73,16 @@ jobs:
9573
bin/camerad --foreground --config /tmp/cryoscope_fits_test.cfg &
9674
sleep 3
9775
98-
python3 << 'EOF'
99-
import socket, sys
100-
101-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
102-
s.settimeout(120)
103-
s.connect(('localhost', 3031))
104-
105-
def cmd(c):
106-
s.sendall((c + '\n').encode())
107-
data = b''
108-
while True:
109-
try:
110-
chunk = s.recv(4096)
111-
if not chunk: break
112-
data += chunk
113-
if b'\n' in data: break
114-
except socket.timeout:
115-
break
116-
return data.decode().strip()
117-
118-
failed = False
119-
for c in ['open', 'load', 'power on', 'mode VIDEORXR', 'exptime 0.1',
120-
'exposuremode SINGLE', 'expose 1']:
121-
resp = cmd(c)
122-
status = 'OK' if 'DONE' in resp else 'FAIL'
123-
print(f' {status}: {c} -> {resp}')
124-
if status == 'FAIL':
125-
failed = True
76+
send() { bin/socksend -p 3031 -t 60 "$1"; }
12677
127-
s.close()
128-
sys.exit(1 if failed else 0)
129-
EOF
78+
send "open"
79+
send "load"
80+
send "power on"
81+
send "mode VIDEORXR"
82+
send "exptime 0.1"
83+
resp=$(send "expose 1")
84+
echo "expose -> $resp"
85+
echo "$resp" | grep -q "DONE" || exit 1
13086
13187
pkill -f 'bin/camerad' || true
13288
pkill -f 'bin/emulator' || true

camerad/archon_exposure_modes.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ namespace Camera {
2121
constexpr const char* RAW = "RAW";
2222
constexpr const char* SINGLE = "SINGLE";
2323
constexpr const char* RXRV = "RXRV";
24-
constexpr const char* ALLMODES[] = {RAW, SINGLE, RXRV};
24+
constexpr const char* UTR_RR = "UTR_RR";
25+
constexpr const char* ALLMODES[] = {RAW, SINGLE, RXRV, UTR_RR};
2526
};
2627

2728
/** @struct ArchonImageBuffer
@@ -79,6 +80,15 @@ namespace Camera {
7980
/***** Camera::ExposureModeSingle *******************************************/
8081

8182

83+
// UTR with Rolling Reset — behaves like SINGLE for now, multi-sample logic TBD
84+
class ExposureModeUtrRR : public ExposureModeSingle {
85+
public:
86+
ExposureModeUtrRR(Camera::ArchonInterface* iface)
87+
: ExposureModeSingle(iface) {
88+
type=ArchonExposureMode::UTR_RR;
89+
}
90+
};
91+
8292
class ExposureModeRXRV : public ArchonImageBuffer, public ExposureModeTemplate<Camera::ArchonInterface> {
8393
public:
8494
ExposureModeRXRV(Camera::ArchonInterface* iface)

camerad/archon_interface.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,10 @@ namespace Camera {
552552
if (caseCompareString(modein, ArchonExposureMode::RXRV)) {
553553
this->exposuremode = std::make_shared<ExposureModeRXRV>(this);
554554
}
555+
else
556+
if (caseCompareString(modein, ArchonExposureMode::UTR_RR)) {
557+
this->exposuremode = std::make_shared<ExposureModeUtrRR>(this);
558+
}
555559
else {
556560
logwrite("Camera::ArchonInterface::set_exposure_mode",
557561
"ERROR unrecognized exposure mode \""+modein+"\"");
@@ -804,6 +808,12 @@ namespace Camera {
804808
// if we made it all the way to the end then this is the selected mode
805809
this->controller->selectedmode = modeselect;
806810

811+
// Set the exposure mode to match the camera mode name if recognized
812+
if (this->set_exposure_mode(modeselect, {}) != NO_ERROR) {
813+
// Fall back to SINGLE if the camera mode name doesn't match an exposure mode
814+
this->set_exposure_mode(std::string(ArchonExposureMode::SINGLE), {});
815+
}
816+
807817
return NO_ERROR;
808818
}
809819
/***** Camera::ArchonInterface::set_camera_mode *****************************/

camerad/camera_server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ namespace Camera {
126126
* @param[in] sock Network::TcpSocket socket object
127127
*
128128
*/
129-
void Server::doit( Network::TcpSocket sock ) {
129+
void Server::doit( Network::TcpSocket &sock ) {
130130
const std::string function("Camera::Server::doit");
131131
std::stringstream message;
132132
std::string cmd, args;

camerad/camera_server.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace Camera {
4242
void configure_server();
4343
void exit_cleanly();
4444
void block_main(std::shared_ptr<Network::TcpSocket> socket);
45-
void doit(Network::TcpSocket sock);
45+
void doit(Network::TcpSocket &sock);
4646
};
4747
}
4848

utils/network.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,9 @@ namespace Network {
595595
message.str(""); message << ( revents & POLLHUP ? "POLLHUP " : "" )
596596
<< ( revents & POLLERR ? "POLLERR " : "" )
597597
<< ( revents & POLLNVAL ? "POLLNVAL " : "" )
598-
<< "recevied: closing socket " << this->host << "/" << this->port << " on fd " << this->fd;
598+
<< "on socket " << this->host << "/" << this->port << " fd " << this->fd;
599599
logwrite( function, message.str() );
600-
this->Close();
600+
return -1;
601601
}
602602

603603
return( ret );

utils/sendcmd.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
#include <fcntl.h>
3+
#include <poll.h>
34
#include <sys/types.h>
45
#include <sys/socket.h>
56
#include <sys/time.h>
@@ -85,6 +86,24 @@ int main(int argc, char *argv[]) {
8586
return -errno;
8687
}
8788

89+
// Wait for non-blocking connect to complete
90+
struct pollfd pfd = { sock, POLLOUT, 0 };
91+
int pret = poll(&pfd, 1, timeout * 1000);
92+
if ( pret <= 0 ) {
93+
std::cerr << "ERROR connect timeout: " << std::strerror(errno) << "\n";
94+
close(sock);
95+
return -ETIME;
96+
}
97+
// Verify the connection actually succeeded
98+
int sockerr = 0;
99+
socklen_t errlen = sizeof(sockerr);
100+
getsockopt(sock, SOL_SOCKET, SO_ERROR, &sockerr, &errlen);
101+
if ( sockerr != 0 ) {
102+
std::cerr << "ERROR connecting: " << std::strerror(sockerr) << "\n";
103+
close(sock);
104+
return -sockerr;
105+
}
106+
88107
message += "\n";
89108

90109
while ( ( nread = write( sock, message.c_str(), message.size() ) ) < 0 ) {

0 commit comments

Comments
 (0)