mirror of
https://github.com/OSURoboticsClub/Rover_2017_2018.git
synced 2025-11-08 10:11:14 +00:00
Got udev rules working for usb serial devices and cameras on rover
This commit is contained in:
15
environment_reference/UDEV Rules/99-rover-cameras.rules
Normal file
15
environment_reference/UDEV Rules/99-rover-cameras.rules
Normal file
@@ -0,0 +1,15 @@
|
||||
# udevadm info -a -p $(udevadm info -q path -n /dev/video2)
|
||||
# ATTRS{serial}=="B9A8A5FF", MODE="0660",GROUP="nvidia",
|
||||
# SUBSYSTEM=="video4linux",ATTRS{idVendor}=="0x046d",ATTRS{idProduct}=="0x082d",NAME="videoext"
|
||||
|
||||
# The zed camera
|
||||
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="2b03", ATTRS{idProduct}=="f580", SYMLINK+="rover/cam_zed"
|
||||
|
||||
# The first C920 Webcam
|
||||
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="082d", ATTRS{serial}=="B9A8A5FF", SYMLINK+="rover/cam_undercarriage"
|
||||
|
||||
# The second C920 Webcam
|
||||
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="082d", ATTRS{serial}=="A98AA5FF", SYMLINK+="rover/cam_grasper"
|
||||
|
||||
# The special main nav cam
|
||||
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="05a3", ATTRS{idProduct}=="9422", ATTRS{serial}=="SN0001", SYMLINK+="rover/cam_main_nav"
|
||||
@@ -0,0 +1 @@
|
||||
SUBSYSTEM=="tty", ATTRS{serial}=="A5027JQW", SYMLINK+="rover/ttyARM"
|
||||
3
environment_reference/UDEV Rules/install_rules.sh
Executable file
3
environment_reference/UDEV Rules/install_rules.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
sudo cp 99-rover-cameras.rules /etc/udev/rules.d/.
|
||||
sudo cp 99-rover-usb-serial.rules /etc/udev/rules.d/.
|
||||
1
rover/CMakeLists.txt
Symbolic link
1
rover/CMakeLists.txt
Symbolic link
@@ -0,0 +1 @@
|
||||
/opt/ros/kinetic/share/catkin/cmake/toplevel.cmake
|
||||
@@ -1,105 +0,0 @@
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Changelog for package gscam
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
0.1.3 (2013-12-19)
|
||||
------------------
|
||||
* Removed special characters from changelog.
|
||||
|
||||
0.1.2 (2013-12-19)
|
||||
------------------
|
||||
* Added install targets for headers
|
||||
* Adding note on blackmagic decklink cards
|
||||
* Make sure nodelets are usable
|
||||
* Add jpeg direct publishing without decoding
|
||||
* Added system to use GST timestamps
|
||||
* Valid test file for jpeg-based publisher
|
||||
* Prepared for jpeg-only subscription
|
||||
* Install some launch files + added nodelet pipeline demo
|
||||
* Added missing bits to install the nodelet
|
||||
* Support for gray (mono8) cameras.
|
||||
* Remove unused ``bpp_`` member.
|
||||
* Expose default settings for ``image_encodings`` to the ros master.
|
||||
* Add in support for mono cameras.
|
||||
* Contributors: Cedric Pradalier, Holger Rapp, Jonathan Bohren, Russell Toris, Severin Lemaignan
|
||||
|
||||
0.1.1 (2013-05-30)
|
||||
------------------
|
||||
* adding missing nodelet dep
|
||||
* Contributors: Jonathan Bohren
|
||||
|
||||
0.1.0 (2013-05-28)
|
||||
------------------
|
||||
* adding maintainer/authors
|
||||
* making node name backwards compatible
|
||||
* re-adding package.xml
|
||||
* more info spam
|
||||
* removing old camera parameters file
|
||||
* updating gscam to use ``camera_info_manager``
|
||||
* Fixing nodelet, adding example
|
||||
* Making gscam a node and nodeelt
|
||||
* adding a note on the videofile player and wrapping readme
|
||||
* adding option to reopen a stream on EOF and adding a videofile example
|
||||
* Hybrid catkin-rosbuild buildsystem
|
||||
* adding minoru example
|
||||
* putting example nodes into namespaces, adding correct error check in gscam source, making tf frame publishing optional
|
||||
* rst->md
|
||||
* making gscam conform to standard ``camera_drivers`` ROS API, note, still need to add polled mode
|
||||
* fixes for decklink capture, adding another example
|
||||
* can't have manifest.xml and package.xml in same directory
|
||||
* removing unneeded find-pkgs
|
||||
* building in catkin ws
|
||||
* hybrid rosbuild/catkin buildsystem
|
||||
* Adding changes that were made to the distribution branch that
|
||||
should have gone into the exerpeimental branch in r2862.
|
||||
Added a bunch of enhancements and fixed bugs involving data
|
||||
missing fromthe image message headers.
|
||||
Index: src/gscam.cpp
|
||||
===================================================================
|
||||
Added ``camera_name`` and ``camera_parameters_file`` globals for camera
|
||||
info.
|
||||
Moved ros init to the top of the main function.
|
||||
Gets the gstreamer configuration either from environment variable
|
||||
``GSCAM_CONFIG`` or ROS param ``~/gscam_config``.
|
||||
Gets the camera calibration parameters from the file located at ROS
|
||||
param ``~/camera_parameters_file``, will look at
|
||||
"../camera_settings.txt" by default.
|
||||
A bunch of re-indenting for consistency.
|
||||
Updated a lot of error fprintfs to ``ROS_ERROR`` calls.
|
||||
Gets the TF ``frame_id`` from the ROS param ``~/frame_id``, can be over-
|
||||
written by camera parameters.
|
||||
Now sets the appropriate ROS timestap in the image message header.
|
||||
Now sets the appropriate TF frame in the image message header.
|
||||
Added more detailed info/error/warn messages.
|
||||
Modified the warning / segfault avoidance added to experimental in
|
||||
r2756. Instead of skipping the frame, it just copies only the
|
||||
amount of data that it was received, and reports the warning each
|
||||
time, instead of just once. In a large scale system with lots of
|
||||
messages, a single warning might easily get lost in the noise.
|
||||
Index: examples/webcam_parameters.txt
|
||||
===================================================================
|
||||
Added example camera parameters (uncalibrated) for a laptop webcam.
|
||||
Index: examples/webcam.launch
|
||||
===================================================================
|
||||
Added a launchfile that makes use of the new rosparam options and
|
||||
TF frame.
|
||||
* avoid segfault when buffer size is too small
|
||||
* ROSProcessingjs clean-up
|
||||
* makefile so rosmake is more reliable
|
||||
* gscam build tweak for oneiric
|
||||
* fixes for Natty build per Willow request
|
||||
* stop node on EOS
|
||||
* File support courtesy of John Hoare of the University of Tennesse at Knoxville
|
||||
* more conservative license policy
|
||||
* fps workaround
|
||||
* ding gscam
|
||||
* back to before
|
||||
* two publishers
|
||||
* Lots of changes. AR Alpha now expects files in the bin directory, to facilitate roslaunch. Gscam must be started from the bin directory, or, again, using roslaunch. The localizer code now works correctly and has been tested on a Create, but has problems cause by AR alpha's processing delays.
|
||||
* Bugfix: supply default camera parameters when real ones are unavailable.
|
||||
* Fully-functional calibration file writing.
|
||||
* Partial changes for file-writing gscam.
|
||||
* Gscam now fits into an image processing pipeline with rectified images. TODO: Save camera configuration info.
|
||||
* Handles built for camera info services, but no testing.
|
||||
* Changed the name of the GStreamer camera package. probe will henceforth be known as gscam.
|
||||
* Contributors: Jonathan Bohren, chriscrick, evan.exe@gmail.com, nevernim@gmail.com, trevorjay
|
||||
@@ -1,118 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
|
||||
project(gscam)
|
||||
|
||||
# System Dependencies
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(GSTREAMER REQUIRED gstreamer-0.10)
|
||||
pkg_check_modules(GST_APP REQUIRED gstreamer-app-0.10)
|
||||
|
||||
if(USE_ROSBUILD)
|
||||
# Use rosbuild
|
||||
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
|
||||
|
||||
rosbuild_init()
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
|
||||
|
||||
include_directories(${GLIB_INCLUDE_DIRS} ${GST_APP_INCLUDE_DIRS})
|
||||
|
||||
rosbuild_add_library(gscam src/gscam.cpp)
|
||||
target_link_libraries(gscam
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
|
||||
rosbuild_add_executable(gscam_node src/gscam_node.cpp)
|
||||
target_link_libraries(gscam_node gscam
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
set_target_properties(gscam_node PROPERTIES OUTPUT_NAME gscam)
|
||||
|
||||
rosbuild_add_library(GSCamNodelet src/gscam_nodelet.cpp)
|
||||
target_link_libraries(GSCamNodelet gscam
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
|
||||
else()
|
||||
# Use Catkin
|
||||
find_package(catkin REQUIRED
|
||||
COMPONENTS roscpp image_transport sensor_msgs nodelet
|
||||
camera_calibration_parsers camera_info_manager
|
||||
)
|
||||
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
LIBRARIES gscam
|
||||
CATKIN_DEPENDS roscpp nodelet image_transport sensor_msgs
|
||||
camera_calibration_parsers camera_info_manager
|
||||
DEPENDS GSTREAMER GST_APP
|
||||
)
|
||||
|
||||
include_directories(
|
||||
include
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${GLIB_INCLUDE_DIRS}
|
||||
${GST_APP_INCLUDE_DIRS})
|
||||
|
||||
add_library(gscam src/gscam.cpp)
|
||||
target_link_libraries(gscam
|
||||
${catkin_LIBRARIES}
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
|
||||
add_executable(gscam_node src/gscam_node.cpp)
|
||||
target_link_libraries(gscam_node gscam
|
||||
${catkin_LIBRARIES}
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
set_target_properties(gscam_node PROPERTIES OUTPUT_NAME gscam)
|
||||
|
||||
add_library(GSCamNodelet src/gscam_nodelet.cpp)
|
||||
target_link_libraries(GSCamNodelet gscam
|
||||
${catkin_LIBRARIES}
|
||||
${GSTREAMER_LIBRARIES}
|
||||
${GST_APP_LIBRARIES})
|
||||
|
||||
# Install directives
|
||||
|
||||
install(TARGETS gscam gscam_node GSCamNodelet
|
||||
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
)
|
||||
|
||||
install(DIRECTORY include/${PROJECT_NAME}/
|
||||
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
PATTERN ".svn" EXCLUDE)
|
||||
|
||||
install(FILES nodelet_plugins.xml
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
)
|
||||
|
||||
install(FILES
|
||||
examples/v4l.launch
|
||||
examples/gscam_nodelet.launch
|
||||
examples/nodelet_pipeline.launch
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
)
|
||||
|
||||
install(FILES examples/uncalibrated_parameters.ini
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/examples
|
||||
)
|
||||
|
||||
# Interim compatibility
|
||||
# Remove this in the next release
|
||||
install(FILES ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/gscam_node
|
||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CATKIN_DEVEL_PREFIX}/lib/${PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
# Interim compatibility
|
||||
# Remove this in the next distribution release
|
||||
configure_file(scripts/gscam_node.in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/gscam_node)
|
||||
file(COPY ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/gscam_node
|
||||
DESTINATION ${EXECUTABLE_OUTPUT_PATH}
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
EXTRA_CMAKE_FLAGS = -DUSE_ROSBUILD:BOOL=1
|
||||
include $(shell rospack find mk)/cmake.mk
|
||||
@@ -1,56 +0,0 @@
|
||||
GSCam
|
||||
=====
|
||||
|
||||
This is a ROS package originally developed by the [Brown Robotics
|
||||
Lab](http://robotics.cs.brown.edu/) for broadcasting any
|
||||
[GStreamer](http://gstreamer.freedesktop.org/)-based video stream via the
|
||||
standard [ROS Camera API](http://ros.org/wiki/camera_drivers). This fork has
|
||||
several fixes incorporated into it to make it broadcast correct
|
||||
`sensor_msgs/Image` messages with proper frames and timestamps. It also allows
|
||||
for more ROS-like configuration and more control over the GStreamer interface.
|
||||
|
||||
Note that this pacakge can be built both in a rosbuild and catkin workspaces.
|
||||
|
||||
ROS API (stable)
|
||||
----------------
|
||||
|
||||
### gscam
|
||||
|
||||
This can be run as both a node and a nodelet.
|
||||
|
||||
#### Nodes
|
||||
* `gscam`
|
||||
|
||||
#### Topics
|
||||
* `camera/image_raw`
|
||||
* `camera/camera_info`
|
||||
|
||||
#### Services
|
||||
* `camera/set_camera_info`
|
||||
|
||||
#### Parameters
|
||||
* `~camera_name`: The name of the camera (corrsponding to the camera info)
|
||||
* `~camera_info_url`: A url (`file://path/to/file`, `package://pkg_name/path/to/file`) to the [camera calibration file](http://www.ros.org/wiki/camera_calibration_parsers#File_formats).
|
||||
* `~gscam_config`: The GStreamer [configuration string](http://wiki.oz9aec.net/index.php?title=Gstreamer_cheat_sheet&oldid=1829).
|
||||
* `~frame_id`: The [TF](http://www.ros.org/wiki/tf) frame ID.
|
||||
* `~reopen_on_eof`: Re-open the stream if it ends (EOF).
|
||||
* `~sync_sink`: Synchronize the app sink (sometimes setting this to `false` can resolve problems with sub-par framerates).
|
||||
|
||||
C++ API (unstable)
|
||||
------------------
|
||||
|
||||
The gscam c++ library can be used, but it is not guaranteed to be stable.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
See example launchfiles and configs in the examples directory. Currently there
|
||||
are examples for:
|
||||
* [Video4Linux2](examples/v4l.launch): Standard
|
||||
[video4linux](http://en.wikipedia.org/wiki/Video4Linux)-based cameras like
|
||||
USB webcams
|
||||
* [Nodelet](examples/gscam_nodelet.launch): Run a V4L-based camera in a nodelet
|
||||
* [Video File](examples/videofile.launch): Any videofile readable by GStreamer
|
||||
* [DeckLink](examples/decklink.launch):
|
||||
[BlackMagic](http://www.blackmagicdesign.com/products/decklink/models)
|
||||
DeckLink SDI capture cards (note: this requires the `gst-plugins-bad` plugins)
|
||||
@@ -1,22 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /decklink/image_raw from the input channel of a BlackMagic
|
||||
DeckLink SDI capture card-->
|
||||
|
||||
<!-- DeckLink config, run $ gst-inspect decklinksrc to see all the options for your card -->
|
||||
<arg name="MODE" default="ntsc"/>
|
||||
<arg name="CONNECTION" default="sdi"/>
|
||||
<arg name="SUBDEVICE" default="0"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<node ns="decklink" name="gscam_driver_decklink" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="decklinksrc mode=$(arg MODE) connection=$(arg CONNECTION) subdevice=$(arg SUBDEVICE) ! ffmpegcolorspace "/>
|
||||
<param name="frame_id" value="/decklink_frame"/>
|
||||
<!-- This needs to be set to false to avoid dropping tons of frames -->
|
||||
<param name="sync_sink" value="false"/>
|
||||
</node>
|
||||
|
||||
<node name="decklink_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /decklink_frame 10"/>
|
||||
</launch>
|
||||
@@ -1,20 +0,0 @@
|
||||
<launch>
|
||||
<arg name="DEVICE" default="/dev/video0"/>
|
||||
<!-- The GStreamer framerate needs to be an integral fraction -->
|
||||
<arg name="FPS" default="30/1"/>
|
||||
|
||||
<node pkg="nodelet" type="nodelet"
|
||||
name="standalone_nodelet" args="manager"
|
||||
output="screen"/>
|
||||
|
||||
<node pkg="nodelet" type="nodelet"
|
||||
name="GSCamNodelet"
|
||||
args="load gscam/GSCamNodelet standalone_nodelet"
|
||||
output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="v4l2src device=$(arg DEVICE) ! video/x-raw-rgb,framerate=$(arg FPS) ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/v4l_frame"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
</launch>
|
||||
@@ -1,39 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /webcam/image_raw -->
|
||||
|
||||
<arg name="LEFT_DEV" default="/dev/video0"/>
|
||||
<arg name="RIGHT_DEV" default="/dev/video1"/>
|
||||
<!-- The GStreamer framerate needs to be an integral fraction -->
|
||||
<!-- Note: Minoru can't push full 640x480 at 30fps -->
|
||||
<arg name="WIDTH" default="320"/>
|
||||
<arg name="HEIGHT" default="240"/>
|
||||
<arg name="FPS" default="30/1"/>
|
||||
<arg name="BRIGHTNESS" default="0"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<!-- Construct the v4l2src format config -->
|
||||
<arg name="FORMAT" default="video/x-raw-rgb,width=$(arg WIDTH),height=$(arg HEIGHT),framerate=$(arg FPS)"/>
|
||||
|
||||
<group ns="minoru">
|
||||
<node ns="left" name="gscam_driver_v4l" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config"
|
||||
value="v4l2src device=$(arg LEFT_DEV) brightness=$(arg BRIGHTNESS) ! $(arg FORMAT) ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/minoru_left"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
<node ns="right" name="gscam_driver_v4l" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config"
|
||||
value="v4l2src device=$(arg RIGHT_DEV) brightness=$(arg BRIGHTNESS) ! $(arg FORMAT) ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/minoru_right"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
</group>
|
||||
|
||||
<node if="$(arg PUBLISH_FRAME)" name="left_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /minoru_left 10"/>
|
||||
<node if="$(arg PUBLISH_FRAME)" name="right_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /minoru_right 10"/>
|
||||
</launch>
|
||||
@@ -1,41 +0,0 @@
|
||||
<!-- -*- mode: XML -*- -->
|
||||
|
||||
<!-- Load Bayer color correction and recification into camera nodelet
|
||||
manager process.
|
||||
|
||||
this is a test script: NOT FOR GENERAL USE
|
||||
|
||||
-->
|
||||
|
||||
<launch>
|
||||
|
||||
<!-- start the driver in a camera_nodelet_manager process -->
|
||||
<include file="$(find gscam)/gscam_nodelet.launch" >
|
||||
</include>
|
||||
|
||||
<!-- Bayer color decoding -->
|
||||
<node pkg="nodelet" type="nodelet" name="image_proc_debayer"
|
||||
args="load image_proc/debayer camera_nodelet_manager">
|
||||
<remap from="camera_info" to="camera/camera_info" />
|
||||
<remap from="image_color" to="camera/image_color" />
|
||||
<remap from="image_mono" to="camera/image_mono" />
|
||||
<remap from="image_raw" to="camera/image_raw" />
|
||||
</node>
|
||||
|
||||
<!-- mono rectification -->
|
||||
<node pkg="nodelet" type="nodelet" name="image_proc_rect"
|
||||
args="load image_proc/rectify camera_nodelet_manager">
|
||||
<remap from="camera_info" to="camera/camera_info" />
|
||||
<remap from="image_mono" to="camera/image_mono" />
|
||||
<remap from="image_rect" to="camera/image_rect" />
|
||||
</node>
|
||||
|
||||
<!-- color rectification -->
|
||||
<node pkg="nodelet" type="nodelet" name="image_proc_rect_color"
|
||||
args="load image_proc/rectify camera_nodelet_manager">
|
||||
<remap from="camera_info" to="camera/camera_info" />
|
||||
<remap from="image_mono" to="camera/image_color" />
|
||||
<remap from="image_rect" to="camera/image_rect_color" />
|
||||
</node>
|
||||
|
||||
</launch>
|
||||
@@ -1,20 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /webcam/image_raw -->
|
||||
|
||||
<!-- The GStreamer device-index needs to be an integer -->
|
||||
<arg name="DEVICE_INDEX" default="0"/>
|
||||
<!-- The GStreamer framerate needs to be an integral fraction -->
|
||||
<arg name="FPS" default="30/1"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<node ns="qtkit" name="gscam_driver_qtkit" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="qtkitvideosrc device-index=$(arg DEVICE_INDEX) ! video/x-raw-yuv,framerate=$(arg FPS) ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/qtkit_frame"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
|
||||
<node if="$(arg PUBLISH_FRAME)" name="qtkit_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /qtkit_frame 10"/>
|
||||
</launch>
|
||||
@@ -1,30 +0,0 @@
|
||||
# Camera intrinsics
|
||||
|
||||
[image]
|
||||
|
||||
width
|
||||
320
|
||||
|
||||
height
|
||||
240
|
||||
|
||||
[default]
|
||||
|
||||
camera matrix
|
||||
467.14110 0.00000 158.56653
|
||||
0.00000 465.42608 131.37432
|
||||
0.00000 0.00000 1.00000
|
||||
|
||||
distortion
|
||||
-0.16999 0.31931 0.00929 0.00040 0.00000
|
||||
|
||||
|
||||
rectification
|
||||
1.00000 0.00000 0.00000
|
||||
0.00000 1.00000 0.00000
|
||||
0.00000 0.00000 1.00000
|
||||
|
||||
projection
|
||||
458.62505 0.00000 158.11160 0.00000
|
||||
0.00000 457.90904 131.91881 0.00000
|
||||
0.00000 0.00000 1.00000 0.00000
|
||||
@@ -1,19 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /webcam/image_raw -->
|
||||
|
||||
<arg name="DEVICE" default="/dev/video0"/>
|
||||
<!-- The GStreamer framerate needs to be an integral fraction -->
|
||||
<arg name="FPS" default="30/1"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<node ns="v4l" name="gscam_driver_v4l" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="v4l2src device=$(arg DEVICE) ! video/x-raw-rgb,framerate=$(arg FPS) ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/v4l_frame"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
|
||||
<node if="$(arg PUBLISH_FRAME)" name="v4l_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /v4l_frame 10"/>
|
||||
</launch>
|
||||
@@ -1,20 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /webcam/image_raw -->
|
||||
|
||||
<arg name="DEVICE" default="/dev/video0"/>
|
||||
<!-- The GStreamer framerate needs to be an integral fraction -->
|
||||
<arg name="FPS" default="30/1"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<node ns="v4l" name="gscam_driver_v4l" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="v4l2src do-timestamp=true is-live=true ! video/x-raw-yuv ! jpegenc ! multipartmux ! multipartdemux ! jpegparse"/>
|
||||
<param name="use_gst_timestamps" value="true"/>
|
||||
<param name="image_encoding" value="jpeg"/>
|
||||
<param name="frame_id" value="/v4l_frame"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
</node>
|
||||
|
||||
</launch>
|
||||
@@ -1,19 +0,0 @@
|
||||
<launch>
|
||||
<!-- This launchfile should bring up a node that broadcasts a ros image
|
||||
transport on /videofile/image_raw -->
|
||||
|
||||
<arg name="FILENAME"/>
|
||||
<arg name="LOOP" default="true"/>
|
||||
<arg name="PUBLISH_FRAME" default="false"/>
|
||||
|
||||
<node ns="videofile" name="gscam_driver_v4l" pkg="gscam" type="gscam" output="screen">
|
||||
<param name="camera_name" value="default"/>
|
||||
<param name="camera_info_url" value="package://gscam/examples/uncalibrated_parameters.ini"/>
|
||||
<param name="gscam_config" value="filesrc location=$(arg FILENAME) ! decodebin ! ffmpegcolorspace"/>
|
||||
<param name="frame_id" value="/videofile_frame"/>
|
||||
<param name="sync_sink" value="true"/>
|
||||
<param name="reopen_on_eof" value="$(arg LOOP)"/>
|
||||
</node>
|
||||
|
||||
<node if="$(arg PUBLISH_FRAME)" name="videofile_transform" pkg="tf" type="static_transform_publisher" args="1 2 3 0 -3.141 0 /world /videofile_frame 10"/>
|
||||
</launch>
|
||||
@@ -1,69 +0,0 @@
|
||||
#ifndef __GSCAM_GSCAM_H
|
||||
#define __GSCAM_GSCAM_H
|
||||
|
||||
extern "C"{
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
}
|
||||
|
||||
#include <ros/ros.h>
|
||||
|
||||
#include <image_transport/image_transport.h>
|
||||
#include <camera_info_manager/camera_info_manager.h>
|
||||
|
||||
#include <sensor_msgs/Image.h>
|
||||
#include <sensor_msgs/CameraInfo.h>
|
||||
#include <sensor_msgs/SetCameraInfo.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace gscam {
|
||||
|
||||
class GSCam {
|
||||
public:
|
||||
GSCam(ros::NodeHandle nh_camera, ros::NodeHandle nh_private);
|
||||
~GSCam();
|
||||
|
||||
bool configure();
|
||||
bool init_stream();
|
||||
void publish_stream();
|
||||
void cleanup_stream();
|
||||
|
||||
void run();
|
||||
|
||||
private:
|
||||
// General gstreamer configuration
|
||||
std::string gsconfig_;
|
||||
|
||||
// Gstreamer structures
|
||||
GstElement *pipeline_;
|
||||
GstElement *sink_;
|
||||
|
||||
// Appsink configuration
|
||||
bool sync_sink_;
|
||||
bool preroll_;
|
||||
bool reopen_on_eof_;
|
||||
bool use_gst_timestamps_;
|
||||
|
||||
// Camera publisher configuration
|
||||
std::string frame_id_;
|
||||
int width_, height_;
|
||||
std::string image_encoding_;
|
||||
std::string camera_name_;
|
||||
std::string camera_info_url_;
|
||||
|
||||
// ROS Inteface
|
||||
// Calibration between ros::Time and gst timestamps
|
||||
double time_offset_;
|
||||
ros::NodeHandle nh_, nh_private_;
|
||||
image_transport::ImageTransport image_transport_;
|
||||
camera_info_manager::CameraInfoManager camera_info_manager_;
|
||||
image_transport::CameraPublisher camera_pub_;
|
||||
// Case of a jpeg only publisher
|
||||
ros::Publisher jpeg_pub_;
|
||||
ros::Publisher cinfo_pub_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ifndef __GSCAM_GSCAM_H
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef __GSCAM_GSCAM_NODELET_H
|
||||
#define __GSCAM_GSCAM_NODELET_H
|
||||
|
||||
#include <nodelet/nodelet.h>
|
||||
|
||||
#include <gscam/gscam.h>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
namespace gscam {
|
||||
class GSCamNodelet : public nodelet::Nodelet
|
||||
{
|
||||
public:
|
||||
GSCamNodelet();
|
||||
~GSCamNodelet();
|
||||
|
||||
virtual void onInit();
|
||||
|
||||
private:
|
||||
boost::scoped_ptr<GSCam> gscam_driver_;
|
||||
boost::scoped_ptr<boost::thread> stream_thread_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // infdef __GSCAM_GSCAM_NODELET_H
|
||||
@@ -1,25 +0,0 @@
|
||||
<package>
|
||||
<description brief="gscam">
|
||||
A ROS camera driver that uses gstreamer to connect to devices such as webcams.
|
||||
</description>
|
||||
<author>Graylin Trevor Jay, Christopher Crick</author>
|
||||
<email>tjay@cs.brown.edu, chriscrick@cs.brown.edu</email>
|
||||
<license>LGPL</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
|
||||
<rosdep name="libgstreamer0.10-dev"/>
|
||||
<rosdep name="libgstreamer-plugins-base0.10-dev"/>
|
||||
<depend package="roscpp"/>
|
||||
<depend package="image_transport"/>
|
||||
<depend package="sensor_msgs"/>
|
||||
<depend package="camera_calibration_parsers" />
|
||||
<depend package="camera_info_manager" />
|
||||
<depend package="nodelet" />
|
||||
|
||||
<export>
|
||||
<nodelet plugin="${prefix}/nodelet_plugins.xml" />
|
||||
</export>
|
||||
|
||||
</package>
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<library path="lib/libGSCamNodelet">
|
||||
<class
|
||||
name="gscam/GSCamNodelet"
|
||||
type="gscam::GSCamNodelet"
|
||||
base_class_type="nodelet::Nodelet">
|
||||
<description>
|
||||
Nodelet for publishing a ROS camera interface from a GStreamer stream.
|
||||
</description>
|
||||
</class>
|
||||
</library>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
<package>
|
||||
<name>gscam</name>
|
||||
<version>0.1.3</version>
|
||||
<description>
|
||||
A ROS camera driver that uses gstreamer to connect to
|
||||
devices such as webcams.
|
||||
</description>
|
||||
<maintainer email="jbo@jhu.edu">Jonathan Bohren</maintainer>
|
||||
<license>BSD</license>
|
||||
|
||||
<author email="jbo@jhu.edu">Jonathan Bohren</author>
|
||||
<author email="tjay@cs.brown.edu">Graylin Trevor Jay</author>
|
||||
<author email="chriscrick@cs.brown.edu">Christopher Crick</author>
|
||||
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<build_depend>libgstreamer0.10-dev</build_depend>
|
||||
<build_depend>libgstreamer-plugins-base0.10-dev</build_depend>
|
||||
|
||||
<build_depend>nodelet</build_depend>
|
||||
<build_depend>cv_bridge</build_depend>
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>image_transport</build_depend>
|
||||
<build_depend>sensor_msgs</build_depend>
|
||||
<build_depend>camera_calibration_parsers</build_depend>
|
||||
<build_depend>camera_info_manager</build_depend>
|
||||
|
||||
<run_depend>nodelet</run_depend>
|
||||
<run_depend>cv_bridge</run_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>image_transport</run_depend>
|
||||
<run_depend>sensor_msgs</run_depend>
|
||||
<run_depend>camera_calibration_parsers</run_depend>
|
||||
<run_depend>camera_info_manager</run_depend>
|
||||
|
||||
<export>
|
||||
<nodelet plugin="${prefix}/nodelet_plugins.xml"/>
|
||||
</export>
|
||||
|
||||
|
||||
</package>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
libgstreamer0.10-dev:
|
||||
ubuntu:
|
||||
libgstreamer0.10-dev
|
||||
libgstreamer-plugins-base0.10-dev:
|
||||
ubuntu:
|
||||
libgstreamer-plugins-base0.10-dev
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo '[WARNING] gscam_node is an interim dependency and will be removed in the next release! Please change all launchfiles back to use "gscam" instead of "gscam_node"'
|
||||
|
||||
${EXECUTABLE_OUTPUT_PATH}/gscam
|
||||
@@ -1,403 +0,0 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
extern "C"{
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
}
|
||||
|
||||
#include <ros/ros.h>
|
||||
|
||||
#include <image_transport/image_transport.h>
|
||||
#include <camera_info_manager/camera_info_manager.h>
|
||||
|
||||
|
||||
#include <sensor_msgs/Image.h>
|
||||
#include <sensor_msgs/CompressedImage.h>
|
||||
#include <sensor_msgs/CameraInfo.h>
|
||||
#include <sensor_msgs/SetCameraInfo.h>
|
||||
#include <sensor_msgs/image_encodings.h>
|
||||
|
||||
#include <camera_calibration_parsers/parse_ini.h>
|
||||
|
||||
#include <gscam/gscam.h>
|
||||
|
||||
namespace gscam {
|
||||
|
||||
GSCam::GSCam(ros::NodeHandle nh_camera, ros::NodeHandle nh_private) :
|
||||
gsconfig_(""),
|
||||
pipeline_(NULL),
|
||||
sink_(NULL),
|
||||
nh_(nh_camera),
|
||||
nh_private_(nh_private),
|
||||
image_transport_(nh_camera),
|
||||
camera_info_manager_(nh_camera)
|
||||
{
|
||||
}
|
||||
|
||||
GSCam::~GSCam()
|
||||
{
|
||||
}
|
||||
|
||||
bool GSCam::configure()
|
||||
{
|
||||
// Get gstreamer configuration
|
||||
// (either from environment variable or ROS param)
|
||||
std::string gsconfig_rosparam = "";
|
||||
bool gsconfig_rosparam_defined = false;
|
||||
char *gsconfig_env = NULL;
|
||||
|
||||
gsconfig_rosparam_defined = nh_private_.getParam("gscam_config",gsconfig_rosparam);
|
||||
gsconfig_env = getenv("GSCAM_CONFIG");
|
||||
|
||||
if (!gsconfig_env && !gsconfig_rosparam_defined) {
|
||||
ROS_FATAL( "Problem getting GSCAM_CONFIG environment variable and 'gscam_config' rosparam is not set. This is needed to set up a gstreamer pipeline." );
|
||||
return false;
|
||||
} else if(gsconfig_env && gsconfig_rosparam_defined) {
|
||||
ROS_FATAL( "Both GSCAM_CONFIG environment variable and 'gscam_config' rosparam are set. Please only define one." );
|
||||
return false;
|
||||
} else if(gsconfig_env) {
|
||||
gsconfig_ = gsconfig_env;
|
||||
ROS_INFO_STREAM("Using gstreamer config from env: \""<<gsconfig_env<<"\"");
|
||||
} else if(gsconfig_rosparam_defined) {
|
||||
gsconfig_ = gsconfig_rosparam;
|
||||
ROS_INFO_STREAM("Using gstreamer config from rosparam: \""<<gsconfig_rosparam<<"\"");
|
||||
}
|
||||
|
||||
// Get additional gscam configuration
|
||||
nh_private_.param("sync_sink", sync_sink_, true);
|
||||
nh_private_.param("preroll", preroll_, false);
|
||||
nh_private_.param("use_gst_timestamps", use_gst_timestamps_, false);
|
||||
|
||||
nh_private_.param("reopen_on_eof", reopen_on_eof_, false);
|
||||
|
||||
// Get the camera parameters file
|
||||
nh_private_.getParam("camera_info_url", camera_info_url_);
|
||||
nh_private_.getParam("camera_name", camera_name_);
|
||||
|
||||
// Get the image encoding
|
||||
nh_private_.param("image_encoding", image_encoding_, sensor_msgs::image_encodings::RGB8);
|
||||
if (image_encoding_ != sensor_msgs::image_encodings::RGB8 &&
|
||||
image_encoding_ != sensor_msgs::image_encodings::MONO8 &&
|
||||
image_encoding_ != "jpeg") {
|
||||
ROS_FATAL_STREAM("Unsupported image encoding: " + image_encoding_);
|
||||
}
|
||||
|
||||
camera_info_manager_.setCameraName(camera_name_);
|
||||
|
||||
if(camera_info_manager_.validateURL(camera_info_url_)) {
|
||||
camera_info_manager_.loadCameraInfo(camera_info_url_);
|
||||
ROS_INFO_STREAM("Loaded camera calibration from "<<camera_info_url_);
|
||||
} else {
|
||||
ROS_WARN_STREAM("Camera info at: "<<camera_info_url_<<" not found. Using an uncalibrated config.");
|
||||
}
|
||||
|
||||
// Get TF Frame
|
||||
if(!nh_private_.getParam("frame_id",frame_id_)){
|
||||
frame_id_ = "/camera_frame";
|
||||
ROS_WARN_STREAM("No camera frame_id set, using frame \""<<frame_id_<<"\".");
|
||||
nh_private_.setParam("frame_id",frame_id_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSCam::init_stream()
|
||||
{
|
||||
if(!gst_is_initialized()) {
|
||||
// Initialize gstreamer pipeline
|
||||
ROS_DEBUG_STREAM( "Initializing gstreamer..." );
|
||||
gst_init(0,0);
|
||||
}
|
||||
|
||||
ROS_DEBUG_STREAM( "Gstreamer Version: " << gst_version_string() );
|
||||
|
||||
GError *error = 0; // Assignment to zero is a gst requirement
|
||||
|
||||
pipeline_ = gst_parse_launch(gsconfig_.c_str(), &error);
|
||||
if (pipeline_ == NULL) {
|
||||
ROS_FATAL_STREAM( error->message );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create RGB sink
|
||||
sink_ = gst_element_factory_make("appsink",NULL);
|
||||
GstCaps * caps = NULL;
|
||||
if (image_encoding_ == sensor_msgs::image_encodings::RGB8) {
|
||||
caps = gst_caps_new_simple("video/x-raw-rgb", NULL);
|
||||
} else if (image_encoding_ == sensor_msgs::image_encodings::MONO8) {
|
||||
caps = gst_caps_new_simple("video/x-raw-gray", NULL);
|
||||
} else if (image_encoding_ == "jpeg") {
|
||||
caps = gst_caps_new_simple("image/jpeg", NULL);
|
||||
}
|
||||
gst_app_sink_set_caps(GST_APP_SINK(sink_), caps);
|
||||
gst_caps_unref(caps);
|
||||
|
||||
// Set whether the sink should sync
|
||||
// Sometimes setting this to true can cause a large number of frames to be
|
||||
// dropped
|
||||
gst_base_sink_set_sync(
|
||||
GST_BASE_SINK(sink_),
|
||||
(sync_sink_) ? TRUE : FALSE);
|
||||
|
||||
if(GST_IS_PIPELINE(pipeline_)) {
|
||||
GstPad *outpad = gst_bin_find_unlinked_pad(GST_BIN(pipeline_), GST_PAD_SRC);
|
||||
g_assert(outpad);
|
||||
|
||||
GstElement *outelement = gst_pad_get_parent_element(outpad);
|
||||
g_assert(outelement);
|
||||
gst_object_unref(outpad);
|
||||
|
||||
if(!gst_bin_add(GST_BIN(pipeline_), sink_)) {
|
||||
ROS_FATAL("gst_bin_add() failed");
|
||||
gst_object_unref(outelement);
|
||||
gst_object_unref(pipeline_);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!gst_element_link(outelement, sink_)) {
|
||||
ROS_FATAL("GStreamer: cannot link outelement(\"%s\") -> sink\n", gst_element_get_name(outelement));
|
||||
gst_object_unref(outelement);
|
||||
gst_object_unref(pipeline_);
|
||||
return false;
|
||||
}
|
||||
|
||||
gst_object_unref(outelement);
|
||||
} else {
|
||||
GstElement* launchpipe = pipeline_;
|
||||
pipeline_ = gst_pipeline_new(NULL);
|
||||
g_assert(pipeline_);
|
||||
|
||||
gst_object_unparent(GST_OBJECT(launchpipe));
|
||||
|
||||
gst_bin_add_many(GST_BIN(pipeline_), launchpipe, sink_, NULL);
|
||||
|
||||
if(!gst_element_link(launchpipe, sink_)) {
|
||||
ROS_FATAL("GStreamer: cannot link launchpipe -> sink");
|
||||
gst_object_unref(pipeline_);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Calibration between ros::Time and gst timestamps
|
||||
GstClock * clock = gst_system_clock_obtain();
|
||||
ros::Time now = ros::Time::now();
|
||||
GstClockTime ct = gst_clock_get_time(clock);
|
||||
gst_object_unref(clock);
|
||||
time_offset_ = now.toSec() - GST_TIME_AS_USECONDS(ct)/1e6;
|
||||
ROS_INFO("Time offset: %.3f",time_offset_);
|
||||
|
||||
gst_element_set_state(pipeline_, GST_STATE_PAUSED);
|
||||
|
||||
if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
|
||||
ROS_FATAL("Failed to PAUSE stream, check your gstreamer configuration.");
|
||||
return false;
|
||||
} else {
|
||||
ROS_DEBUG_STREAM("Stream is PAUSED.");
|
||||
}
|
||||
|
||||
// Create ROS camera interface
|
||||
if (image_encoding_ == "jpeg") {
|
||||
jpeg_pub_ = nh_.advertise<sensor_msgs::CompressedImage>("camera/image_raw/compressed",1);
|
||||
cinfo_pub_ = nh_.advertise<sensor_msgs::CameraInfo>("camera/camera_info",1);
|
||||
} else {
|
||||
camera_pub_ = image_transport_.advertiseCamera("camera/image_raw", 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSCam::publish_stream()
|
||||
{
|
||||
ROS_INFO_STREAM("Publishing stream...");
|
||||
|
||||
// Pre-roll camera if needed
|
||||
if (preroll_) {
|
||||
ROS_DEBUG("Performing preroll...");
|
||||
|
||||
//The PAUSE, PLAY, PAUSE, PLAY cycle is to ensure proper pre-roll
|
||||
//I am told this is needed and am erring on the side of caution.
|
||||
gst_element_set_state(pipeline_, GST_STATE_PLAYING);
|
||||
if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
|
||||
ROS_ERROR("Failed to PLAY during preroll.");
|
||||
return;
|
||||
} else {
|
||||
ROS_DEBUG("Stream is PLAYING in preroll.");
|
||||
}
|
||||
|
||||
gst_element_set_state(pipeline_, GST_STATE_PAUSED);
|
||||
if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
|
||||
ROS_ERROR("Failed to PAUSE.");
|
||||
return;
|
||||
} else {
|
||||
ROS_INFO("Stream is PAUSED in preroll.");
|
||||
}
|
||||
}
|
||||
|
||||
if(gst_element_set_state(pipeline_, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
|
||||
ROS_ERROR("Could not start stream!");
|
||||
return;
|
||||
}
|
||||
ROS_INFO("Started stream.");
|
||||
|
||||
// Poll the data as fast a spossible
|
||||
while(ros::ok()) {
|
||||
// This should block until a new frame is awake, this way, we'll run at the
|
||||
// actual capture framerate of the device.
|
||||
// ROS_DEBUG("Getting data...");
|
||||
GstBuffer* buf = gst_app_sink_pull_buffer(GST_APP_SINK(sink_));
|
||||
GstClockTime bt = gst_element_get_base_time(pipeline_);
|
||||
// ROS_INFO("New buffer: timestamp %.6f %lu %lu %.3f",
|
||||
// GST_TIME_AS_USECONDS(buf->timestamp+bt)/1e6+time_offset_, buf->timestamp, bt, time_offset_);
|
||||
|
||||
|
||||
#if 0
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
gint64 current = -1;
|
||||
|
||||
Query the current position of the stream
|
||||
if (gst_element_query_position(pipeline_, &fmt, ¤t)) {
|
||||
ROS_INFO_STREAM("Position "<<current);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Stop on end of stream
|
||||
if (!buf) {
|
||||
ROS_INFO("Stream ended.");
|
||||
break;
|
||||
}
|
||||
|
||||
// ROS_DEBUG("Got data.");
|
||||
|
||||
// Get the image width and height
|
||||
GstPad* pad = gst_element_get_static_pad(sink_, "sink");
|
||||
const GstCaps *caps = gst_pad_get_negotiated_caps(pad);
|
||||
GstStructure *structure = gst_caps_get_structure(caps,0);
|
||||
gst_structure_get_int(structure,"width",&width_);
|
||||
gst_structure_get_int(structure,"height",&height_);
|
||||
|
||||
// Update header information
|
||||
sensor_msgs::CameraInfoPtr cinfo;
|
||||
cinfo.reset(new sensor_msgs::CameraInfo(camera_info_manager_.getCameraInfo()));
|
||||
if (use_gst_timestamps_) {
|
||||
cinfo->header.stamp = ros::Time(GST_TIME_AS_USECONDS(buf->timestamp+bt)/1e6+time_offset_);
|
||||
} else {
|
||||
cinfo->header.stamp = ros::Time::now();
|
||||
}
|
||||
// ROS_INFO("Image time stamp: %.3f",cinfo->header.stamp.toSec());
|
||||
cinfo->header.frame_id = frame_id_;
|
||||
if (image_encoding_ == "jpeg") {
|
||||
sensor_msgs::CompressedImagePtr img(new sensor_msgs::CompressedImage());
|
||||
img->header = cinfo->header;
|
||||
img->format = "jpeg";
|
||||
img->data.resize(buf->size);
|
||||
std::copy(buf->data, (buf->data)+(buf->size),
|
||||
img->data.begin());
|
||||
jpeg_pub_.publish(img);
|
||||
cinfo_pub_.publish(cinfo);
|
||||
} else {
|
||||
// Complain if the returned buffer is smaller than we expect
|
||||
const unsigned int expected_frame_size =
|
||||
image_encoding_ == sensor_msgs::image_encodings::RGB8
|
||||
? width_ * height_ * 3
|
||||
: width_ * height_;
|
||||
|
||||
if (buf->size < expected_frame_size) {
|
||||
ROS_WARN_STREAM( "GStreamer image buffer underflow: Expected frame to be "
|
||||
<< expected_frame_size << " bytes but got only "
|
||||
<< (buf->size) << " bytes. (make sure frames are correctly encoded)");
|
||||
}
|
||||
|
||||
// Construct Image message
|
||||
sensor_msgs::ImagePtr img(new sensor_msgs::Image());
|
||||
|
||||
img->header = cinfo->header;
|
||||
|
||||
// Image data and metadata
|
||||
img->width = width_;
|
||||
img->height = height_;
|
||||
img->encoding = image_encoding_;
|
||||
img->is_bigendian = false;
|
||||
img->data.resize(expected_frame_size);
|
||||
|
||||
// Copy only the data we received
|
||||
// Since we're publishing shared pointers, we need to copy the image so
|
||||
// we can free the buffer allocated by gstreamer
|
||||
if (image_encoding_ == sensor_msgs::image_encodings::RGB8) {
|
||||
img->step = width_ * 3;
|
||||
} else {
|
||||
img->step = width_;
|
||||
}
|
||||
std::copy(
|
||||
buf->data,
|
||||
(buf->data)+(buf->size),
|
||||
img->data.begin());
|
||||
|
||||
// Publish the image/info
|
||||
camera_pub_.publish(img, cinfo);
|
||||
}
|
||||
|
||||
// Release the buffer
|
||||
gst_buffer_unref(buf);
|
||||
|
||||
ros::spinOnce();
|
||||
}
|
||||
}
|
||||
|
||||
void GSCam::cleanup_stream()
|
||||
{
|
||||
// Clean up
|
||||
ROS_INFO("Stopping gstreamer pipeline...");
|
||||
if(pipeline_) {
|
||||
gst_element_set_state(pipeline_, GST_STATE_NULL);
|
||||
gst_object_unref(pipeline_);
|
||||
pipeline_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GSCam::run() {
|
||||
while(ros::ok()) {
|
||||
if(!this->configure()) {
|
||||
ROS_FATAL("Failed to configure gscam!");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!this->init_stream()) {
|
||||
ROS_FATAL("Failed to initialize gscam stream!");
|
||||
break;
|
||||
}
|
||||
|
||||
// Block while publishing
|
||||
this->publish_stream();
|
||||
|
||||
this->cleanup_stream();
|
||||
|
||||
ROS_INFO("GStreamer stream stopped!");
|
||||
|
||||
if(reopen_on_eof_) {
|
||||
ROS_INFO("Reopening stream...");
|
||||
} else {
|
||||
ROS_INFO("Cleaning up stream and exiting...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Example callbacks for appsink
|
||||
// TODO: enable callback-based capture
|
||||
void gst_eos_cb(GstAppSink *appsink, gpointer user_data ) {
|
||||
}
|
||||
GstFlowReturn gst_new_preroll_cb(GstAppSink *appsink, gpointer user_data ) {
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
GstFlowReturn gst_new_asample_cb(GstAppSink *appsink, gpointer user_data ) {
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <gscam/gscam.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
ros::init(argc, argv, "gscam_publisher");
|
||||
ros::NodeHandle nh, nh_private("~");
|
||||
|
||||
gscam::GSCam gscam_driver(nh, nh_private);
|
||||
gscam_driver.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <nodelet/nodelet.h>
|
||||
#include <pluginlib/class_list_macros.h>
|
||||
#include <gscam/gscam_nodelet.h>
|
||||
|
||||
PLUGINLIB_DECLARE_CLASS(gscam, GSCamNodelet, gscam::GSCamNodelet, nodelet::Nodelet)
|
||||
|
||||
namespace gscam {
|
||||
GSCamNodelet::GSCamNodelet() :
|
||||
nodelet::Nodelet(),
|
||||
gscam_driver_(NULL),
|
||||
stream_thread_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
GSCamNodelet::~GSCamNodelet()
|
||||
{
|
||||
stream_thread_->join();
|
||||
}
|
||||
|
||||
void GSCamNodelet::onInit()
|
||||
{
|
||||
gscam_driver_.reset(new gscam::GSCam(this->getNodeHandle(), this->getPrivateNodeHandle()));
|
||||
stream_thread_.reset(new boost::thread(boost::bind(&GSCam::run, gscam_driver_.get())));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<launch>
|
||||
<group ns="cam1">
|
||||
<node name="usb_cam1" pkg="usb_cam" type="usb_cam_node" output="screen" >
|
||||
<param name="video_device" value="/dev/video1" />
|
||||
<param name="video_device" value="/dev/rover/cam_grasper" />
|
||||
<param name="image_width" value="1280" />
|
||||
<param name="image_height" value="720" />
|
||||
<param name="pixel_format" value="mjpeg" />
|
||||
<param name="camera_frame_id" value="usb_cam" />
|
||||
<param name="camera_frame_id" value="usb_cam1" />
|
||||
<param name="io_method" value="mmap"/>
|
||||
</node>
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
<group ns="cam2">
|
||||
<node name="usb_cam2" pkg="usb_cam" type="usb_cam_node" output="screen" >
|
||||
<param name="video_device" value="/dev/video2" />
|
||||
<param name="video_device" value="/dev/rover/cam_undercarriage" />
|
||||
<param name="image_width" value="1280" />
|
||||
<param name="image_height" value="720" />
|
||||
<param name="pixel_format" value="mjpeg" />
|
||||
<param name="camera_frame_id" value="usb_cam" />
|
||||
<param name="camera_frame_id" value="usb_cam2" />
|
||||
<param name="io_method" value="mmap"/>
|
||||
</node>
|
||||
|
||||
|
||||
13
rover/uvc_capture/launch/uvc_one_cam.launch
Normal file
13
rover/uvc_capture/launch/uvc_one_cam.launch
Normal file
@@ -0,0 +1,13 @@
|
||||
<launch>
|
||||
<group ns="cam1">
|
||||
<node name="usb_cam1" pkg="usb_cam" type="usb_cam_node" output="screen" >
|
||||
<param name="video_device" value="/dev/rover/cam_undercarriage" />
|
||||
<param name="image_width" value="1280" />
|
||||
<param name="image_height" value="720" />
|
||||
<param name="pixel_format" value="mjpeg" />
|
||||
<param name="camera_frame_id" value="usb_cam" />
|
||||
<param name="io_method" value="mmap"/>
|
||||
</node>
|
||||
|
||||
</group>
|
||||
</launch>
|
||||
0
rover/zed_wrapper/cfg/Zed.cfg
Normal file → Executable file
0
rover/zed_wrapper/cfg/Zed.cfg
Normal file → Executable file
@@ -46,10 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
<!-- ZED parameters -->
|
||||
<param name="zed_id" value="$(arg zed_id)" />
|
||||
|
||||
<param name="resolution" value="3" />
|
||||
<param name="resolution" value="2" />
|
||||
<param name="quality" value="1" />
|
||||
<param name="sensing_mode" value="0" />
|
||||
<param name="frame_rate" value="60" />
|
||||
<param name="frame_rate" value="30" />
|
||||
<param name="odometry_db" value="" />
|
||||
<param name="openni_depth_mode" value="0" />
|
||||
<param name="gpu_id" value="$(arg gpu_id)" />
|
||||
|
||||
Reference in New Issue
Block a user