Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions .github/workflows/emulator-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ jobs:
run: |
mkdir -p /tmp/ci_milk_shm /tmp/ci_fits_test

bin/emulator config/frame_outputs_test/frame_outputs_test.cfg -i generic &
bin/camerad-emulator config/frame_outputs_test/frame_outputs_test.cfg -i generic &
sleep 2
bin/camerad --foreground --config config/frame_outputs_test/frame_outputs_test.cfg &
sleep 3

send() { bin/socksend -p 3131 -t 60 "$1"; }
send() { bin/camerad-socksend -p 3131 -t 60 "$1"; }

send "open"
send "load"
Expand All @@ -74,11 +74,11 @@ jobs:
# succeeded -- shm_reader's exit code and the FITS file's existence
# are the real pass/fail signal
sleep 1
bin/shm_reader ci_frame_outputs_shm /tmp/ci_milk_shm
bin/camerad-shm-reader ci_frame_outputs_shm /tmp/ci_milk_shm
ls /tmp/ci_fits_test/ci_frame_outputs_*.fits

pkill -f 'bin/camerad' || true
pkill -f 'bin/emulator' || true
pkill -f 'bin/camerad-emulator' || true

python-module-emulator-test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -119,20 +119,20 @@ jobs:
sudo make install
sudo ldconfig

- name: Build the Python module and emulator
- name: Build everything
run: |
mkdir -p ${{github.workspace}}/build
cd ${{github.workspace}}/build
cmake -DCONTROLLER=archon -DINSTRUMENT=hispec_tracking_camera \
-DENABLE_SHM_OUTPUT=ON -DImageStreamIO_DIR=/usr/local/lib/cmake \
-DBUILD_PYTHON_MODULE=ON ..
make camera_interface emulator -j$(nproc)
make -j$(nproc)

- name: Python module control test
run: |
mkdir -p /tmp/ci_milk_shm /tmp/ci_fits_test

bin/emulator config/frame_outputs_test/frame_outputs_test.cfg -i generic &
bin/camerad-emulator config/frame_outputs_test/frame_outputs_test.cfg -i generic &
sleep 2

# No camerad process here: the module owns the Archon connection, and
Expand All @@ -141,7 +141,25 @@ jobs:
--config config/frame_outputs_test/frame_outputs_test.cfg \
--fits-dir /tmp/ci_fits_test

pkill -f 'bin/emulator' || true
pkill -f 'bin/camerad-emulator' || true

- name: Install to a prefix and verify
run: |
cmake --install build --prefix /tmp/camerad-prefix

for tool in camerad camerad-socksend camerad-emulator camerad-shm-reader; do
test -x "/tmp/camerad-prefix/bin/$tool" || { echo "not installed: $tool"; exit 1; }
done

# Run from /tmp so the build tree cannot satisfy the import and mask a
# missing install rule
cd /tmp
PYTHONPATH=/tmp/camerad-prefix/lib python3 - <<'PY'
import camera_interface as ci
assert ci.__file__.startswith("/tmp/camerad-prefix/lib/"), ci.__file__
assert ci.instrument_name() == "hispec_tracking_camera", ci.instrument_name()
print("imported", ci.__file__)
PY

cryoscope-emulator-test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -179,12 +197,12 @@ jobs:

- name: CryoScope synthetic test
run: |
bin/emulator config/cryoscope/cryoscope.cfg -i generic &
bin/camerad-emulator config/cryoscope/cryoscope.cfg -i generic &
sleep 2
bin/camerad --foreground --config config/cryoscope/cryoscope.cfg &
sleep 3

send() { bin/socksend -p 3031 -t 60 "$1"; }
send() { bin/camerad-socksend -p 3031 -t 60 "$1"; }

send "open"
send "load"
Expand All @@ -195,20 +213,20 @@ jobs:
echo "$resp" | grep -q "DONE" || exit 1

pkill -f 'bin/camerad' || true
pkill -f 'bin/emulator' || true
pkill -f 'bin/camerad-emulator' || true
sleep 1

- name: CryoScope FITS playback test
run: |
cp config/cryoscope/cryoscope.cfg /tmp/cryoscope_fits_test.cfg
echo "EMULATOR_DATADIR=config/cryoscope" >> /tmp/cryoscope_fits_test.cfg

bin/emulator /tmp/cryoscope_fits_test.cfg -i generic &
bin/camerad-emulator /tmp/cryoscope_fits_test.cfg -i generic &
sleep 2
bin/camerad --foreground --config /tmp/cryoscope_fits_test.cfg &
sleep 3

send() { bin/socksend -p 3031 -t 60 "$1"; }
send() { bin/camerad-socksend -p 3031 -t 60 "$1"; }

send "open"
send "load"
Expand All @@ -220,4 +238,4 @@ jobs:
echo "$resp" | grep -q "DONE" || exit 1

pkill -f 'bin/camerad' || true
pkill -f 'bin/emulator' || true
pkill -f 'bin/camerad-emulator' || true
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_BASE_DIR}/lib)
find_package(Threads)
find_package(nlohmann_json REQUIRED)

include(GNUInstallDirs)

# Declared here so the static libs get PIC, which ELF needs for a shared module
option(BUILD_PYTHON_MODULE "Build the camera_interface Python module" OFF)
if (BUILD_PYTHON_MODULE)
Expand Down
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,37 @@ If you encounter any problems or have questions about this project, please open
$ make
```

5. **Run the Camera Server:**
5. **(Optional) Install:** `make install` copies what the build produced under
`${CMAKE_INSTALL_PREFIX}`, which defaults to `/usr/local`:

```bash
$ cmake -DCONTROLLER=archon -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
$ make && make install
```

| Artifact | Installed to | Built when |
|----------------------|--------------|--------------------------|
| `camerad` | `bin` | always |
| `camerad-socksend` | `bin` | always |
| `camerad-emulator` | `bin` | `-DINTERFACE_TYPE=Archon` (the default) |
| `camerad-shm-reader` | `bin` | `-DENABLE_SHM_OUTPUT=ON` |
| `camera_interface` | `lib` | `-DBUILD_PYTHON_MODULE=ON` |

The tools carry a `camerad-` prefix because names like `socksend` are too
generic for a directory shared with every other package.

The Python module installs to `lib`, so importing it means putting that
directory on `PYTHONPATH`:

```bash
$ PYTHONPATH=$HOME/.local/lib python3 -c "import camera_interface"
```

Without installing, the binaries are only ever run from `bin/` in the source
tree, so a rebuild replaces whatever is deployed and there is no way to keep
two versions or to tell which one is running.

6. **Run the Camera Server:**

The configuration file is passed with `--config` and is required.

Expand All @@ -102,15 +132,15 @@ If you encounter any problems or have questions about this project, please open

Logging always goes to a daily file under `LOGPATH`. Whether it is also written to stderr follows `--foreground`, so an operator watching a console sees it and a daemon does not duplicate its whole log into the stderr redirect. `LOG_STDERR` in the `.cfg` overrides that either way.

6. **(Optional) Run the Archon Emulator:**
7. **(Optional) Run the Archon Emulator:**

```bash
$ ../bin/emulator <file.cfg> -i <instrument>
$ ../bin/camerad-emulator <file.cfg> -i <instrument>
```

The emulator reads `EMULATOR_PORT` and `EMULATOR_SYSTEM` from the same `.cfg` the server uses, so point `ARCHON_IP`/`ARCHON_PORT` at it to run without hardware. `-i generic` suits the shipped test configs.

7. **(Optional) Run Unit Tests.** The tests are excluded from the default target, so build them first:
8. **(Optional) Run Unit Tests.** The tests are excluded from the default target, so build them first:

```bash
$ make run_unit_tests
Expand Down
2 changes: 2 additions & 0 deletions camerad/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ target_link_libraries(camerad
${ZMQ_LIB}
)

install(TARGETS camerad RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

# ----------------------------------------------------------------------------
# optional Python module
# ----------------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions emulator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ target_link_libraries(emulator
)
target_include_directories(emulator PRIVATE ${CFITSIO_INCLUDE_DIRS})
target_link_directories(emulator PRIVATE ${CFITSIO_LIBRARY_DIRS})

# Prefixed because "emulator" is too generic for a shared bin directory
set_target_properties(emulator PROPERTIES OUTPUT_NAME camerad-emulator)

install(TARGETS emulator RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
elseif( ${INTERFACE_TYPE} STREQUAL "AstroCam" )
message( STATUS "emulator not implemented for AstroCam" )
else()
Expand Down
2 changes: 2 additions & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ target_link_libraries(camera_interface PRIVATE
${ZMQPP_LIB}
${ZMQ_LIB}
)

install(TARGETS camera_interface LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
9 changes: 9 additions & 0 deletions utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@ add_executable(listener
add_executable(socksend
${PROJECT_UTILS_DIR}/sendcmd.cpp
)

# Prefixed because these names are too generic for a shared bin directory
set_target_properties(socksend PROPERTIES OUTPUT_NAME camerad-socksend)

install(TARGETS socksend RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if (ENABLE_SHM_OUTPUT)
set_target_properties(shm_reader PROPERTIES OUTPUT_NAME camerad-shm-reader)
install(TARGETS shm_reader RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
Loading