Skip to content

Commit

Permalink
fix: trigger_out shall be enabled only on primary node
Browse files Browse the repository at this point in the history
  • Loading branch information
mgineer85 committed Oct 27, 2024
1 parent 1e5f5d6 commit 64cf1b2
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 15 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ On all systems edit `/boot/firmware/config.txt` as follows:
```ini
# add to all section
[all]
# disable UART because it would interfere with the clock and trigger events on GPIO14/15 detected as event in the app
enable_uart=0
# REMOVE or comment any of the following in the file:
# console=serial0,115200

# camera
# rotate=0 because camera is upside down in case
Expand All @@ -58,8 +62,6 @@ dtparam=audio=off # because GPIO18 interferes with audio
dtoverlay=pwm,pin=18,func=2 # GPIO18 reserved for hardware pwm


#

# shutdown button signal
# TODO
```
Expand Down
2 changes: 1 addition & 1 deletion node/services/backends/io/abstractbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def derive_nominal_framerate_from_clock(self) -> int:
pass

@abstractmethod
def trigger(self, on: bool):
def set_trigger_out(self, on: bool):
# forward to output trigger
pass

Expand Down
17 changes: 11 additions & 6 deletions node/services/backends/io/gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ def __init__(self, config: ConfigBackendGpio):
def start(self):
super().start()

if self._config.enable_clock:
if self._config.is_primary:
logger.info("loading primary clockwork service")
self._set_hardware_clock(enable=True)
logger.info("generating clock using hardware pwm overlay")

self._trigger_out = DigitalOutputDevice(pin=self._config.trigger_out_pin_name, initial_value=False, active_high=True)
logger.info(f"forward trigger_out on {self._trigger_out}")
else:
logger.info("skipped loading primary clockwork service because disabled in config")

self._trigger_out = DigitalOutputDevice(pin=self._config.trigger_out_pin_name, initial_value=False, active_high=True)
logger.info(f"forward trigger_out on {self._trigger_out}")
logger.info("skipped enabling trigger_out because disabled in config, trigger out should be enabled on primary node usually only.")

self._gpio_thread = Thread(name="_gpio_thread", target=self._gpio_fun, args=(), daemon=True)
self._gpio_thread.start()
Expand All @@ -53,7 +54,7 @@ def start(self):
def stop(self):
super().stop()

if self._config.enable_clock:
if self._config.is_primary:
self._set_hardware_clock(enable=False)

if self._trigger_out:
Expand Down Expand Up @@ -82,7 +83,11 @@ def derive_nominal_framerate_from_clock(self) -> int:

return fps

def trigger(self, on: bool):
def set_trigger_out(self, on: bool):
if not self._trigger_out:
logger.debug("trigger requested to forward on this device but disabled in config!")
return

if on:
self._trigger_out.on()
else:
Expand Down
3 changes: 2 additions & 1 deletion node/services/backends/io/virtualio.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def stop(self):
def derive_nominal_framerate_from_clock(self) -> int:
return self._config.fps_nominal

def trigger(self, on: bool):
def set_trigger_out(self, on: bool):
# trigger out is forwarded in virtual mode directly to trigger in again
if on:
self._on_trigger_in()

Expand Down
6 changes: 3 additions & 3 deletions node/services/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ class ConfigBackendVirtualIo(BaseModel):


class ConfigBackendGpio(BaseModel):
chip: str = Field(default="/dev/gpiochip0")
clock_in_pin_name: str = Field(default="GPIO14")
trigger_in_pin_name: str = Field(default="GPIO15")
trigger_out_pin_name: str = Field(default="GPIO17")

enable_clock: bool = Field(default=False)
is_primary: bool = Field(default=False)
fps_nominal: int = Field(default=9) # needs to be lower than cameras mode max fps to allow for control reserve
chip: str = Field(default="/dev/gpiochip0")
pwmchip: str = Field(default="pwmchip2") # pi5: pwmchip2, other pwmchip0
pwm_channel: int = Field(default=2) # pi5: 2, other 0
trigger_out_pin_name: str = Field(default="GPIO17")


class ConfigBackendVirtualCamera(BaseModel):
Expand Down
5 changes: 3 additions & 2 deletions node/services/sync_acquisition_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,18 @@ def _trigger_fun(self):
if self._flag_execute_job.wait(timeout=1):
# first clear to avoid endless loops
self._flag_execute_job.clear()
logger.info("executing job")
# timeout=anything so it doesnt block shutdown. If flag is set during timeout it will be catched during next run and is not lost
# there is a job that shall be processed, now wait until we get a falling clock
# timeout not None (to avoid blocking) but longer than any frame could ever take
self._gpio_backend.wait_for_clock_fall_signal(timeout=1)
# clock is fallen, this is the sync point to send out trigger to other clients. chosen to send on falling clock because capture
# shall be on rising clock and this is with 1/2 frame distance far enough that all clients can prepare to capture
self._gpio_backend.trigger(True) # clients detect rising edge on trigger_in and invoke capture.
self._gpio_backend.set_trigger_out(True) # clients detect rising edge on trigger_in and invoke capture.
# now we wait until next falling clock and turn off the trigger
# timeout not None (to avoid blocking) but longer than any frame could ever take
self._gpio_backend.wait_for_clock_fall_signal(timeout=1)
self._gpio_backend.trigger(False)
self._gpio_backend.set_trigger_out(False)
# done, restart waiting for flag...
else:
pass
Expand Down

0 comments on commit 64cf1b2

Please sign in to comment.