Skip to content

Triggering GigEVision cameras with action commands

Thies Möller edited this page Dec 12, 2022 · 2 revisions

Basler cameras can be triggered via hardware or software

Among the software trigger sources, Basler GigEVision cameras support action commands. These are specifically crafted, broadcasted network packets that can directly trigger one or multiple cameras.

The details are described in the section about action commands in the Basler Product Documentation.

To use this functionality gst-plugin-pylon version has to be >= 0.5.0

Set up a triggered gstreamer pipeline

On which action command the camera will react has to be set up.

This pipeline will start pylonsrc to start a new frame on every received action command with these parameters:

  • ActionDeviceKey 0x1234
  • ActionGroupKey 0x1
  • ActionGroupMask 0x1
gst-launch-1.0 pylonsrc \
		cam::TriggerMode-FrameStart=On \
		cam::TriggerSource-FrameStart=Action1 \
		cam::ActionDeviceKey=0x1234 \
		cam::ActionGroupKey=0x1 \
		cam::ActionGroupMask=0x1 \
		! autovideosink

Generate Action Commands

Currently, pylonsrc has no capability to generate action commands.

The easiest option to generate action commands is by using pypylon the python binding to the Basler pylon SDK. On most platforms a pip3 install pypylon should work.

The following script ( trigger_action_cmd.py ) will generate single or repeated action commands and will optionally wait for a device acknowledge

#! /usr/bin/python
import argparse
import pypylon.pylon as py
import time

tl_factory = py.TlFactory.GetInstance()

# get the gige transport layer to access action_command routines
gige_tl = tl_factory.CreateTl("BaslerGigE")


def send_action_cmd(
   action_key: int,
   action_group_key: int,
   action_group_mask: int,
   wait_for_n_ack: int = 0,
   timeout_ms: int = 1000,
):

   # possible results for issuing an action command
   act_cmd_status_strings = {
       py.GigEActionCommandStatus_Ok: "The device acknowledged the command",
       py.GigEActionCommandStatus_NoRefTime: "The device is not synchronized to a master clock",
       py.GigEActionCommandStatus_Overflow: "The action commands queue is full",
       py.GigEActionCommandStatus_ActionLate: "The requested action time was at a point in time that is in the past",
   }

   # Using default value of "255.255.255.255" for fourth
   # parameter 'broadcastAddress'.
   act_cmd = gige_tl.ActionCommand(action_key, action_group_key, action_group_mask)

   if wait_for_n_ack > 0:
       # use waiting variant on even counter
       # wait_for_n_ack == number of cameras that should return with an ack
       ok, results = act_cmd.IssueWait(timeout_ms, wait_for_n_ack)
       result_info = []
       for ip_addr, status in results:
           result_info.append((ip_addr, act_cmd_status_strings[status]))

       return ok, results

   else:
       ok = act_cmd.IssueNoWait()
       return ok, []


if __name__ == "__main__":
   parser = argparse.ArgumentParser(
       prog="trigger_via_action_cmd",
       description="Send trigger signals via action command",
   )

   parser.add_argument(
       "ActionDeviceKey",
       type=lambda x: int(x, 0),
       help="The application device key that allows the device to check the validity of action commands.",
   )
   parser.add_argument(
       "ActionGroupKey",
       type=lambda x: int(x, 0),
       help="The group key to transfer with the action command.",
   )
   parser.add_argument(
       "ActionGroupMask",
       type=lambda x: int(x, 0),
       help="The group bit mask to transfer with the action command.",
   )
   parser.add_argument(
       "-r",
       "--repeat_ms",
       type=int,
       help="Repeat trigger every repeat_ms.",
       dest="repeat_ms",
   )
   parser.add_argument(
       "-a",
       "--ack_count",
       type=int,
       help="Number of acknowledges to wait for. If the trigger will reach e.g. 5 cameras -> --ack_count 5",
       dest="ack_count",
       default=0,
   )
   args = parser.parse_args()

   if args.repeat_ms is None:
       ok, results = send_action_cmd(
           args.ActionDeviceKey,
           args.ActionGroupKey,
           args.ActionGroupMask,
           args.ack_count,
       )
       print(f"Success: {ok}")
       for r in results:
           print(r)
   else:
       print(f"Repeat sending trigger every {args.repeat_ms}ms\nabort with ^C")
       while True:
           ok, results = send_action_cmd(
               args.ActionDeviceKey,
               args.ActionGroupKey,
               args.ActionGroupMask,
               args.ack_count,
           )
           print(f"Success: {ok}")
           for r in results:
               print(r)
           time.sleep(args.repeat_ms * 1e-3)

To trigger the pipeline that has been launched in the section above

python trigger_via_action_cmd.py 0x1234 0x1 0x1 -r 1000 -a 1

Send an action command with

  • ActionDeviceKey 0x1234
  • ActionGroupKey 0x1
  • ActionGroupMask 0x1

every 1000ms and wait after each action command for an ACK message from one camera