[ros-users] Patch Prosilica Camera Drivers

Top Page
Attachments:
Message as email
+ (text/plain)
+ prosilica_camera.patch (text/x-patch)
Delete this message
Reply to this message
Author: User discussions
Date:  
To: ros-users
Subject: [ros-users] Patch Prosilica Camera Drivers
Hi all,

I've extended the prosilica_camera package to be able to work with
external trigger signals making it possible to externally trigger
multiple prosilica camera's.
Please find the patch attached, comments are always welcome to improve.
When the patch is applied I will update the documentation on the Wiki.

Greetz,

Koen Buys
Only in ./cfg: cpp
diff '--exclude=.svn' -rB ./cfg/ProsilicaCamera.cfg /home/koen/ros_unstable_svn/camera_drivers/prosilica_camera//cfg/ProsilicaCamera.cfg
3c3
< PACKAGE='prosilica_camera_hw'
---
> PACKAGE='prosilica_camera'

11,16c11,12
< mode_enum = gen.enum( [ gen.const("FreerunMode", str_t, "freerun", "Freerun mode"),
<                         gen.const("SyncIn1Mode", str_t, "syncin1", "SyncIn 1 mode"),
<                         gen.const("SyncIn2Mode", str_t, "syncin2", "SyncIn 2 mode"),
<                         gen.const("FixedRateMode", str_t, "fixedrate", "Fixed Rate mode"),
<                         gen.const("SoftwarePolledMode", str_t, "software", "Software Polled mode") ], "Enum to set the mode.")
<                         
---

> mode_enum = gen.enum( [ gen.const("StreamingMode", str_t, "streaming", "Streaming mode"),
>                         gen.const("PolledMode", str_t, "polled", "Polled mode") ], "Enum to set the mode.")

18c14
< gen.add("trigger_mode",      str_t,    SensorLevels.RECONFIGURE_STOP,    "Camera Trigger mode", "freerun", edit_method = mode_enum)
---

> gen.add("trigger_mode",      str_t,    SensorLevels.RECONFIGURE_STOP,    "Camera mode (streaming vs. polled)", "streaming", edit_method = mode_enum)

34c30
< exit(gen.generate(PACKAGE, "prosilica_driver", "Prosilica_Camera_Hw"))
---
> exit(gen.generate(PACKAGE, "prosilica_node", "ProsilicaCamera"))

diff '--exclude=.svn' -rB ./include/prosilica/prosilica.h /home/koen/ros_unstable_svn/camera_drivers/prosilica_camera//include/prosilica/prosilica.h
67,78d66
< /// According to FrameStartTriggerMode Enum - AVT GigE Camera and Driver Attributes
< /// Firmware 1.38 April 7,2010
< enum FrameStartTriggerMode
< {
< Freerun,
< SyncIn1,
< SyncIn2,
< FixedRate,
< Software,
< None
< };
<
82,84c70,72
< SingleFrame,
< MultiFrame,
< Recorder
---
> //FixedRate,
> Triggered,
> None

107c95
< void start(FrameStartTriggerMode = Freerun, AcquisitionMode = Continuous);
---
> void start(AcquisitionMode mode = Continuous);

110,111d97
< //! Capture a frame from external hardware sync trigger
< tPvFrame* sync_grab(unsigned long timeout_ms = PVINFINITE);
113,114c99,100
< //! start(Software Triggered).
< tPvFrame* sw_grab(unsigned long timeout_ms = PVINFINITE);
---
> //! start(Triggered).
> tPvFrame* grab(unsigned long timeout_ms = PVINFINITE);

157,158c143
< FrameStartTriggerMode FSTmode_;
< AcquisitionMode Amode_;
---
> AcquisitionMode mode_;

diff '--exclude=.svn' -rB ./manifest.xml /home/koen/ros_unstable_svn/camera_drivers/prosilica_camera//manifest.xml
2,4c2,3
< <description>A ROS and Orocos node to provide access to Prosilica cameras. Including support for external
< hardware trigger signals</description>
< <author>Patrick Mihelich, Koen Buys - Koen </author>
---
> <description>A ROS node to provide access to Prosilica cameras.</description>
> <author>Patrick Mihelich</author>

diff '--exclude=.svn' -rB ./src/libprosilica/prosilica.cpp /home/koen/ros_unstable_svn/camera_drivers/prosilica_camera//src/libprosilica/prosilica.cpp
59,60c59
< static const char* triggerModes[] = {"Freerun", "SyncIn1", "SyncIn2", "FixedRate", "Software"};
< static const char* acquisitionModes[] = {"Continuous","SingleFrame","MultiFrame","Recorder"};
---
> static const char* triggerModes[] = {"Freerun", "Software"};

139c138
< : bufferSize_(bufferSize), FSTmode_(None)
---
> : bufferSize_(bufferSize), mode_(None)

148c147
< : bufferSize_(bufferSize), FSTmode_(None)
---
> : bufferSize_(bufferSize), mode_(None)

211c210
< void Camera::start(FrameStartTriggerMode fmode, AcquisitionMode amode)
---
> void Camera::start(AcquisitionMode mode)

213,215c212,213
< assert( FSTmode_ == None && fmode != None );
< ///@todo verify this assert again
< assert( fmode == SyncIn1 || fmode == SyncIn2 || fmode == Software || !userCallback_.empty() );
---
> assert( mode_ == None && mode != None );
> assert( mode == Triggered || !userCallback_.empty() );

220c218
< if (fmode == Freerun)
---
> if (mode != Triggered)

226,227c224
<     ///@todo take this one also as an argument
<     CHECK_ERR( PvAttrEnumSet(handle_, "AcquisitionMode", acquisitionModes[amode]),
---

>     CHECK_ERR( PvAttrEnumSet(handle_, "AcquisitionMode", "Continuous"),

229c226
<     CHECK_ERR( PvAttrEnumSet(handle_, "FrameStartTriggerMode", triggerModes[fmode]),
---

>     CHECK_ERR( PvAttrEnumSet(handle_, "FrameStartTriggerMode", triggerModes[mode]),

233,234c230
< }
< catch (ProsilicaException& e) {
---
> } catch (ProsilicaException& e) {

238,239c234,235
< FSTmode_ = fmode;
< Amode_ = amode;
---
>
> mode_ = mode;

244c240
< if (FSTmode_ == None)
---
> if (mode_ == None)

250c246
< FSTmode_ = None;
---
> mode_ = None;

253c249
< tPvFrame* Camera::sync_grab(unsigned long timeout_ms)
---
> tPvFrame* Camera::grab(unsigned long timeout_ms)

255,298c251
<   //Check if were in the correct mode
<   assert( (FSTmode_ == SyncIn1) || (FSTmode_ == SyncIn2) );
<  
<     unsigned long time_so_far = 0;
<     while (time_so_far < timeout_ms)
<     { 
<     // Queue up a single frame
<     // Queue up a single frame
<     tPvFrame* frame = &frames_[0];
<     CHECK_ERR( PvCaptureQueueFrame(handle_, frame, NULL), "Couldn't queue frame" );
<     
<     // Wait for frame capture to finish. The wait call may timeout in less
<     // than the allotted time, so we keep trying until we exceed it.
<     tPvErr e = ePvErrSuccess;
<     do
<     {
<       try
<       {
<         if (e != ePvErrSuccess)
<           ROS_DEBUG("Retrying CaptureWait due to error: %s", errorStrings[e]);
<         clock_t start_time = clock();
<         e = PvCaptureWaitForFrameDone(handle_, frame, timeout_ms - time_so_far);
<         if (timeout_ms != PVINFINITE)
<           time_so_far += ((clock() - start_time) * 1000) / CLOCKS_PER_SEC;
<       } 
<       catch (prosilica::ProsilicaException &e) {
<         ROS_ERROR("Prosilica exception during grab, will retry: %s\n", e.what());
<       }
<     } while (e == ePvErrTimeout && time_so_far < timeout_ms);
< 
<     if (e != ePvErrSuccess)
<       return NULL; // Something bad happened (camera unplugged?)
<     
<     if (frame->Status == ePvErrSuccess)
<       return frame; // Yay!
< 
<     ROS_DEBUG("Error in frame: %s", errorStrings[frame->Status]);
< 
<     // Retry if data was lost in transmission. Probably no hope on other errors.
<     if (frame->Status != ePvErrDataMissing && frame->Status != ePvErrDataLost)
<       return NULL;
<   } 
<   return NULL; 
< }
---

> assert( mode_ == Triggered );

300,303d252
< tPvFrame* Camera::sw_grab(unsigned long timeout_ms)
< {
< assert( FSTmode_ == Software );
<
diff '--exclude=.svn' -rB ./src/nodes/prosilica_node.cpp /home/koen/ros_unstable_svn/camera_drivers/prosilica_camera//src/nodes/prosilica_node.cpp
41d40
< #include <std_msgs/Header.h>
75,76c74
< ros::Subscriber sub_;
<
---
>

79,80c77
< prosilica::FrameStartTriggerMode FSTmode_; /// @todo Make this property of Camera
< prosilica::AcquisitionMode Amode_;
---
> prosilica::AcquisitionMode mode_; /// @todo Make this property of Camera

191,192c188,189
<     if (config.trigger_mode == "freerun") {
<       FSTmode_ = prosilica::Freerun;
---

>     if (config.trigger_mode == "streaming") {
>       mode_ = prosilica::Continuous;

196,211c193,194
<     else if (config.trigger_mode == "syncin1") {
<       FSTmode_ = prosilica::SyncIn1;
<       desired_freq_ = 0;
<     }
<     else if (config.trigger_mode == "syncin2") {
<       FSTmode_ = prosilica::SyncIn2;
<       desired_freq_ = 0;
<     }
<     else if (config.trigger_mode == "fixedrate") {
<       ROS_DEBUG("Fixed rate not supported yet implementing software");
<       FSTmode_ = prosilica::Software;
<       ///@todo add the fixed rate implementation
<       desired_freq_ = 0;
<     }
<     else if (config.trigger_mode == "software") {
<       FSTmode_ = prosilica::Software;
---

>     else if (config.trigger_mode == "polled") {
>       mode_ = prosilica::Triggered;

279,309d261
<   void SyncInCallback (const std_msgs::Header::ConstPtr& msg)
<   {
<     tPvFrame* frame = NULL;
<     ROS_INFO("In SyncInCallback");
<     try {
<       // Zero duration means "no timeout" How to handle the timeout? 
<       // Put it also in the message?
<       unsigned long timeout = PVINFINITE;
<       frame = cam_->sync_grab(timeout);
<     }
<     catch (prosilica::ProsilicaException &e) {
<       if (e.error_code == ePvErrBadSequence)
<       {
<         ROS_INFO("Prosilica exception, ePvErrBadSequence, %s", e.what());
<         throw; // not easily recoverable
<       }
<       ROS_INFO("Prosilica exception %s", e.what());
<       return;
<     }
<     if (!frame) {
<       ROS_DEBUG("Failed to capture frame, may have timed out");
<       return;
<     }
<     if (processFrame(frame, img_, cam_info_))
<       streaming_pub_.publish(img_, cam_info_);
<     else
<        ROS_DEBUG("Captured frame but failed to process it");
<   }
<   
<   ///@todo add the setting of output sync1 and sync2?
< 
314c266
<     if (FSTmode_ == prosilica::Software) {
---

>     if (mode_ == prosilica::Triggered) {

319,322d270
<     else if ((FSTmode_ == prosilica::SyncIn1) || (FSTmode_ == prosilica::SyncIn2)){
<       streaming_pub_ = it_.advertiseCamera("image_raw", 1);
<       sub_ = nh_.subscribe("trigger", 1, &ProsilicaNode::SyncInCallback, this);
<     }
324c272
<       assert(FSTmode_ == prosilica::Freerun);
---

>       assert(mode_ == prosilica::Continuous);

328,329c276,277
<     Amode_ = prosilica::Continuous;
<     cam_->start(FSTmode_, Amode_);
---

>
>     cam_->start(mode_);

348c296
<     if (FSTmode_ != prosilica::Software) {
---

>     if (mode_ != prosilica::Triggered) {

350c298
<       rsp.status_message = "Camera is not in software triggered mode";
---

>       rsp.status_message = "Camera is not in triggered mode";

375c323
<       frame = cam_->sw_grab(timeout);
---

>       frame = cam_->grab(timeout);

565c513
<     cam_->start(prosilica::Freerun);
---

>     cam_->start(prosilica::Continuous);

790c738
<       if (FSTmode_ != prosilica::Software) {
---

>       if (mode_ != prosilica::Triggered) {

803c751
<         status.summary(2, "No frames captured over 3s in freerun mode");
---

>         status.summary(2, "No frames captured over 3s in continuous mode");

807c755
<       // In software triggered mode, try to grab a frame
---

>       // In triggered mode, try to grab a frame

809c757
<       tPvFrame* frame = cam_->sw_grab(500);
---

>       tPvFrame* frame = cam_->grab(500);

838a787
>

840a790
>