smartek_camera_node.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <sstream>
3 
4 #include <cv_bridge/cv_bridge.h>
5 #include <opencv2/opencv.hpp>
6 
7 #include "smartek_camera_node.h"
8 
13  defaultTimesyncOptions_.useMedianFilter = true;
14  defaultTimesyncOptions_.medianFilterWindow = 2500;
15  defaultTimesyncOptions_.useHoltWinters = true;
16  defaultTimesyncOptions_.alfa_HoltWinters = 3e-3;
17  defaultTimesyncOptions_.beta_HoltWinters = 2e-3;
18  defaultTimesyncOptions_.alfa_HoltWinters_early = 1e-1;
19  defaultTimesyncOptions_.beta_HoltWinters_early = 0.0;
20  defaultTimesyncOptions_.earlyClamp = true;
21  defaultTimesyncOptions_.earlyClampWindow = 500;
22  defaultTimesyncOptions_.timeOffset = 0.0;
23  defaultTimesyncOptions_.initialB_HoltWinters = -3e-7;
24  ptimestampSynchronizer_ = std::make_unique<TimestampSynchronizer>(defaultTimesyncOptions_);
25 }
26 
33 void SmartekCameraNode::publishGigeImage(const gige::IImageBitmapInterface &img, const gige::IImageInfo &imgInfo) {
34 
35  double currentRosTime = ros::Time::now().toSec();
36 
37  double currentCamTime = static_cast<double>(imgInfo->GetCameraTimestamp()) / 1000000.0;
38  UINT32 seq = imgInfo->GetImageID();
39 
40  UINT32 srcPixelType;
41  UINT32 srcWidth, srcHeight;
42 
43  img.GetPixelType(srcPixelType);
44  img.GetSize(srcWidth, srcHeight);
45 
46  UINT32 lineSize = img.GetLineSize();
47 
48  // construct an openCV image which shares memory with the GigE image
49  cv::Mat cvImage(srcHeight, srcWidth, config_.SmartekPipeline ? CV_8UC4 : CV_8UC1, (void *) img.GetRawData(), lineSize);
50  // ...then, build an image sensor message from the openCV image
51  sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), config_.SmartekPipeline ? "bgra8" : "bayer_rggb8", cvImage).toImageMsg();
52 
53  msg->header.frame_id=frame_id_;
54  msg->header.seq = seq;
55  msg->header.stamp = ros::Time(config_.EnableTimesync ? ptimestampSynchronizer_->sync(currentCamTime, currentRosTime, seq)
56  : currentRosTime);
57 
58  cameraInfo_ = pcameraInfoManager_->getCameraInfo();
59  cameraInfo_.header.stamp = msg->header.stamp;
60  cameraInfo_.header.seq = msg->header.seq;
61  cameraInfo_.header.frame_id = msg->header.frame_id;
62  cameraInfo_.width = srcWidth;
63  cameraInfo_.height = srcHeight;
64 
65  cameraPublisher_.publish(*msg, cameraInfo_);
66 }
67 
72 static std::string IpAddrToString(UINT32 ipAddress) {
73  std::stringstream outStream;
74  UINT32 part1, part2, part3, part4;
75 
76  part1 = ((ipAddress >> 24) & 0xFF);
77  part2 = ((ipAddress >> 16) & 0xFF);
78  part3 = ((ipAddress >> 8) & 0xFF);
79  part4 = ((ipAddress) & 0xFF);
80 
81  outStream << part1 << "." << part2 << "." << part3 << "." << part4;
82 
83  return outStream.str();
84 }
85 
87  while ( ros::ok() && isCameraConnected_ ) {
88  processFrames();
89  ros::spinOnce();
90  }
91 }
92 
94  n_ = ros::NodeHandle();
95  np_ = ros::NodeHandle(std::string("~"));
96 
97  frame_id_ = np_.param<std::string>("frame_id", "camera");
98 
99  if(config_.EnableTimesync) {
101  }
102 
103  serialNumber_ = np_.param<std::string>("SerialNumber", std::string());
104 
105  m_device_ = NULL;
106  gige::InitGigEVisionAPI();
107  gige::IGigEVisionAPI gigeVisionApi = gige::GetGigEVisionAPI();
108  gige::InitImageProcAPI();
109  m_imageProcApi_ = gige::GetImageProcAPI();
110  isCameraConnected_ = false;
111 
112  if (!gigeVisionApi->IsUsingKernelDriver()) {
113  ROS_WARN("!!! Warning: Smartek Filter Driver not loaded.");
114  }
115 
116  m_colorPipelineAlg_ = m_imageProcApi_->GetAlgorithmByName("ColorPipeline");
119  m_imageProcApi_->CreateBitmap(&m_colorPipelineBitmap_);
120 
121  ROS_INFO("Beginning device discovery...");
122  gigeVisionApi->FindAllDevices(3.0);
123  gige::DevicesList devices = gigeVisionApi->GetAllDevices();
124 
125  if (devices.size() > 0) {
126 
127  // if the user has requested a camera with specific serial number,
128  // loop through all discovered devices until we find it
129  if(!serialNumber_.empty()) {
130  for(int i = 0; i < devices.size(); i++)
131  if(devices[i]->GetSerialNumber() == serialNumber_) {
132  m_device_ = devices[i];
133  break;
134  }
135  }
136  else {
137  m_device_ = devices[0];
138  }
139 
140  // to change number of images in image buffer from default 10 images
141  // call SetImageBufferFrameCount() method before Connect() method
142  //m_device_->SetImageBufferFrameCount(20);
143 
144  if (m_device_ != NULL && m_device_->Connect()) {
145  UINT32 address = m_device_->GetIpAddress();
146  ROS_INFO_STREAM("Device IP address: " << IpAddrToString(address));
147  ROS_INFO_STREAM("Device serial number: " << m_device_->GetSerialNumber());
148 
149  // disable trigger mode
150  m_device_->SetStringNodeValue("TriggerMode", "Off");
151  // set continuous acquisition mode
152  m_device_->SetStringNodeValue("AcquisitionMode", "Continuous");
153 
154  // start acquisition
155  m_device_->SetIntegerNodeValue("TLParamsLocked", 1);
156  m_device_->CommandNodeExecute("AcquisitionStart");
157 
158  double currentExposure, currentGain, currentAcquisitionFramerate;
159  m_device_->GetFloatNodeValue("ExposureTime", currentExposure);
160  ROS_INFO("Exposure: %.2lf", currentExposure);
161 
162  m_device_->GetFloatNodeValue("Gain", currentGain);
163  ROS_INFO("Gain: %.2lf", currentGain);
164 
165  m_device_->GetFloatNodeValue("AcquisitionFrameRate", currentAcquisitionFramerate);
166  ROS_INFO("Acquisition framerate: %.2lf", currentAcquisitionFramerate);
167 
168  ROS_INFO("Timesync %s", config_.EnableTimesync ? "enabled" : "disabled");
169 
170  //m_defaultGainNotSet_ = true;
171  //m_defaultGain_ = 0.0;
172  isCameraConnected_ = true;
173 
174  pimageTransport_ = std::make_unique<image_transport::ImageTransport>(np_);
175  cameraPublisher_ = pimageTransport_->advertiseCamera("image_raw", 10);
176 
177  pcameraInfoManager_ = std::make_unique<camera_info_manager::CameraInfoManager>(np_, m_device_->GetSerialNumber());
178 
180  reconfigureServer_.setCallback(reconfigureCallback_);
181  }
182  }
183 
184  if (!isCameraConnected_) {
185  ROS_ERROR("No camera connected!");
186  if(!serialNumber_.empty())
187  ROS_ERROR_STREAM("Requested camera with serial number " << serialNumber_);
188  }
189 }
190 
191 void SmartekCameraNode::reconfigure_callback(Config &config, uint32_t level) {
192  if(isCameraConnected_) {
193  ROS_INFO("Reconfiguring camera");
194 
195  // stop acquisition
196  m_device_->CommandNodeExecute("AcquisitionStop");
197  m_device_->SetIntegerNodeValue("TLParamsLocked", 0);
198 
199  m_device_->SetFloatNodeValue("ExposureTime", config.ExposureTime);
200  m_device_->SetFloatNodeValue("Gain", config.Gain);
201  // the property in the GigEVision api is "AcqusitionFrameRate", with a capital R
202  m_device_->SetFloatNodeValue("AcquisitionFrameRate", config.AcquisitionFramerate);
203 
204  ROS_INFO("New exposure: %.2lf", config.ExposureTime);
205  ROS_INFO("New gain: %.2lf", config.Gain);
206  ROS_INFO("New acquisition framerate: %.2lf", config.AcquisitionFramerate);
207  ROS_INFO("Timesync %s", config.EnableTimesync ? "enabled" : "disabled");
208 
209  // reinitialize timesync if it has just been enabled
210  if(config.EnableTimesync && !config_.EnableTimesync) {
212  }
213 
214  // start acquisition
215  m_device_->SetIntegerNodeValue("TLParamsLocked", 1);
216  m_device_->CommandNodeExecute("AcquisitionStart");
217 
218  config_ = config;
219  }
220 }
221 
223 
224  if (m_device_.IsValid() && m_device_->IsConnected()) {
225  // stop acquisition
226  bool status = m_device_->CommandNodeExecute("AcquisitionStop");
227  status = m_device_->SetIntegerNodeValue("TLParamsLocked", 0);
228  m_device_->Disconnect();
229  }
230 
233  m_imageProcApi_->DestroyBitmap(m_colorPipelineBitmap_);
234 
235  gige::ExitImageProcAPI();
236  gige::ExitGigEVisionAPI();
237 }
238 
240  if (m_device_.IsValid() && m_device_->IsConnected()) {
241  bool gotImage = false;
242 
243  // sleep until the next frame is received
244  if(m_device_->WaitForImage(10.0)) {
245  if (!m_device_->IsBufferEmpty()) {
246 
247  m_device_->GetImageInfo(&m_imageInfo_);
248 
249  if (m_imageInfo_ != NULL) {
250  gotImage = true;
251 
252  if (config_.SmartekPipeline) {
255  publishGigeImage(gige::IImageBitmapInterface(m_colorPipelineBitmap_), m_imageInfo_);
256  } else
257  publishGigeImage(gige::IImageBitmapInterface(m_imageInfo_), m_imageInfo_);
258  }
259 
260  // remove (pop) image from image buffer
261  m_device_->PopImage(m_imageInfo_);
262  // empty buffer
263  m_device_->ClearImageBuffer();
264  }
265  }
266  if(!gotImage){
267  ROS_ERROR("Image not received!");
268  }
269  }
270  else {
271  isCameraConnected_ = false;
272  ROS_ERROR("Camera disconnected!");
273  }
274 
275 }
276 
277 int main(int argc, char **argv) {
278 
279  ros::init(argc, argv, "camera");
280  ros::start();
281 
282  // if the smartek camera node quits for some reason, e.g. camera disconnected,
283  // try to construct it again until the application receives an interrupt
284  while(ros::ok()) {
285  SmartekCameraNode().run();
286  }
287 
288  ros::shutdown();
289  return 0;
290 }
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
ros::NodeHandle n_
image_transport::CameraPublisher cameraPublisher_
std::unique_ptr< image_transport::ImageTransport > pimageTransport_
ROSCPP_DECL void start()
std::unique_ptr< TimestampSynchronizer > ptimestampSynchronizer_
void reconfigure_callback(Config &config, uint32_t level)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
gige::IImageBitmap m_colorPipelineBitmap_
gige::IImageInfo m_imageInfo_
dynamic_reconfigure::Server< Config > reconfigureServer_
#define ROS_WARN(...)
gige::IAlgorithm m_colorPipelineAlg_
gige::IResults m_colorPipelineResults_
gige::IImageProcAPI m_imageProcApi_
int main(int argc, char **argv)
sensor_msgs::CameraInfo cameraInfo_
void publishGigeImage(const gige::IImageBitmapInterface &img, const gige::IImageInfo &imgInfo)
smartek_camera::SmartekCameraConfig Config
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
gige::IParams m_colorPipelineParams_
ROSCPP_DECL bool ok()
std::unique_ptr< camera_info_manager::CameraInfoManager > pcameraInfoManager_
#define ROS_INFO_STREAM(args)
static Time now()
ROSCPP_DECL void shutdown()
ROS driver for the Smartek camera.
#define ROS_ERROR_STREAM(args)
ros::NodeHandle np_
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
gige::IDevice m_device_
dynamic_reconfigure::Server< Config >::CallbackType reconfigureCallback_
static std::string IpAddrToString(UINT32 ipAddress)
TimestampSynchronizer::Options defaultTimesyncOptions_
sensor_msgs::ImagePtr toImageMsg() const


smartek_camera
Author(s): Juraj Oršulić
autogenerated on Mon Jun 10 2019 15:10:30