00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <arv.h>
00023
00024 #include <iostream>
00025 #include <stdlib.h>
00026 #include <math.h>
00027 #include <string.h>
00028
00029 #include <glib.h>
00030
00031 #include <ros/ros.h>
00032 #include <ros/time.h>
00033 #include <ros/duration.h>
00034 #include <sensor_msgs/Image.h>
00035 #include <std_msgs/Int64.h>
00036 #include <sensor_msgs/image_encodings.h>
00037 #include <image_transport/image_transport.h>
00038 #include <camera_info_manager/camera_info_manager.h>
00039
00040 #include <dynamic_reconfigure/server.h>
00041 #include <driver_base/SensorLevels.h>
00042 #include <tf/transform_listener.h>
00043 #include <camera_aravis/CameraAravisConfig.h>
00044
00045 #include "XmlRpc.h"
00046
00047
00048
00049
00050 #define CLIP(x,lo,hi) MIN(MAX((lo),(x)),(hi))
00051 #define THROW_ERROR(m) throw std::string((m))
00052
00053 #define TRIGGERSOURCE_SOFTWARE 0
00054 #define TRIGGERSOURCE_LINE1 1
00055 #define TRIGGERSOURCE_LINE2 2
00056
00057 #define ARV_PIXEL_FORMAT_BIT_PER_PIXEL(pixel_format) (((pixel_format) >> 16) & 0xff)
00058 #define ARV_PIXEL_FORMAT_BYTE_PER_PIXEL(pixel_format) ((((pixel_format) >> 16) & 0xff) >> 3)
00059 typedef camera_aravis::CameraAravisConfig Config;
00060
00061 static gboolean SoftwareTrigger_callback (void *);
00062
00063 typedef struct
00064 {
00065 const char *szName;
00066 const char *szTag;
00067 ArvDomNode *pNode;
00068 ArvDomNode *pNodeSibling;
00069 } NODEEX;
00070
00071
00072 struct global_s
00073 {
00074 gboolean bCancel;
00075 image_transport::CameraPublisher publisher;
00076 camera_info_manager::CameraInfoManager *pCameraInfoManager;
00077 sensor_msgs::CameraInfo camerainfo;
00078 gint width, height;
00079 Config config;
00080 Config configMin;
00081 Config configMax;
00082 int idSoftwareTriggerTimer;
00083
00084 int isImplementedAcquisitionFrameRate;
00085 int isImplementedAcquisitionFrameRateEnable;
00086 int isImplementedGain;
00087 int isImplementedExposureTimeAbs;
00088 int isImplementedExposureAuto;
00089 int isImplementedGainAuto;
00090 int isImplementedFocusPos;
00091 int isImplementedTriggerSelector;
00092 int isImplementedTriggerSource;
00093 int isImplementedTriggerMode;
00094 int isImplementedAcquisitionMode;
00095 int isImplementedMtu;
00096
00097 int xRoi;
00098 int yRoi;
00099 int widthRoi;
00100 int widthRoiMin;
00101 int widthRoiMax;
00102 int heightRoi;
00103 int heightRoiMin;
00104 int heightRoiMax;
00105
00106 int widthSensor;
00107 int heightSensor;
00108
00109 const char *pszPixelformat;
00110 unsigned nBytesPixel;
00111 ros::NodeHandle *phNode;
00112 ArvCamera *pCamera;
00113 ArvDevice *pDevice;
00114 int mtu;
00115 int Acquire;
00116 const char *keyAcquisitionFrameRate;
00117 #ifdef TUNING
00118 ros::Publisher *ppubInt64;
00119 #endif
00120
00121 } global;
00122
00123
00124 typedef struct
00125 {
00126 GMainLoop *main_loop;
00127 int nBuffers;
00128 } ApplicationData;
00129
00130
00131
00132
00133 const char *szBufferStatusFromInt[] = {
00134 "ARV_BUFFER_STATUS_SUCCESS",
00135 "ARV_BUFFER_STATUS_CLEARED",
00136 "ARV_BUFFER_STATUS_TIMEOUT",
00137 "ARV_BUFFER_STATUS_MISSING_PACKETS",
00138 "ARV_BUFFER_STATUS_WRONG_PACKET_ID",
00139 "ARV_BUFFER_STATUS_SIZE_MISMATCH",
00140 "ARV_BUFFER_STATUS_FILLING",
00141 "ARV_BUFFER_STATUS_ABORTED"
00142 };
00143
00144
00145 static void set_cancel (int signal)
00146 {
00147 global.bCancel = TRUE;
00148 }
00149
00150 ArvGvStream *CreateStream(void)
00151 {
00152 gboolean bAutoBuffer = FALSE;
00153 gboolean bPacketResend = TRUE;
00154 unsigned int timeoutPacket = 40;
00155 unsigned int timeoutFrameRetention = 200;
00156
00157
00158 ArvGvStream *pStream = (ArvGvStream *)arv_device_create_stream (global.pDevice, NULL, NULL);
00159 if (pStream)
00160 {
00161 ArvBuffer *pBuffer;
00162 gint nbytesPayload;
00163
00164
00165 if (!ARV_IS_GV_STREAM (pStream))
00166 ROS_WARN("Stream is not a GV_STREAM");
00167
00168 if (bAutoBuffer)
00169 g_object_set (pStream,
00170 "socket-buffer",
00171 ARV_GV_STREAM_SOCKET_BUFFER_AUTO,
00172 "socket-buffer-size", 0,
00173 NULL);
00174 if (!bPacketResend)
00175 g_object_set (pStream,
00176 "packet-resend",
00177 bPacketResend ? ARV_GV_STREAM_PACKET_RESEND_ALWAYS : ARV_GV_STREAM_PACKET_RESEND_NEVER,
00178 NULL);
00179 g_object_set (pStream,
00180 "packet-timeout",
00181 (unsigned) timeoutPacket * 1000,
00182 "frame-retention", (unsigned) timeoutFrameRetention * 1000,
00183 NULL);
00184
00185
00186 nbytesPayload = arv_camera_get_payload (global.pCamera);
00187 for (int i=0; i<50; i++)
00188 {
00189 pBuffer = arv_buffer_new (nbytesPayload, NULL);
00190 arv_stream_push_buffer ((ArvStream *)pStream, pBuffer);
00191 }
00192 }
00193 return pStream;
00194 }
00195
00196
00197
00198 void RosReconfigure_callback(Config &config, uint32_t level)
00199 {
00200 int changedAcquire;
00201 int changedAcquisitionFrameRate;
00202 int changedExposureAuto;
00203 int changedGainAuto;
00204 int changedExposureTimeAbs;
00205 int changedGain;
00206 int changedAcquisitionMode;
00207 int changedTriggerMode;
00208 int changedTriggerSource;
00209 int changedSoftwarerate;
00210 int changedFrameid;
00211 int changedFocusPos;
00212 int changedMtu;
00213
00214
00215 std::string tf_prefix = tf::getPrefixParam(*global.phNode);
00216 ROS_DEBUG_STREAM("tf_prefix: " << tf_prefix);
00217
00218 if (config.frame_id == "")
00219 config.frame_id = "camera";
00220
00221
00222
00223 changedAcquire = (global.config.Acquire != config.Acquire);
00224 changedAcquisitionFrameRate = (global.config.AcquisitionFrameRate != config.AcquisitionFrameRate);
00225 changedExposureAuto = (global.config.ExposureAuto != config.ExposureAuto);
00226 changedExposureTimeAbs = (global.config.ExposureTimeAbs != config.ExposureTimeAbs);
00227 changedGainAuto = (global.config.GainAuto != config.GainAuto);
00228 changedGain = (global.config.Gain != config.Gain);
00229 changedAcquisitionMode = (global.config.AcquisitionMode != config.AcquisitionMode);
00230 changedTriggerMode = (global.config.TriggerMode != config.TriggerMode);
00231 changedTriggerSource = (global.config.TriggerSource != config.TriggerSource);
00232 changedSoftwarerate = (global.config.softwaretriggerrate != config.softwaretriggerrate);
00233 changedFrameid = (global.config.frame_id != config.frame_id);
00234 changedFocusPos = (global.config.FocusPos != config.FocusPos);
00235 changedMtu = (global.config.mtu != config.mtu);
00236
00237
00238
00239 config.AcquisitionFrameRate = CLIP(config.AcquisitionFrameRate, global.configMin.AcquisitionFrameRate, global.configMax.AcquisitionFrameRate);
00240 config.ExposureTimeAbs = CLIP(config.ExposureTimeAbs, global.configMin.ExposureTimeAbs, global.configMax.ExposureTimeAbs);
00241 config.Gain = CLIP(config.Gain, global.configMin.Gain, global.configMax.Gain);
00242 config.FocusPos = CLIP(config.FocusPos, global.configMin.FocusPos, global.configMax.FocusPos);
00243 config.frame_id = tf::resolve(tf_prefix, config.frame_id);
00244
00245
00246
00247 if (changedExposureTimeAbs || changedGainAuto || ((changedAcquisitionFrameRate || changedGain || changedFrameid
00248 || changedAcquisitionMode || changedTriggerSource || changedSoftwarerate) && config.ExposureAuto=="Once"))
00249 config.ExposureAuto = "Off";
00250
00251 if (changedGain || changedExposureAuto || ((changedAcquisitionFrameRate || changedExposureTimeAbs || changedFrameid
00252 || changedAcquisitionMode || changedTriggerSource || changedSoftwarerate) && config.GainAuto=="Once"))
00253 config.GainAuto = "Off";
00254
00255 if (changedAcquisitionFrameRate)
00256 config.TriggerMode = "Off";
00257
00258
00259
00260 changedAcquire = (global.config.Acquire != config.Acquire);
00261 changedAcquisitionFrameRate = (global.config.AcquisitionFrameRate != config.AcquisitionFrameRate);
00262 changedExposureAuto = (global.config.ExposureAuto != config.ExposureAuto);
00263 changedExposureTimeAbs = (global.config.ExposureTimeAbs != config.ExposureTimeAbs);
00264 changedGainAuto = (global.config.GainAuto != config.GainAuto);
00265 changedGain = (global.config.Gain != config.Gain);
00266 changedAcquisitionMode = (global.config.AcquisitionMode != config.AcquisitionMode);
00267 changedTriggerMode = (global.config.TriggerMode != config.TriggerMode);
00268 changedTriggerSource = (global.config.TriggerSource != config.TriggerSource);
00269 changedSoftwarerate = (global.config.softwaretriggerrate != config.softwaretriggerrate);
00270 changedFrameid = (global.config.frame_id != config.frame_id);
00271 changedFocusPos = (global.config.FocusPos != config.FocusPos);
00272 changedMtu = (global.config.mtu != config.mtu);
00273
00274
00275
00276 if (changedExposureTimeAbs)
00277 {
00278 if (global.isImplementedExposureTimeAbs)
00279 {
00280 ROS_INFO ("Set ExposureTimeAbs = %f", config.ExposureTimeAbs);
00281 arv_device_set_float_feature_value (global.pDevice, "ExposureTimeAbs", config.ExposureTimeAbs);
00282 }
00283 else
00284 ROS_INFO ("Camera does not support ExposureTimeAbs.");
00285 }
00286
00287 if (changedGain)
00288 {
00289 if (global.isImplementedGain)
00290 {
00291 ROS_INFO ("Set gain = %f", config.Gain);
00292
00293 arv_camera_set_gain (global.pCamera, config.Gain);
00294 }
00295 else
00296 ROS_INFO ("Camera does not support Gain or GainRaw.");
00297 }
00298
00299 if (changedExposureAuto)
00300 {
00301 if (global.isImplementedExposureAuto && global.isImplementedExposureTimeAbs)
00302 {
00303 ROS_INFO ("Set ExposureAuto = %s", config.ExposureAuto.c_str());
00304 arv_device_set_string_feature_value (global.pDevice, "ExposureAuto", config.ExposureAuto.c_str());
00305 if (config.ExposureAuto=="Once")
00306 {
00307 ros::Duration(2.0).sleep();
00308 config.ExposureTimeAbs = arv_device_get_float_feature_value (global.pDevice, "ExposureTimeAbs");
00309 ROS_INFO ("Get ExposureTimeAbs = %f", config.ExposureTimeAbs);
00310 config.ExposureAuto = "Off";
00311 }
00312 }
00313 else
00314 ROS_INFO ("Camera does not support ExposureAuto.");
00315 }
00316 if (changedGainAuto)
00317 {
00318 if (global.isImplementedGainAuto && global.isImplementedGain)
00319 {
00320 ROS_INFO ("Set GainAuto = %s", config.GainAuto.c_str());
00321 arv_device_set_string_feature_value (global.pDevice, "GainAuto", config.GainAuto.c_str());
00322 if (config.GainAuto=="Once")
00323 {
00324 ros::Duration(2.0).sleep();
00325
00326 config.Gain = arv_camera_get_gain (global.pCamera);
00327 ROS_INFO ("Get Gain = %f", config.Gain);
00328 config.GainAuto = "Off";
00329 }
00330 }
00331 else
00332 ROS_INFO ("Camera does not support GainAuto.");
00333 }
00334
00335 if (changedAcquisitionFrameRate)
00336 {
00337 if (global.isImplementedAcquisitionFrameRate)
00338 {
00339 ROS_INFO ("Set %s = %f", global.keyAcquisitionFrameRate, config.AcquisitionFrameRate);
00340 arv_device_set_float_feature_value (global.pDevice, global.keyAcquisitionFrameRate, config.AcquisitionFrameRate);
00341 }
00342 else
00343 ROS_INFO ("Camera does not support AcquisitionFrameRate.");
00344 }
00345
00346 if (changedTriggerMode)
00347 {
00348 if (global.isImplementedTriggerMode)
00349 {
00350 ROS_INFO ("Set TriggerMode = %s", config.TriggerMode.c_str());
00351 arv_device_set_string_feature_value (global.pDevice, "TriggerMode", config.TriggerMode.c_str());
00352 }
00353 else
00354 ROS_INFO ("Camera does not support TriggerMode.");
00355 }
00356
00357 if (changedTriggerSource)
00358 {
00359 if (global.isImplementedTriggerSource)
00360 {
00361 ROS_INFO ("Set TriggerSource = %s", config.TriggerSource.c_str());
00362 arv_device_set_string_feature_value (global.pDevice, "TriggerSource", config.TriggerSource.c_str());
00363 }
00364 else
00365 ROS_INFO ("Camera does not support TriggerSource.");
00366 }
00367
00368 if ((changedTriggerMode || changedTriggerSource || changedSoftwarerate) && config.TriggerMode=="On" && config.TriggerSource=="Software")
00369 {
00370 if (global.isImplementedAcquisitionFrameRate)
00371 {
00372
00373 config.AcquisitionFrameRate = global.configMax.AcquisitionFrameRate;
00374 ROS_INFO ("Set %s = %f", global.keyAcquisitionFrameRate, config.AcquisitionFrameRate);
00375 arv_device_set_float_feature_value (global.pDevice, global.keyAcquisitionFrameRate, config.AcquisitionFrameRate);
00376 }
00377 }
00378
00379 if (changedTriggerSource || changedSoftwarerate)
00380 {
00381
00382 if (global.idSoftwareTriggerTimer)
00383 {
00384 g_source_remove(global.idSoftwareTriggerTimer);
00385 global.idSoftwareTriggerTimer = 0;
00386 }
00387 if (!strcmp(config.TriggerSource.c_str(),"Software"))
00388 {
00389 ROS_INFO ("Set softwaretriggerrate = %f", 1000.0/ceil(1000.0 / config.softwaretriggerrate));
00390
00391
00392 global.idSoftwareTriggerTimer = g_timeout_add ((guint)ceil(1000.0 / config.softwaretriggerrate), SoftwareTrigger_callback, global.pCamera);
00393 }
00394 }
00395 if (changedFocusPos)
00396 {
00397 if (global.isImplementedFocusPos)
00398 {
00399 ROS_INFO ("Set FocusPos = %d", config.FocusPos);
00400 arv_device_set_integer_feature_value(global.pDevice, "FocusPos", config.FocusPos);
00401 ros::Duration(1.0).sleep();
00402 config.FocusPos = arv_device_get_integer_feature_value(global.pDevice, "FocusPos");
00403 ROS_INFO ("Get FocusPos = %d", config.FocusPos);
00404 }
00405 else
00406 ROS_INFO ("Camera does not support FocusPos.");
00407 }
00408 if (changedMtu)
00409 {
00410 if (global.isImplementedMtu)
00411 {
00412 ROS_INFO ("Set mtu = %d", config.mtu);
00413 arv_device_set_integer_feature_value(global.pDevice, "GevSCPSPacketSize", config.mtu);
00414 ros::Duration(1.0).sleep();
00415 config.mtu = arv_device_get_integer_feature_value(global.pDevice, "GevSCPSPacketSize");
00416 ROS_INFO ("Get mtu = %d", config.mtu);
00417 }
00418 else
00419 ROS_INFO ("Camera does not support mtu (i.e. GevSCPSPacketSize).");
00420 }
00421
00422 if (changedAcquisitionMode)
00423 {
00424 if (global.isImplementedAcquisitionMode)
00425 {
00426 ROS_INFO ("Set AcquisitionMode = %s", config.AcquisitionMode.c_str());
00427 arv_device_set_string_feature_value (global.pDevice, "AcquisitionMode", config.AcquisitionMode.c_str());
00428
00429 ROS_INFO("AcquisitionStop");
00430 arv_device_execute_command (global.pDevice, "AcquisitionStop");
00431 ROS_INFO("AcquisitionStart");
00432 arv_device_execute_command (global.pDevice, "AcquisitionStart");
00433 }
00434 else
00435 ROS_INFO ("Camera does not support AcquisitionMode.");
00436 }
00437
00438 if (changedAcquire)
00439 {
00440 if (config.Acquire)
00441 {
00442 ROS_INFO("AcquisitionStart");
00443 arv_device_execute_command (global.pDevice, "AcquisitionStart");
00444 }
00445 else
00446 {
00447 ROS_INFO("AcquisitionStop");
00448 arv_device_execute_command (global.pDevice, "AcquisitionStop");
00449 }
00450 }
00451
00452
00453
00454 global.config = config;
00455
00456 }
00457
00458
00459 static void NewBuffer_callback (ArvStream *pStream, ApplicationData *pApplicationdata)
00460 {
00461 static uint64_t cm = 0L;
00462 uint64_t cn = 0L;
00463
00464 #ifdef TUNING
00465 static uint64_t rm = 0L;
00466 #endif
00467 uint64_t rn = 0L;
00468
00469 static uint64_t tm = 0L;
00470 uint64_t tn = 0L;
00471
00472 static int64_t em = 0L;
00473 int64_t en = 0L;
00474 int64_t de = 0L;
00475 int64_t ie = 0L;
00476 int64_t u = 0L;
00477
00478 int64_t kp1 = 0L;
00479 int64_t kp2 = 1024L;
00480 int64_t kd1 = 0L;
00481 int64_t kd2 = 1024L;
00482 int64_t ki1 = -1L;
00483 int64_t ki2 = 1024L;
00484
00485 static uint32_t iFrame = 0;
00486
00487 ArvBuffer *pBuffer;
00488
00489
00490 #ifdef TUNING
00491 std_msgs::Int64 msgInt64;
00492 int kp = 0;
00493 int kd = 0;
00494 int ki = 0;
00495
00496 if (global.phNode->hasParam(ros::this_node::getName()+"/kp"))
00497 {
00498 global.phNode->getParam(ros::this_node::getName()+"/kp", kp);
00499 kp1 = kp;
00500 }
00501
00502 if (global.phNode->hasParam(ros::this_node::getName()+"/kd"))
00503 {
00504 global.phNode->getParam(ros::this_node::getName()+"/kd", kd);
00505 kd1 = kd;
00506 }
00507
00508 if (global.phNode->hasParam(ros::this_node::getName()+"/ki"))
00509 {
00510 global.phNode->getParam(ros::this_node::getName()+"/ki", ki);
00511 ki1 = ki;
00512 }
00513 #endif
00514
00515 pBuffer = arv_stream_try_pop_buffer (pStream);
00516 if (pBuffer != NULL)
00517 {
00518 if (pBuffer->status == ARV_BUFFER_STATUS_SUCCESS)
00519 {
00520 sensor_msgs::Image msg;
00521
00522 pApplicationdata->nBuffers++;
00523 std::vector<uint8_t> this_data(pBuffer->size);
00524 memcpy(&this_data[0], pBuffer->data, pBuffer->size);
00525
00526
00527
00528 cn = (uint64_t)pBuffer->timestamp_ns;
00529 rn = ros::Time::now().toNSec();
00530
00531 if (iFrame < 10)
00532 {
00533 cm = cn;
00534 tm = rn;
00535 }
00536
00537
00538 en = (int64_t)tm + (int64_t)cn - (int64_t)cm - (int64_t)rn;
00539 de = en-em;
00540 ie += en;
00541 u = kp1*(en/kp2) + ki1*(ie/ki2) + kd1*(de/kd2);
00542
00543
00544 tn = (uint64_t)((int64_t)tm + (int64_t)cn-(int64_t)cm + u);
00545
00546 #ifdef TUNING
00547 ROS_WARN("en=%16ld, ie=%16ld, de=%16ld, u=%16ld + %16ld + %16ld = %16ld", en, ie, de, kp1*(en/kp2), ki1*(ie/ki2), kd1*(de/kd2), u);
00548 ROS_WARN("cn=%16lu, rn=%16lu, cn-cm=%8ld, rn-rm=%8ld, tn-tm=%8ld, tn-rn=%ld", cn, rn, cn-cm, rn-rm, (int64_t)tn-(int64_t)tm, tn-rn);
00549 msgInt64.data = tn-rn;
00550 global.ppubInt64->publish(msgInt64);
00551 rm = rn;
00552 #endif
00553
00554
00555 cm = cn;
00556 tm = tn;
00557 em = en;
00558
00559
00560 msg.header.stamp.fromNSec(tn);
00561 msg.header.seq = pBuffer->frame_id;
00562 msg.header.frame_id = global.config.frame_id;
00563 msg.width = global.widthRoi;
00564 msg.height = global.heightRoi;
00565 msg.encoding = global.pszPixelformat;
00566 msg.step = msg.width * global.nBytesPixel;
00567 msg.data = this_data;
00568
00569
00570 global.camerainfo = global.pCameraInfoManager->getCameraInfo();
00571 global.camerainfo.header.stamp = msg.header.stamp;
00572 global.camerainfo.header.seq = msg.header.seq;
00573 global.camerainfo.header.frame_id = msg.header.frame_id;
00574 global.camerainfo.width = global.widthRoi;
00575 global.camerainfo.height = global.heightRoi;
00576
00577 global.publisher.publish(msg, global.camerainfo);
00578
00579 }
00580 else
00581 ROS_WARN ("Frame error: %s", szBufferStatusFromInt[pBuffer->status]);
00582
00583 arv_stream_push_buffer (pStream, pBuffer);
00584 iFrame++;
00585 }
00586 }
00587
00588
00589 static void ControlLost_callback (ArvGvDevice *pGvDevice)
00590 {
00591 ROS_ERROR ("Control lost.");
00592
00593 global.bCancel = TRUE;
00594 }
00595
00596 static gboolean SoftwareTrigger_callback (void *pCamera)
00597 {
00598 arv_device_execute_command (global.pDevice, "TriggerSoftware");
00599
00600 return TRUE;
00601 }
00602
00603
00604
00605
00606 static gboolean PeriodicTask_callback (void *applicationdata)
00607 {
00608 ApplicationData *pData = (ApplicationData*)applicationdata;
00609
00610
00611 pData->nBuffers = 0;
00612
00613 if (global.bCancel)
00614 {
00615 g_main_loop_quit (pData->main_loop);
00616 return FALSE;
00617 }
00618
00619 ros::spinOnce();
00620
00621 return TRUE;
00622 }
00623
00624
00625
00626 NODEEX GetGcFirstChild(ArvGc *pGenicam, NODEEX nodeex)
00627 {
00628 const char *szName=0;
00629
00630 if (nodeex.pNode)
00631 {
00632 nodeex.pNode = arv_dom_node_get_first_child(nodeex.pNode);
00633 if (nodeex.pNode)
00634 {
00635 nodeex.szName = arv_dom_node_get_node_name(nodeex.pNode);
00636 nodeex.pNodeSibling = arv_dom_node_get_next_sibling(nodeex.pNode);
00637
00638
00639 if (nodeex.szName[0]=='p' && strcmp("pInvalidator", nodeex.szName))
00640 {
00641 szName = arv_dom_node_get_node_value(arv_dom_node_get_first_child(nodeex.pNode));
00642 nodeex.pNode = (ArvDomNode *)arv_gc_get_node(pGenicam, szName);
00643 nodeex.szTag = arv_dom_node_get_node_name(nodeex.pNode);
00644 }
00645 else
00646 {
00647 nodeex.szTag = nodeex.szName;
00648 }
00649 }
00650 else
00651 nodeex.pNodeSibling = NULL;
00652 }
00653 else
00654 {
00655 nodeex.szName = NULL;
00656 nodeex.szTag = NULL;
00657 nodeex.pNodeSibling = NULL;
00658 }
00659
00660
00661
00662
00663 return nodeex;
00664 }
00665
00666
00667
00668 NODEEX GetGcNextSibling(ArvGc *pGenicam, NODEEX nodeex)
00669 {
00670 const char *szName=0;
00671
00672
00673 nodeex.pNode = nodeex.pNodeSibling;
00674 if (nodeex.pNode)
00675 {
00676 nodeex.szName = arv_dom_node_get_node_name(nodeex.pNode);
00677 nodeex.pNodeSibling = arv_dom_node_get_next_sibling(nodeex.pNode);
00678
00679
00680 if (nodeex.szName[0]=='p' && strcmp("pInvalidator", nodeex.szName))
00681 {
00682 szName = arv_dom_node_get_node_value(arv_dom_node_get_first_child(nodeex.pNode));
00683 nodeex.pNode = (ArvDomNode *)arv_gc_get_node(pGenicam, szName);
00684 nodeex.szTag = nodeex.pNode ? arv_dom_node_get_node_name(nodeex.pNode) : NULL;
00685 }
00686 else
00687 {
00688 nodeex.szTag = nodeex.szName;
00689 }
00690 }
00691 else
00692 {
00693 nodeex.szName = NULL;
00694 nodeex.szTag = NULL;
00695 nodeex.pNodeSibling = NULL;
00696 }
00697
00698
00699
00700
00701 return nodeex;
00702 }
00703
00704
00705
00706 void PrintDOMTree(ArvGc *pGenicam, NODEEX nodeex, int nIndent)
00707 {
00708 char *szIndent=0;
00709 const char *szFeature=0;
00710 const char *szDomName=0;
00711 const char *szFeatureValue=0;
00712
00713 szIndent = new char[nIndent+1];
00714 memset(szIndent,' ',nIndent);
00715 szIndent[nIndent]=0;
00716
00717 nodeex = GetGcFirstChild(pGenicam, nodeex);
00718 if (nodeex.pNode)
00719 {
00720 do
00721 {
00722 if (ARV_IS_GC_FEATURE_NODE((ArvGcFeatureNode *)nodeex.pNode))
00723 {
00724 szDomName = arv_dom_node_get_node_name(nodeex.pNode);
00725 szFeature = arv_gc_feature_node_get_name((ArvGcFeatureNode *)nodeex.pNode);
00726 szFeatureValue = arv_gc_feature_node_get_value_as_string((ArvGcFeatureNode *)nodeex.pNode, NULL);
00727 if (szFeature && szFeatureValue && szFeatureValue[0])
00728 ROS_INFO("FeatureName: %s%s, %s=%s", szIndent, szDomName, szFeature, szFeatureValue);
00729 }
00730 PrintDOMTree(pGenicam, nodeex, nIndent+4);
00731
00732
00733 nodeex = GetGcNextSibling(pGenicam, nodeex);
00734
00735 } while (nodeex.pNode && nodeex.pNodeSibling);
00736 }
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 void WriteCameraFeaturesFromRosparam(void)
00750 {
00751 XmlRpc::XmlRpcValue xmlrpcParams;
00752 XmlRpc::XmlRpcValue::iterator iter;
00753 ArvGcNode *pGcNode;
00754 GError *error=NULL;
00755
00756
00757 global.phNode->getParam (ros::this_node::getName(), xmlrpcParams);
00758
00759
00760 if (xmlrpcParams.getType() == XmlRpc::XmlRpcValue::TypeStruct)
00761 {
00762 for (iter=xmlrpcParams.begin(); iter!=xmlrpcParams.end(); iter++)
00763 {
00764 std::string key = iter->first;
00765
00766 pGcNode = arv_device_get_feature (global.pDevice, key.c_str());
00767 if (pGcNode && arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error))
00768 {
00769
00770
00771
00772
00773 switch (iter->second.getType())
00774 {
00775 case XmlRpc::XmlRpcValue::TypeBoolean:
00776 {
00777 int value = (bool)iter->second;
00778 arv_device_set_integer_feature_value(global.pDevice, key.c_str(), value);
00779 ROS_INFO("Read parameter (bool) %s: %d", key.c_str(), value);
00780 }
00781 break;
00782
00783 case XmlRpc::XmlRpcValue::TypeInt:
00784 {
00785 int value = (int)iter->second;
00786 arv_device_set_integer_feature_value(global.pDevice, key.c_str(), value);
00787 ROS_INFO("Read parameter (int) %s: %d", key.c_str(), value);
00788 }
00789 break;
00790
00791 case XmlRpc::XmlRpcValue::TypeDouble:
00792 {
00793 double value = (double)iter->second;
00794 arv_device_set_float_feature_value(global.pDevice, key.c_str(), value);
00795 ROS_INFO("Read parameter (float) %s: %f", key.c_str(), value);
00796 }
00797 break;
00798
00799 case XmlRpc::XmlRpcValue::TypeString:
00800 {
00801 std::string value = (std::string)iter->second;
00802 arv_device_set_string_feature_value(global.pDevice, key.c_str(), value.c_str());
00803 ROS_INFO("Read parameter (string) %s: %s", key.c_str(), value.c_str());
00804 }
00805 break;
00806
00807 case XmlRpc::XmlRpcValue::TypeInvalid:
00808 case XmlRpc::XmlRpcValue::TypeDateTime:
00809 case XmlRpc::XmlRpcValue::TypeBase64:
00810 case XmlRpc::XmlRpcValue::TypeArray:
00811 case XmlRpc::XmlRpcValue::TypeStruct:
00812 default:
00813 ROS_WARN("Unhandled rosparam type in WriteCameraFeaturesFromRosparam()");
00814 }
00815 }
00816 }
00817 }
00818 }
00819
00820
00821
00822 int main(int argc, char** argv)
00823 {
00824 char *pszGuid = NULL;
00825 char szGuid[512];
00826 int nInterfaces = 0;
00827 int nDevices = 0;
00828 int i = 0;
00829 const char *pkeyAcquisitionFrameRate[2] = {"AcquisitionFrameRate", "AcquisitionFrameRateAbs"};
00830 ArvGcNode *pGcNode;
00831 GError *error=NULL;
00832
00833
00834
00835
00836 global.bCancel = FALSE;
00837 global.config = global.config.__getDefault__();
00838 global.idSoftwareTriggerTimer = 0;
00839
00840 ros::init(argc, argv, "camera");
00841 global.phNode = new ros::NodeHandle();
00842
00843
00844
00845
00846
00847 ROS_INFO ("Attached cameras:");
00848 arv_update_device_list();
00849 nInterfaces = arv_get_n_interfaces();
00850 ROS_INFO ("# Interfaces: %d", nInterfaces);
00851
00852 nDevices = arv_get_n_devices();
00853 ROS_INFO ("# Devices: %d", nDevices);
00854 for (i=0; i<nDevices; i++)
00855 ROS_INFO ("Device%d: %s", i, arv_get_device_id(i));
00856
00857 if (nDevices>0)
00858 {
00859
00860 if (argc==2)
00861 {
00862 strcpy(szGuid, argv[1]);
00863 pszGuid = szGuid;
00864 }
00865 else
00866 {
00867 if (global.phNode->hasParam(ros::this_node::getName()+"/guid"))
00868 {
00869 std::string stGuid;
00870
00871 global.phNode->getParam(ros::this_node::getName()+"/guid", stGuid);
00872 strcpy (szGuid, stGuid.c_str());
00873 pszGuid = szGuid;
00874 }
00875 else
00876 pszGuid = NULL;
00877 }
00878
00879
00880 ROS_INFO("Opening: %s", pszGuid ? pszGuid : "(any)");
00881 while (TRUE)
00882 {
00883 global.pCamera = arv_camera_new(pszGuid);
00884 if (global.pCamera)
00885 break;
00886 else
00887 {
00888 ROS_WARN ("Could not open camera %s. Retrying...", pszGuid);
00889 ros::Duration(1.0).sleep();
00890 ros::spinOnce();
00891 }
00892 }
00893
00894 global.pDevice = arv_camera_get_device(global.pCamera);
00895 ROS_INFO("Opened: %s-%s", arv_device_get_string_feature_value (global.pDevice, "DeviceVendorName"), arv_device_get_string_feature_value (global.pDevice, "DeviceID"));
00896
00897
00898
00899 pGcNode = arv_device_get_feature (global.pDevice, "AcquisitionMode");
00900 global.isImplementedAcquisitionMode = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00901
00902 pGcNode = arv_device_get_feature (global.pDevice, "GainRaw");
00903 global.isImplementedGain = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00904 pGcNode = arv_device_get_feature (global.pDevice, "Gain");
00905 global.isImplementedGain |= ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00906
00907 pGcNode = arv_device_get_feature (global.pDevice, "ExposureTimeAbs");
00908 global.isImplementedExposureTimeAbs = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00909
00910 pGcNode = arv_device_get_feature (global.pDevice, "ExposureAuto");
00911 global.isImplementedExposureAuto = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00912
00913 pGcNode = arv_device_get_feature (global.pDevice, "GainAuto");
00914 global.isImplementedGainAuto = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00915
00916 pGcNode = arv_device_get_feature (global.pDevice, "TriggerSelector");
00917 global.isImplementedTriggerSelector = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00918
00919 pGcNode = arv_device_get_feature (global.pDevice, "TriggerSource");
00920 global.isImplementedTriggerSource = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00921
00922 pGcNode = arv_device_get_feature (global.pDevice, "TriggerMode");
00923 global.isImplementedTriggerMode = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00924
00925 pGcNode = arv_device_get_feature (global.pDevice, "FocusPos");
00926 global.isImplementedFocusPos = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00927
00928 pGcNode = arv_device_get_feature (global.pDevice, "GevSCPSPacketSize");
00929 global.isImplementedMtu = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00930
00931 pGcNode = arv_device_get_feature (global.pDevice, "AcquisitionFrameRateEnable");
00932 global.isImplementedAcquisitionFrameRateEnable = ARV_GC_FEATURE_NODE (pGcNode) ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00933
00934
00935 global.keyAcquisitionFrameRate = NULL;
00936 for (i=0; i<2; i++)
00937 {
00938 pGcNode = arv_device_get_feature (global.pDevice, pkeyAcquisitionFrameRate[i]);
00939 global.isImplementedAcquisitionFrameRate = pGcNode ? arv_gc_feature_node_is_implemented (ARV_GC_FEATURE_NODE (pGcNode), &error) : FALSE;
00940 if (global.isImplementedAcquisitionFrameRate)
00941 {
00942 global.keyAcquisitionFrameRate = pkeyAcquisitionFrameRate[i];
00943 break;
00944 }
00945 }
00946
00947
00948
00949 arv_camera_get_exposure_time_bounds (global.pCamera, &global.configMin.ExposureTimeAbs, &global.configMax.ExposureTimeAbs);
00950 arv_camera_get_gain_bounds (global.pCamera, &global.configMin.Gain, &global.configMax.Gain);
00951 arv_camera_get_sensor_size (global.pCamera, &global.widthSensor, &global.heightSensor);
00952 arv_camera_get_width_bounds (global.pCamera, &global.widthRoiMin, &global.widthRoiMax);
00953 arv_camera_get_height_bounds (global.pCamera, &global.heightRoiMin, &global.heightRoiMax);
00954
00955 if (global.isImplementedFocusPos)
00956 {
00957 gint64 focusMin64, focusMax64;
00958 arv_device_get_integer_feature_bounds (global.pDevice, "FocusPos", &focusMin64, &focusMax64);
00959 global.configMin.FocusPos = focusMin64;
00960 global.configMax.FocusPos = focusMax64;
00961 }
00962 else
00963 {
00964 global.configMin.FocusPos = 0;
00965 global.configMax.FocusPos = 0;
00966 }
00967
00968 global.configMin.AcquisitionFrameRate = 0.0;
00969 global.configMax.AcquisitionFrameRate = 1000.0;
00970
00971
00972
00973 if (global.isImplementedExposureTimeAbs)
00974 arv_device_set_float_feature_value(global.pDevice, "ExposureTimeAbs", global.config.ExposureTimeAbs);
00975 if (global.isImplementedGain)
00976 arv_camera_set_gain(global.pCamera, global.config.Gain);
00977
00978 if (global.isImplementedAcquisitionFrameRateEnable)
00979 arv_device_set_integer_feature_value(global.pDevice, "AcquisitionFrameRateEnable", 1);
00980 if (global.isImplementedAcquisitionFrameRate)
00981 arv_device_set_float_feature_value(global.pDevice, global.keyAcquisitionFrameRate, global.config.AcquisitionFrameRate);
00982
00983
00984
00985 if (global.isImplementedTriggerMode)
00986 {
00987 if (global.isImplementedTriggerSelector && global.isImplementedTriggerMode)
00988 {
00989 arv_device_set_string_feature_value(global.pDevice, "TriggerSelector", "AcquisitionStart");
00990 arv_device_set_string_feature_value(global.pDevice, "TriggerMode", "Off");
00991 arv_device_set_string_feature_value(global.pDevice, "TriggerSelector", "FrameStart");
00992 arv_device_set_string_feature_value(global.pDevice, "TriggerMode", "Off");
00993 }
00994 }
00995
00996
00997 WriteCameraFeaturesFromRosparam ();
00998
00999
01000 #ifdef TUNING
01001 ros::Publisher pubInt64 = global.phNode->advertise<std_msgs::Int64>(ros::this_node::getName()+"/dt", 100);
01002 global.ppubInt64 = &pubInt64;
01003 #endif
01004
01005
01006 global.pCameraInfoManager = new camera_info_manager::CameraInfoManager(ros::NodeHandle(ros::this_node::getName()), arv_device_get_string_feature_value (global.pDevice, "DeviceID"));
01007
01008
01009 dynamic_reconfigure::Server<Config> reconfigureServer;
01010 dynamic_reconfigure::Server<Config>::CallbackType reconfigureCallback;
01011
01012 reconfigureCallback = boost::bind(&RosReconfigure_callback, _1, _2);
01013 reconfigureServer.setCallback(reconfigureCallback);
01014 ros::Duration(2.0).sleep();
01015
01016
01017
01018 global.xRoi=0; global.yRoi=0; global.widthRoi=0; global.heightRoi=0;
01019 arv_camera_get_region (global.pCamera, &global.xRoi, &global.yRoi, &global.widthRoi, &global.heightRoi);
01020 global.config.ExposureTimeAbs = global.isImplementedExposureTimeAbs ? arv_device_get_float_feature_value (global.pDevice, "ExposureTimeAbs") : 0;
01021 global.config.Gain = global.isImplementedGain ? arv_camera_get_gain (global.pCamera) : 0.0;
01022 global.pszPixelformat = g_string_ascii_down(g_string_new(arv_device_get_string_feature_value(global.pDevice, "PixelFormat")))->str;
01023 global.nBytesPixel = ARV_PIXEL_FORMAT_BYTE_PER_PIXEL(arv_device_get_integer_feature_value(global.pDevice, "PixelFormat"));
01024 global.config.FocusPos = global.isImplementedFocusPos ? arv_device_get_integer_feature_value (global.pDevice, "FocusPos") : 0;
01025
01026
01027
01028 ROS_INFO (" Using Camera Configuration:");
01029 ROS_INFO (" ---------------------------");
01030 ROS_INFO (" Vendor name = %s", arv_device_get_string_feature_value (global.pDevice, "DeviceVendorName"));
01031 ROS_INFO (" Model name = %s", arv_device_get_string_feature_value (global.pDevice, "DeviceModelName"));
01032 ROS_INFO (" Device id = %s", arv_device_get_string_feature_value (global.pDevice, "DeviceID"));
01033 ROS_INFO (" Sensor width = %d", global.widthSensor);
01034 ROS_INFO (" Sensor height = %d", global.heightSensor);
01035 ROS_INFO (" ROI x,y,w,h = %d, %d, %d, %d", global.xRoi, global.yRoi, global.widthRoi, global.heightRoi);
01036 ROS_INFO (" Pixel format = %s", global.pszPixelformat);
01037 ROS_INFO (" BytesPerPixel = %d", global.nBytesPixel);
01038 ROS_INFO (" Acquisition Mode = %s", global.isImplementedAcquisitionMode ? arv_device_get_string_feature_value (global.pDevice, "AcquisitionMode") : "(not implemented in camera)");
01039 ROS_INFO (" Trigger Mode = %s", global.isImplementedTriggerMode ? arv_device_get_string_feature_value (global.pDevice, "TriggerMode") : "(not implemented in camera)");
01040 ROS_INFO (" Trigger Source = %s", global.isImplementedTriggerSource ? arv_device_get_string_feature_value(global.pDevice, "TriggerSource") : "(not implemented in camera)");
01041 ROS_INFO (" Can set FrameRate: %s", global.isImplementedAcquisitionFrameRate ? "True" : "False");
01042 if (global.isImplementedAcquisitionFrameRate)
01043 {
01044 global.config.AcquisitionFrameRate = arv_device_get_float_feature_value (global.pDevice, global.keyAcquisitionFrameRate);
01045 ROS_INFO (" AcquisitionFrameRate = %g hz", global.config.AcquisitionFrameRate);
01046 }
01047
01048 ROS_INFO (" Can set Exposure: %s", global.isImplementedExposureTimeAbs ? "True" : "False");
01049 if (global.isImplementedExposureTimeAbs)
01050 {
01051 ROS_INFO (" Can set ExposureAuto: %s", global.isImplementedExposureAuto ? "True" : "False");
01052 ROS_INFO (" Exposure = %g us in range [%g,%g]", global.config.ExposureTimeAbs, global.configMin.ExposureTimeAbs, global.configMax.ExposureTimeAbs);
01053 }
01054
01055 ROS_INFO (" Can set Gain: %s", global.isImplementedGain ? "True" : "False");
01056 if (global.isImplementedGain)
01057 {
01058 ROS_INFO (" Can set GainAuto: %s", global.isImplementedGainAuto ? "True" : "False");
01059 ROS_INFO (" Gain = %f %% in range [%f,%f]", global.config.Gain, global.configMin.Gain, global.configMax.Gain);
01060 }
01061
01062 ROS_INFO (" Can set FocusPos: %s", global.isImplementedFocusPos ? "True" : "False");
01063
01064 if (global.isImplementedMtu)
01065 ROS_INFO (" Network mtu = %lu", arv_device_get_integer_feature_value(global.pDevice, "GevSCPSPacketSize"));
01066
01067 ROS_INFO (" ---------------------------");
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 ArvGvStream *pStream = NULL;
01084 while (TRUE)
01085 {
01086 pStream = CreateStream();
01087 if (pStream)
01088 break;
01089 else
01090 {
01091 ROS_WARN("Could not create image stream for %s. Retrying...", pszGuid);
01092 ros::Duration(1.0).sleep();
01093 ros::spinOnce();
01094 }
01095 }
01096
01097
01098 ApplicationData applicationdata;
01099 applicationdata.nBuffers=0;
01100 applicationdata.main_loop = 0;
01101
01102
01103 image_transport::ImageTransport *pTransport = new image_transport::ImageTransport(*global.phNode);
01104 global.publisher = pTransport->advertiseCamera(ros::this_node::getName()+"/image_raw", 1);
01105
01106
01107 g_signal_connect (pStream, "new-buffer", G_CALLBACK (NewBuffer_callback), &applicationdata);
01108 g_signal_connect (global.pDevice, "control-lost", G_CALLBACK (ControlLost_callback), NULL);
01109 g_timeout_add_seconds (1, PeriodicTask_callback, &applicationdata);
01110 arv_stream_set_emit_signals ((ArvStream *)pStream, TRUE);
01111
01112
01113 void (*pSigintHandlerOld)(int);
01114 pSigintHandlerOld = signal (SIGINT, set_cancel);
01115
01116 arv_device_execute_command (global.pDevice, "AcquisitionStart");
01117
01118 applicationdata.main_loop = g_main_loop_new (NULL, FALSE);
01119 g_main_loop_run (applicationdata.main_loop);
01120
01121 if (global.idSoftwareTriggerTimer)
01122 {
01123 g_source_remove(global.idSoftwareTriggerTimer);
01124 global.idSoftwareTriggerTimer = 0;
01125 }
01126
01127 signal (SIGINT, pSigintHandlerOld);
01128
01129 g_main_loop_unref (applicationdata.main_loop);
01130
01131 guint64 n_completed_buffers;
01132 guint64 n_failures;
01133 guint64 n_underruns;
01134 guint64 n_resent;
01135 guint64 n_missing;
01136 arv_stream_get_statistics ((ArvStream *)pStream, &n_completed_buffers, &n_failures, &n_underruns);
01137 ROS_INFO ("Completed buffers = %Lu", (unsigned long long) n_completed_buffers);
01138 ROS_INFO ("Failures = %Lu", (unsigned long long) n_failures);
01139 ROS_INFO ("Underruns = %Lu", (unsigned long long) n_underruns);
01140 arv_gv_stream_get_statistics (pStream, &n_resent, &n_missing);
01141 ROS_INFO ("Resent buffers = %Lu", (unsigned long long) n_resent);
01142 ROS_INFO ("Missing = %Lu", (unsigned long long) n_missing);
01143
01144 arv_device_execute_command (global.pDevice, "AcquisitionStop");
01145
01146 g_object_unref (pStream);
01147
01148 }
01149 else
01150 ROS_ERROR ("No cameras detected.");
01151
01152 delete global.phNode;
01153
01154 return 0;
01155 }
01156