Program Listing for File camera.hpp
↰ Return to documentation for file (include/spinnaker_camera_driver/camera.hpp
)
// -*-c++-*--------------------------------------------------------------------
// Copyright 2023 Bernd Pfrommer <bernd.pfrommer@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SPINNAKER_CAMERA_DRIVER__CAMERA_HPP_
#define SPINNAKER_CAMERA_DRIVER__CAMERA_HPP_
#include <camera_info_manager/camera_info_manager.hpp>
#include <deque>
#include <flir_camera_msgs/msg/camera_control.hpp>
#include <flir_camera_msgs/msg/image_meta_data.hpp>
#include <image_transport/image_transport.hpp>
#include <limits>
#include <map>
#include <memory>
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/camera_info.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <spinnaker_camera_driver/image.hpp>
#include <spinnaker_camera_driver/spinnaker_wrapper.hpp>
#include <spinnaker_camera_driver/synchronizer.hpp>
#include <std_msgs/msg/float64.hpp>
#include <thread>
namespace spinnaker_camera_driver
{
class ExposureController; // forward decl
class Camera
{
public:
using ImageConstPtr = spinnaker_camera_driver::ImageConstPtr;
explicit Camera(
rclcpp::Node * node, image_transport::ImageTransport * it, const std::string & prefix,
bool useStatus = true);
~Camera();
bool start();
bool stop();
void setSynchronizer(const std::shared_ptr<Synchronizer> & s) { synchronizer_ = s; }
void setExposureController(const std::shared_ptr<ExposureController> & e)
{
exposureController_ = e;
}
const std::string & getName() const { return (name_); }
const std::string & getPrefix() const { return (prefix_); }
private:
struct NodeInfo
{
enum NodeType { INVALID, ENUM, FLOAT, INT, BOOL, COMMAND };
explicit NodeInfo(const std::string & n, const std::string & nodeType);
std::string name;
NodeType type{INVALID};
rcl_interfaces::msg::ParameterDescriptor descriptor;
};
void processImage(const ImageConstPtr & image);
void readParameters();
void printCameraInfo();
void startCamera();
bool stopCamera();
void createCameraParameters();
void setParameter(const NodeInfo & ni, const rclcpp::Parameter & p);
bool setEnum(const std::string & nodeName, const std::string & v = "");
bool setDouble(const std::string & nodeName, double v);
bool setInt(const std::string & nodeName, int v);
bool setBool(const std::string & nodeName, bool v);
bool execute(const std::string & nodeName);
bool readParameterDefinitionFile();
rclcpp::Time getAdjustedTimeStamp(uint64_t t, int64_t sensorTime);
void run(); // thread
rcl_interfaces::msg::SetParametersResult parameterChanged(
const std::vector<rclcpp::Parameter> & params);
void controlCallback(const flir_camera_msgs::msg::CameraControl::UniquePtr msg);
void printStatus();
void checkSubscriptions();
void doPublish(const ImageConstPtr & im);
rclcpp::Logger get_logger()
{
return rclcpp::get_logger(
!name_.empty() ? name_ : (serial_.empty() ? std::string("camera") : serial_));
}
template <class T>
T safe_declare(const std::string & name, const T & def)
{
try {
return (node_->declare_parameter<T>(name, def));
} catch (const rclcpp::exceptions::ParameterAlreadyDeclaredException & e) {
T value;
(void)node_->get_parameter_or<T>(name, value, def);
return (value);
}
}
void safe_declare(
const std::string & name, const rclcpp::ParameterValue & pv,
const rcl_interfaces::msg::ParameterDescriptor & desc)
{
try {
node_->declare_parameter(name, pv, desc, false);
} catch (rclcpp::exceptions::InvalidParameterTypeException & e) {
RCLCPP_WARN_STREAM(
get_logger(), "overwriting bad param with default: " + std::string(e.what()));
node_->declare_parameter(name, pv, desc, true);
} catch (const rclcpp::exceptions::ParameterAlreadyDeclaredException & e) {
// do nothing
}
}
// ----- variables --
std::string prefix_;
std::string topicPrefix_;
rclcpp::Node * node_;
image_transport::ImageTransport * imageTransport_;
image_transport::CameraPublisher pub_;
rclcpp::Publisher<flir_camera_msgs::msg::ImageMetaData>::SharedPtr metaPub_;
std::string serial_;
std::string name_;
std::string cameraInfoURL_;
std::string frameId_;
std::string parameterFile_;
double frameRate_;
double exposureTime_; // in microseconds
bool autoExposure_; // if auto exposure is on/off
bool dumpNodeMap_{false};
bool debug_{false};
bool quiet_{false};
bool computeBrightness_{false};
double acquisitionTimeout_{3.0};
bool adjustTimeStamp_{false};
bool connectWhileSubscribed_{false}; // if true, connects to SDK when subscription happens
bool enableExternalControl_{false};
uint32_t currentExposureTime_{0};
double averageTimeDifference_{std::numeric_limits<double>::quiet_NaN()};
int64_t baseTimeOffset_{0};
float currentGain_{std::numeric_limits<float>::lowest()};
std::shared_ptr<spinnaker_camera_driver::SpinnakerWrapper> wrapper_;
std::shared_ptr<camera_info_manager::CameraInfoManager> infoManager_;
sensor_msgs::msg::Image imageMsg_;
sensor_msgs::msg::CameraInfo cameraInfoMsg_;
flir_camera_msgs::msg::ImageMetaData metaMsg_;
rclcpp::Node::OnSetParametersCallbackHandle::SharedPtr callbackHandle_; // keep alive callbacks
rclcpp::TimerBase::SharedPtr statusTimer_;
rclcpp::TimerBase::SharedPtr checkSubscriptionsTimer_;
bool cameraRunning_{false};
std::mutex mutex_;
std::condition_variable cv_;
std::deque<ImageConstPtr> bufferQueue_;
size_t maxBufferQueueSize_{4};
std::shared_ptr<std::thread> thread_;
bool keepRunning_{true};
std::map<std::string, NodeInfo> parameterMap_;
std::vector<std::string> parameterList_; // remember original ordering
rclcpp::Subscription<flir_camera_msgs::msg::CameraControl>::SharedPtr controlSub_;
uint32_t publishedCount_{0};
uint32_t droppedCount_{0};
uint32_t queuedCount_{0};
rclcpp::Time lastStatusTime_;
int qosDepth_{4};
std::shared_ptr<Synchronizer> synchronizer_;
std::shared_ptr<ExposureController> exposureController_;
bool firstSynchronizedFrame_{true};
};
} // namespace spinnaker_camera_driver
#endif // SPINNAKER_CAMERA_DRIVER__CAMERA_HPP_