camnode.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 
00003 
00004 // camera_aravis
00005 //
00006 // This is a ROS node that operates GenICam-based cameras via the Aravis library.
00007 // Commonly available camera features are supported through the dynamic_reconfigure user-interface and GUI,
00008 // and for those features not in the GUI but that are specific to a camera, they can be set in the
00009 // camera by setting the appropriate parameter at startup.  This code reads those parameters, and
00010 // if any of them match a camera feature, then the camera is written to.
00011 //
00012 // For example, if a camera has a feature called "IRFormat" that is an integer 0, 1, or 2, you can do
00013 // rosparam set camnode/IRFormat 2
00014 // and this driver will write it to the camera at startup.  Note that the datatype of the parameter
00015 // must be correct for the camera feature (e.g. bool, int, double, string, etc), so for example you should use
00016 // rosparam set camnode/GainAuto true
00017 // and NOT
00018 // rosparam set camnode/GainAuto 1
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 //#define TUNING        // Allows tuning the gains for the timestamp controller.  Publishes output on topic /dt, and receives gains on params /kp, /ki, /kd
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 // Global variables -------------------
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; // buffer->width and buffer->height not working, so I used a global.
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;       // Counter for Hz calculation.
00128 } ApplicationData;
00129 // ------------------------------------
00130 
00131 
00132 // Conversions from integers to Arv types.
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; // milliseconds
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                 // Load up some buffers.
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 } // CreateStream()
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     // Find what the user changed.
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     // Limit params to legal values.
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     // Adjust other controls dependent on what the user changed.
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     // Find what changed for any reason.
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     // Set params into the camera.
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                         //arv_device_set_integer_feature_value (global.pDevice, "GainRaw", config.GainRaw);
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                                 //config.GainRaw = arv_device_get_integer_feature_value (global.pDevice, "GainRaw");
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                         // The software rate is limited by the camera's internal framerate.  Bump up the camera's internal framerate if necessary.
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         // Recreate the software trigger callback.
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                 // Turn on software timer callback.
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 } // RosReconfigure_callback()
00457 
00458 
00459 static void NewBuffer_callback (ArvStream *pStream, ApplicationData *pApplicationdata)
00460 {
00461         static uint64_t  cm = 0L;       // Camera time prev
00462         uint64_t                 cn = 0L;       // Camera time now
00463 
00464 #ifdef TUNING                   
00465         static uint64_t  rm = 0L;       // ROS time prev
00466 #endif
00467         uint64_t                 rn = 0L;       // ROS time now
00468 
00469         static uint64_t  tm = 0L;       // Calculated image time prev
00470         uint64_t                 tn = 0L;       // Calculated image time now
00471                 
00472         static int64_t   em = 0L;       // Error prev.
00473         int64_t                  en = 0L;       // Error now between calculated image time and ROS time.
00474         int64_t                  de = 0L;       // derivative.
00475         int64_t                  ie = 0L;       // integral.
00476         int64_t                  u = 0L;        // Output of controller.
00477         
00478         int64_t                  kp1 = 0L;              // Fractional gains in integer form.
00479         int64_t                  kp2 = 1024L;
00480         int64_t                  kd1 = 0L;
00481         int64_t                  kd2 = 1024L;
00482         int64_t                  ki1 = -1L;             // A gentle pull toward zero.
00483         int64_t                  ki2 = 1024L;
00484 
00485         static uint32_t  iFrame = 0;    // Frame counter.
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                         // Camera/ROS Timestamp coordination.
00528                         cn                              = (uint64_t)pBuffer->timestamp_ns;                              // Camera now
00529                         rn                              = ros::Time::now().toNSec();                                    // ROS now
00530                         
00531                         if (iFrame < 10)
00532                         {
00533                                 cm = cn;
00534                                 tm  = rn;
00535                         }
00536                         
00537                         // Control the error between the computed image timestamp and the ROS timestamp.
00538                         en = (int64_t)tm + (int64_t)cn - (int64_t)cm - (int64_t)rn; // i.e. tn-rn, but calced from prior values.
00539                         de = en-em;
00540                         ie += en;
00541                         u = kp1*(en/kp2) + ki1*(ie/ki2) + kd1*(de/kd2);  // kp<0, ki<0, kd>0
00542                         
00543                         // Compute the new timestamp.
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; //cn-cm+tn-tm; //
00550                         global.ppubInt64->publish(msgInt64);
00551                         rm = rn;
00552 #endif
00553                         
00554                         // Save prior values.
00555                         cm = cn;
00556                         tm = tn;
00557                         em = en;
00558                         
00559                         // Construct the image message.
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                         // get current CameraInfo data
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 } // NewBuffer_callback()
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 // PeriodicTask_callback()
00605 // Check for termination, and spin for ROS.
00606 static gboolean PeriodicTask_callback (void *applicationdata)
00607 {
00608     ApplicationData *pData = (ApplicationData*)applicationdata;
00609 
00610     //  ROS_INFO ("Frame rate = %d Hz", pData->nBuffers);
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 } // PeriodicTask_callback()
00623 
00624 
00625 // Get the child and the child's sibling, where <p___> indicates an indirection.
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                         // Do the indirection.
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         //ROS_INFO("GFC name=%s, node=%p, sib=%p", szNameChild, nodeex.pNode, nodeex.pNodeSibling);
00661 
00662         
00663         return nodeex;
00664 } // GetGcFirstChild()
00665 
00666 
00667 // Get the sibling and the sibling's sibling, where <p___> indicates an indirection.
00668 NODEEX GetGcNextSibling(ArvGc *pGenicam, NODEEX nodeex)
00669 {
00670         const char *szName=0;
00671 
00672         // Go to the sibling.
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                 // Do the indirection.
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         //ROS_INFO("GNS name=%s, node=%p, sib=%p", nodeex.szName, nodeex.pNode, nodeex.pNodeSibling);
00699 
00700         
00701         return nodeex;
00702 } // GetGcNextSibling()
00703 
00704 
00705 // Walk the DOM tree, i.e. the tree represented by the XML file in the camera, and that contains all the various features, parameters, etc.
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                         // Go to the next sibling.
00733                         nodeex = GetGcNextSibling(pGenicam, nodeex);
00734 
00735                 } while (nodeex.pNode && nodeex.pNodeSibling);
00736         }
00737 } //PrintDOMTree()
00738 
00739 
00740 // WriteCameraFeaturesFromRosparam()
00741 // Read ROS parameters from this node's namespace, and see if each parameter has a similarly named & typed feature in the camera.  Then set the
00742 // camera feature to that value.  For example, if the parameter camnode/Gain is set to 123.0, then we'll write 123.0 to the Gain feature
00743 // in the camera.
00744 //
00745 // Note that the datatype of the parameter *must* match the datatype of the camera feature, and this can be determined by
00746 // looking at the camera's XML file.  Camera enum's are string parameters, camera bools are false/true parameters (not 0/1),
00747 // integers are integers, doubles are doubles, etc.
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 //                              unsigned long   typeValue = arv_gc_feature_node_get_value_type((ArvGcFeatureNode *)pGcNode);
00770 //                              ROS_INFO("%s cameratype=%lu, rosparamtype=%d", key.c_str(), typeValue, static_cast<int>(iter->second.getType()));
00771 
00772                                 // We'd like to check the value types too, but typeValue is often given as G_TYPE_INVALID, so ignore it.
00773                                 switch (iter->second.getType())
00774                                 {
00775                                         case XmlRpc::XmlRpcValue::TypeBoolean://if ((iter->second.getType()==XmlRpc::XmlRpcValue::TypeBoolean))// && (typeValue==G_TYPE_INT64))
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: //if ((iter->second.getType()==XmlRpc::XmlRpcValue::TypeInt))// && (typeValue==G_TYPE_INT64))
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: //if ((iter->second.getType()==XmlRpc::XmlRpcValue::TypeDouble))// && (typeValue==G_TYPE_DOUBLE))
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: //if ((iter->second.getType()==XmlRpc::XmlRpcValue::TypeString))// && (typeValue==G_TYPE_STRING))
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 } // WriteCameraFeaturesFromRosparam()
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     //g_type_init ();
00845 
00846     // Print out some useful info.
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                 // Get the camera guid from either the command-line or as a parameter.
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         // Open the camera, and set it up.
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                 // See if some basic camera features exist.
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                 // Find the key name for framerate.
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                 // Get parameter bounds.
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                 // Initial camera settings.
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                         //arv_device_set_integer_feature_value(global.pDevice, "GainRaw", global.config.GainRaw);
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                 // Set up the triggering.
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                 // Start the camerainfo manager.
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                 // Start the dynamic_reconfigure server.
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                 // Get parameter current values.
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                 // Print information.
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 //              // Print the tree of camera features, with their values.
01071 //              ROS_INFO ("    ----------------------------------------------------------------------------------");
01072 //              NODEEX           nodeex;
01073 //              ArvGc   *pGenicam=0;
01074 //              pGenicam = arv_device_get_genicam(global.pDevice);
01075 //
01076 //              nodeex.szName = "Root";
01077 //              nodeex.pNode = (ArvDomNode      *)arv_gc_get_node(pGenicam, nodeex.szName);
01078 //              nodeex.pNodeSibling = NULL;
01079 //              PrintDOMTree(pGenicam, nodeex, 0);
01080 //              ROS_INFO ("    ----------------------------------------------------------------------------------");
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                 // Set up image_raw.
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                 // Connect signals with callbacks.
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 } // main()
01156 


camera_aravis
Author(s): Steve Safarik , Andrew Straw , strawlab, Steve Safarik
autogenerated on Fri Aug 28 2015 10:13:44