├── CMakeLists.txt ├── README.md ├── catkin_simple ├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake │ └── catkin_simple-extras.cmake.em ├── package.xml └── test │ └── scenarios │ └── hello_world │ ├── .gitignore │ ├── bar │ ├── include │ │ └── bar │ │ │ └── hello.h │ ├── msg │ │ └── HeaderString.msg │ ├── package.xml │ └── src │ │ └── hello.cpp │ ├── baz │ ├── include │ │ └── baz │ │ │ └── world.h │ └── package.xml │ ├── catkin_simple │ └── foo │ ├── package.xml │ └── src │ └── main.cpp ├── davis_ros_driver ├── CMakeLists.txt ├── cfg │ └── DAVIS_ROS_Driver.cfg ├── config │ ├── calib.yaml │ ├── indoors.yaml │ └── standard.yaml ├── davis_ros_driver_nodelet.xml ├── include │ └── davis_ros_driver │ │ ├── driver.h │ │ └── driver_nodelet.h ├── package.xml └── src │ ├── driver.cpp │ ├── driver_node.cpp │ └── driver_nodelet.cpp ├── dvs_driver ├── 88-retina.rules ├── 88-retinaDAVIS.rules ├── CMakeLists.txt ├── include │ └── dvs_driver │ │ └── dvs_driver.h ├── install.sh ├── installDAVIS.sh ├── package.xml └── src │ └── dvs_driver.cpp ├── dvs_meanshift ├── .vscode │ └── settings.json ├── CMakeLists.txt ├── LICENSE ├── README.md ├── include │ ├── dvs_meanshift │ │ ├── color_meanshift.h │ │ └── meanshift.h │ ├── graph3d │ │ ├── convolve.h │ │ ├── disjoint-set.h │ │ ├── filter.h │ │ ├── image.h │ │ ├── imconv.h │ │ ├── imutil.h │ │ ├── misc.h │ │ ├── pnmfile.h │ │ ├── segment-graph.h │ │ ├── segment-image.h │ │ └── segment.h │ └── image_reconstruct │ │ └── image_reconst.h ├── launch │ ├── dvs_mono.launch │ └── dvs_segmentation.launch ├── package.xml └── src │ ├── COPYING │ ├── README │ ├── color_meanshift.cpp │ ├── image_reconst.cpp │ ├── meanshift.cpp │ ├── meanshift_node.cpp │ └── segment.cpp ├── dvs_msgs ├── CMakeLists.txt ├── EventArrayRule.bmr ├── msg │ ├── Event.msg │ └── EventArray.msg └── package.xml ├── dvs_renderer ├── .CMakeLists.txt.swp ├── CMakeLists.txt ├── dvs_renderer_nodelet.xml ├── include │ └── dvs_renderer │ │ ├── image_tracking.h │ │ ├── renderer.h │ │ └── renderer_nodelet.h ├── launch │ ├── bias_tuning.launch │ ├── davis_mono.launch │ ├── dvs_mono.launch │ ├── mono.launch │ ├── nodelet_mono.launch │ ├── nodelet_stereo.launch │ ├── renderer_mono.launch │ ├── renderer_stereo.launch │ ├── rgbd-dvs-rig.launch │ ├── stereo.launch │ ├── viewer_mono.launch │ └── viewer_stereo.launch ├── package.xml └── src │ ├── image_tracking.cpp │ ├── renderer.cpp │ ├── renderer_node.cpp │ └── renderer_nodelet.cpp ├── dvs_ros_driver ├── CMakeLists.txt ├── cfg │ └── DVS_ROS_Driver.cfg ├── config │ ├── fast.yaml │ ├── slow.yaml │ ├── standard.yaml │ └── stereo.yaml ├── dvs_ros_driver_nodelet.xml ├── include │ └── dvs_ros_driver │ │ ├── driver.h │ │ └── driver_nodelet.h ├── launch │ └── stereo.launch ├── package.xml └── src │ ├── driver.cpp │ ├── driver_node.cpp │ └── driver_nodelet.cpp ├── libcaer ├── .cproject ├── .gitignore ├── .project ├── .settings │ ├── language.settings.xml │ └── org.eclipse.cdt.codan.core.prefs ├── CMakeLists.txt ├── COPYING ├── ChangeLog ├── README ├── docs │ ├── .gitignore │ ├── CMakeLists.txt │ ├── libcaer_api.doxy.in │ └── libcaer_api_manual.pdf ├── examples │ ├── .gitignore │ ├── README │ ├── davis_simple.c │ ├── davis_simple.cpp │ ├── dvs128_simple.c │ └── dvs128_simple.cpp ├── include │ ├── .gitignore │ ├── CMakeLists.txt │ ├── devices │ │ ├── davis.h │ │ ├── dvs128.h │ │ └── usb.h │ ├── events │ │ ├── common.h │ │ ├── config.h │ │ ├── ear.h │ │ ├── frame.h │ │ ├── imu6.h │ │ ├── imu9.h │ │ ├── packetContainer.h │ │ ├── point1d.h │ │ ├── point2d.h │ │ ├── point3d.h │ │ ├── point4d.h │ │ ├── polarity.h │ │ ├── sample.h │ │ └── special.h │ ├── frame_utils.h │ ├── frame_utils_opencv.h │ ├── libcaer_in.h │ ├── log.h │ └── portable_endian.h ├── libcaer.pc.in ├── libcaer_opencv.pc.in └── src │ ├── .gitignore │ ├── CMakeLists.txt │ ├── c11threads_posix.h │ ├── davis_common.c │ ├── davis_common.h │ ├── davis_fx2.c │ ├── davis_fx2.h │ ├── davis_fx3.c │ ├── davis_fx3.h │ ├── device.c │ ├── dvs128.c │ ├── dvs128.h │ ├── events.c │ ├── frame_utils.c │ ├── frame_utils_opencv.cpp │ ├── log.c │ └── ringbuffer │ ├── portable_aligned_alloc.h │ ├── ringbuffer.c │ └── ringbuffer.h └── libcaer_catkin ├── 65-inilabs.rules ├── CMakeLists.txt ├── cmake └── libcaer-extras.cmake ├── install.sh └── package.xml /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | /opt/ros/kinetic/share/catkin/cmake/toplevel.cmake -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Real-time clustering and tracking for event-based sensors 2 | 3 | This package implements a clustering and tracking using Kalman filters for DVS data (event based camera). 4 | 5 | ## Getting Started 6 | 7 | Clone or download the project. After that, first source your *ROS distro* files: 8 | ``` 9 | $ source /opt/ros//setup.bash 10 | ``` 11 | 12 | And follow the next files to compile the package: 13 | ``` 14 | $ mkdir -p ~/dvs_clustering_tracking/src 15 | $ cd ~/dvs_clustering_tracking/ 16 | $ catkin_make 17 | ``` 18 | 19 | After this, you will have a copy of the project for testing. 20 | 21 | ### Prerequisites 22 | 23 | In order to install the project, you will need a ROS distribution running in your platform. This project was developed and tested using *kinetic*. See more about the installation and tutorial examples in the [ROS website](http://wiki.ros.org/ROS/Tutorials/). 24 | 25 | ### Installing 26 | 27 | In order to install all the dependencies you will have to install: 28 | * [`rpg_dvs_ros`](https://github.com/uzh-rpg/rpg_dvs_ros): where you will require `dvs_ros_driver`(and then `dvs_driver`), `dvs_msgs`, `dvs_renderer`, `libcaer_catkin` (and then `libcaer`) 29 | * [`catkin_simple`](https://github.com/catkin/catkin_simple) 30 | 31 | ## Running the tests 32 | 33 | After the compiling the project code, source the *setup.bash* file 34 | 35 | ``` 36 | :~/dvs_clustering_tracking$ source devel/setup.bash 37 | ``` 38 | Next, we will show two examples for running some of the tests: 39 | 40 | ### Running the dvs_renderer 41 | If you do not have the DVS camera and want to run a file, simply run: 42 | ``` 43 | :~/dvs_clustering_tracking$ rosbag play ~/bagfiles/shapes_rotation.bag -l 44 | ``` 45 | where in `~/bagfiles` we have the rosbag file with dvs events ([rosbag files dataset] (http://rpg.ifi.uzh.ch/davis_data.html)) 46 | 47 | Or, if you have your own camera, just run in a different console (you'll need to source again the setup.bash files in this new console): 48 | ``` 49 | $ roslaunch dvs_renderer dvs_mono.launch 50 | ``` 51 | 52 | ### Running dvs_meanshift 53 | In case there is no attached DVS, just run the same rosbag example: 54 | ``` 55 | :~/dvs_clustering_tracking$ rosbag play ~/bagfiles/shapes_rotation.bag -l 56 | ``` 57 | where in `~/bagfiles` we have the rosbag file with dvs events ([rosbag files dataset] (http://rpg.ifi.uzh.ch/davis_data.html)) 58 | 59 | Then, run in a different console (you'll need to source again the *setup.bash* files in this new console): 60 | ``` 61 | $ roslaunch dvs_meanshift dvs_segmentation.launch 62 | ``` 63 | 64 | ## Publications 65 | 66 | If you use this work in an academic context, please cite the following publication: 67 | 68 | * F. Barranco, C. Fermuller, E. Ros: **Real-time clsutering for multi-target tracking using event-based sensors**. IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), Madrid, 2018. ([PDF](https://arxiv.org/pdf/1807.02851.pdf)) 69 | 70 | 71 | ## Authors 72 | 73 | * **Francisco Barranco** - *University of Granada* 74 | Please report problems, bugs, or suggestions to fbarranco_at_ugr_dot_es (Replace _at_ by @ and _dot_ by .). 75 | 76 | ## Acknowledgments 77 | 78 | * This work was supported by a Spanish Juan de la Cierva grant (IJCI-2014-21376), partially funded by MINECO-FEDER TIN2016-81041-R grant, the EU HPB-SGA2 grant (H2020-RIA 785907), the National Science Foundation under grant SMA 1540916, and the NG-UMD seed grant (Object Motion Analysis for Autonomous Systems). 79 | 80 | ## License 81 | 82 | Copyright (C) 2018 Francisco Barranco, 01/09/2018, University of Granada. 83 | 84 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License. 85 | 86 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 87 | 88 | You should have received a copy of the GNU General Public License along with this program. If not, see . 89 | 90 | -------------------------------------------------------------------------------- /catkin_simple/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /catkin_simple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(catkin_simple) 3 | 4 | find_package(catkin REQUIRED) 5 | 6 | catkin_package( 7 | CATKIN_DEPENDS catkin 8 | CFG_EXTRAS catkin_simple-extras.cmake 9 | ) 10 | -------------------------------------------------------------------------------- /catkin_simple/README.md: -------------------------------------------------------------------------------- 1 | # catkin simple 2 | 3 | This `catkin` package is designed to make the `CMakeLists.txt` of other `catkin` packages simpler. 4 | 5 | ## CMakeLists.txt Example 6 | 7 | Here is an example of a package `foo` which depends on other catkin packages: 8 | 9 | ```cmake 10 | cmake_minimum_required(VERSION 2.8.3) 11 | project(foo) 12 | 13 | find_package(catkin_simple REQUIRED) 14 | 15 | catkin_simple() 16 | 17 | cs_add_library(my_lib src/my_lib.cpp) 18 | 19 | cs_add_executable(my_exec src/main.cpp) 20 | target_link_libraries(my_exec my_lib) 21 | 22 | cs_install() 23 | 24 | cs_install_scripts(scripts/my_script.py) 25 | 26 | cs_export() 27 | ``` 28 | 29 | Lets break this down, line by line. 30 | 31 | First is the standard CMake header: 32 | 33 | ```cmake 34 | cmake_minimum_required(VERSION 2.8.3) 35 | project(foo) 36 | ``` 37 | 38 | Which defines the minimum CMake version and the name of this project. 39 | 40 | Next comes the `find_package` of `catkin_simple`: 41 | 42 | ```cmake 43 | find_package(catkin_simple REQUIRED) 44 | ``` 45 | 46 | This is just like `find_package` for any other `catkin` package. This command is required. 47 | 48 | ### catkin_simple() 49 | 50 | Then you invoke `catkin_simple`: 51 | 52 | ```cmake 53 | catkin_simple() 54 | ``` 55 | 56 | This macro call gathers your `build_depend`'s from the `package.xml` of your package, then does a `find_package(...)` on each of them. 57 | 58 | By default, `find_package(...)` is called with the `QUIET` option and without the `REQUIRED` option. That way, if any of the build_depend's are not `catkin` packages then they are simply ignored. This means that if you depend on a `caktin` package which is not on your system, `catkin_simple` will not warn you about this, because there is no way to know if it is a missing `catkin` package or a system dependency. If this is not the desired behaviour, calling `catkin_simple(ALL_DEPS_REQUIRED)` will call `find_package(...)` on each dependency *with* the `REQUIRED` option. 59 | 60 | Packages which are successfully found and identified to be `catkin` packages are added to a list of "catkin build dependencies" for your package. This list of build dependencies is passed to `find_package(catkin REQUIRED COMPONENTS ...)`. This command is required. 61 | 62 | Next, this macro adds the local `include` folder and any `catkin` include directories to the include path with CMake's `include_directories(...)` macro, but the local `include` folder is only added if it exists. 63 | 64 | Finally, this macro will discover and build any ROS messages, services, and actions which reside in the `msg`, `srv`, action `action` folders, respectively. The automatic discovery and building of messages/services is only done if your package `build_depend`'s on `message_generation`, and message generation will complain if your package does not run_depend on `message_runtime`. 65 | 66 | This macro discovers and builds [dynamic_reconfigure](http://wiki.ros.org/dynamic_reconfigure) config files from the `cfg` folder. The automatic discovery only works if your package `build_depend`'s on `dynamic_reconfigure`, and dynamic reconfigure will complain if your package does not run_depend on `dynamic_reconfigure`. 67 | 68 | ### cs_add_library() 69 | 70 | Next we create a library: 71 | 72 | ```cmake 73 | cs_add_library(my_lib src/my_lib.cpp) 74 | ``` 75 | 76 | This call does a few things, first it calls directly through to the normal CMake macro `add_library`, then it calls `target_link_libraries(my_lib ${catkin_LIBRARIES})` to link your new library against any catkin libraries you have build depended on in your package.xml. Finally it does some bookkeeping so that your library target can be implicitly used later. 77 | 78 | ### cs_add_executable() 79 | 80 | Next we add a new executable: 81 | 82 | ```cmake 83 | cs_add_executable(my_exec src/main.cpp) 84 | target_link_libraries(my_exec my_lib) 85 | ``` 86 | 87 | This works just like `cs_add_library`, but it calls CMake's `add_executable(...)` instead. 88 | 89 | Notice that here we have to explicitly call `target_link_libraries` for linking against our library, this is because there is no way to enforce order of target creation. The executable is still automatically linked against the catkin libraries. 90 | 91 | ### cs_install() 92 | 93 | Next we install everything: 94 | 95 | ```cmake 96 | cs_install() 97 | 98 | cs_install_scripts(scripts/my_script.py) 99 | ``` 100 | 101 | The first macro call creates an installation rule for any libraries and executables you created with `cs_` prefixed commands. That call can also take zero to many additional targets you wish to install which were created without the `cs_` prefixed commands. This command is optional. 102 | 103 | The second macro call creates an installation rule for the given scripts, installing them to `${prefix}/lib/${pkg_name}/`. This command is optional. 104 | 105 | ### cs_export() 106 | 107 | Finally, we export everything: 108 | 109 | ```cmake 110 | cs_export() 111 | ``` 112 | 113 | This command calls `catkin_package(...)` under the hood, extending that call with any libraries created and catkin_depends found automatically with `catkin_simple`. You can also pass in your own arguments to `catkin_package(...)` through this command. This command is required. 114 | 115 | ## Known Limitations 116 | 117 | There are several known assumptions and incorrect behaviors in `catkin_simple` which are a result of the trade-off of correctness for convenience. 118 | 119 | * There is no warning when a catkin package is not found during `find_package`. 120 | * There is over linking, as all libraries of all dependencies are linked against all targets indiscriminately. 121 | * Assumes that the `include` folder is meant to be in the include path. 122 | * If new .msg or .srv files are added, they will not be detected until you force CMake to run again 123 | * All targets have a target dependency on any downstream message generation, which results in sub-optimal parallelization of targets, as there are unnecessary dependencies created. 124 | -------------------------------------------------------------------------------- /catkin_simple/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | catkin_simple 4 | 0.1.1 5 | catkin, simpler 6 | 7 | William Woodall 8 | Dirk Thomas 9 | BSD 10 | 11 | William Woodall 12 | Dirk Thomas 13 | 14 | catkin 15 | catkin 16 | 17 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt 2 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/bar/include/bar/hello.h: -------------------------------------------------------------------------------- 1 | void hello(); 2 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/bar/msg/HeaderString.msg: -------------------------------------------------------------------------------- 1 | Header header 2 | string data 3 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/bar/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bar 4 | 0.1.0 5 | The bar package 6 | William Woodall 7 | BSD 8 | 9 | catkin 10 | catkin_simple 11 | boost 12 | message_runtime 13 | std_msgs 14 | boost-dev 15 | message_generation 16 | std_msgs 17 | 18 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/bar/src/hello.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | inline void print_hello() { 10 | std::cout << "Hello "; 11 | } 12 | 13 | void hello() { 14 | boost::thread t(print_hello); 15 | t.join(); 16 | } 17 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/baz/include/baz/world.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | void print_world() { 6 | std::cout << "world!" << std::endl; 7 | } 8 | 9 | void world() { 10 | boost::thread t(print_world); 11 | t.join(); 12 | } 13 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/baz/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | baz 4 | 0.1.0 5 | The baz package 6 | William Woodall 7 | BSD 8 | 9 | catkin 10 | boost 11 | boost-dev 12 | 13 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/catkin_simple: -------------------------------------------------------------------------------- 1 | ../../.. -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/foo/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | foo 4 | 0.1.0 5 | The foo package 6 | William Woodall 7 | BSD 8 | 9 | catkin 10 | catkin_simple 11 | bar 12 | bar 13 | baz 14 | baz 15 | boost 16 | boost-dev 17 | 18 | -------------------------------------------------------------------------------- /catkin_simple/test/scenarios/hello_world/foo/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | hello(); 6 | world(); 7 | 8 | return 0; 9 | } -------------------------------------------------------------------------------- /davis_ros_driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(davis_ros_driver) 3 | 4 | # search for everything we need to build the package 5 | find_package(catkin REQUIRED COMPONENTS 6 | roscpp 7 | libcaer_catkin 8 | dvs_msgs 9 | std_msgs 10 | sensor_msgs 11 | dynamic_reconfigure 12 | camera_info_manager 13 | nodelet 14 | ) 15 | 16 | generate_dynamic_reconfigure_options( 17 | cfg/DAVIS_ROS_Driver.cfg 18 | ) 19 | 20 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") 21 | 22 | # since we need eigen and boost search them as well 23 | # find_package makes the ${..._INCLUDE_DIRS} ${..._LIBRARIES} variables we use later 24 | find_package(Boost REQUIRED COMPONENTS system thread) 25 | 26 | # export the dependencis of this package for who ever depends on us 27 | catkin_package( 28 | INCLUDE_DIRS 29 | include 30 | CATKIN_DEPENDS 31 | roscpp 32 | libcaer_catkin 33 | dvs_msgs 34 | std_msgs 35 | sensor_msgs 36 | dynamic_reconfigure 37 | camera_info_manager 38 | nodelet 39 | DEPENDS 40 | boost 41 | ) 42 | 43 | # tell catkin where to find the headers for this project 44 | include_directories( 45 | include 46 | ${catkin_INCLUDE_DIRS} 47 | ${Boost_INCLUDE_DIRS} 48 | ) 49 | 50 | # make the executable 51 | add_executable(davis_ros_driver 52 | src/driver_node.cpp 53 | src/driver.cpp 54 | ) 55 | 56 | # make the nodelet into a library 57 | add_library(davis_ros_driver_nodelet 58 | src/driver_nodelet.cpp 59 | src/driver.cpp 60 | ) 61 | 62 | # to build the executable we depend on other packets, 63 | # they need to be build beforehand, especially the messages 64 | add_dependencies(davis_ros_driver 65 | ${catkin_EXPORTED_TARGETS} 66 | ${PROJECT_NAME}_gencfg 67 | ) 68 | 69 | add_dependencies(davis_ros_driver_nodelet 70 | ${catkin_EXPORTED_TARGETS} 71 | ${PROJECT_NAME}_gencfg 72 | ) 73 | 74 | # link the executable to the necesarry libs 75 | target_link_libraries(davis_ros_driver 76 | ${catkin_LIBRARIES} 77 | ${Boost_LIBRARIES} 78 | ${CATKIN_DEVEL_PREFIX}/lib/libcaer${CMAKE_SHARED_LIBRARY_SUFFIX} 79 | ) 80 | 81 | # link the executable to the necesarry libs 82 | target_link_libraries(davis_ros_driver_nodelet 83 | ${catkin_LIBRARIES} 84 | ${Boost_LIBRARIES} 85 | ${CATKIN_DEVEL_PREFIX}/lib/libcaer${CMAKE_SHARED_LIBRARY_SUFFIX} 86 | ) 87 | 88 | # Install the nodelet library 89 | install(TARGETS davis_ros_driver_nodelet 90 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 91 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 92 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 93 | ) 94 | 95 | # Install other support files for installation 96 | install(FILES davis_ros_driver_nodelet.xml 97 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 98 | ) 99 | -------------------------------------------------------------------------------- /davis_ros_driver/cfg/DAVIS_ROS_Driver.cfg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | PACKAGE = "davis_ros_driver" 3 | 4 | from dynamic_reconfigure.parameter_generator_catkin import * 5 | 6 | gen = ParameterGenerator() 7 | 8 | gen.add("streaming_rate", int_t, 0, "integration time (0 is instant sending)", 30, 0, 10000) 9 | gen.add("max_events", int_t, 0, "max. events per packet (0 is no limit)", 0, 0, 100000) 10 | 11 | gen.add("aps_enabled", bool_t, 0, "enables APS", True) 12 | gen.add("dvs_enabled", bool_t, 0, "enables DVS", True) 13 | gen.add("imu_enabled", bool_t, 0, "enables IMU", True) 14 | 15 | gen.add("exposure", int_t, 0, "exposure (frame exposure time in microseconds)", 5000, 0, 1000000) 16 | gen.add("frame_delay", int_t, 0, "frame_delay (delay between consecutive frames in microseconds)", 0, 0, 1000000) 17 | 18 | # DAVIS Biasing 19 | # a bias consists of a coarse 3 bit value and a fine 8 bit value. 20 | # Coarse values are logarithmic and adding one means ~8 times higher current 21 | # fine values are linear and produce the output current range [0, coarse]. This 22 | # means setting a fine value to 32 is equal to decreasing coarse by 1 and 23 | # setting fine to 255. 24 | 25 | # if you want only one event per illumination change, use: high PrBp, PrSFBn and 26 | # low DiffBn 27 | 28 | def addBias(grp, name, descr, coarse_def, fine_def): 29 | grp.add(name+"_coarse", int_t, 1, descr+" (coarse, logarithmic)", coarse_def, 0, 7) 30 | grp.add(name+"_fine", int_t, 1, descr+" (fine, linear)", fine_def, 0, 255) 31 | 32 | grp_stage_one = gen.add_group("DAVIS_Biases_Stage_1") 33 | addBias(grp_stage_one, "PrBp", 34 | "Amplifier in first stage. Limits the speed. Higher=faster and more noise", 2, 58) 35 | addBias(grp_stage_one, "PrSFBp", 36 | "Source follower: set high to allow higher pixel bandwidth (has no influence if set high enough)", 1, 33) 37 | 38 | grp_stage_two = gen.add_group("DAVIS_Biases_Stage_2") 39 | addBias(grp_stage_two, "DiffBn", 40 | "Amplifier of second stage. Indep of actual illumination level. rebalance ONBn/OFFBn after changing this", 4, 39) 41 | addBias(grp_stage_two, "ONBn", 42 | "Threshold for ON events (contrast sensitivity). Must be >DiffBn.", 6, 200) 43 | addBias(grp_stage_two, "OFFBn", 44 | "Threshold for OFF events (contrast sensitivity). Must be 2 | 3 | 4 | A nodelet wrapper for the davis_ros_driver. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /davis_ros_driver/include/davis_ros_driver/driver.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | // boost 22 | #include 23 | #include 24 | #include 25 | 26 | // messages 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | // DAVIS driver 34 | #include 35 | #include 36 | 37 | // dynamic reconfigure 38 | #include 39 | #include 40 | 41 | // camera info manager 42 | #include 43 | #include 44 | 45 | namespace davis_ros_driver { 46 | 47 | class DavisRosDriver { 48 | public: 49 | DavisRosDriver(ros::NodeHandle & nh, ros::NodeHandle nh_private); 50 | ~DavisRosDriver(); 51 | 52 | static void onDisconnectUSB(void*); 53 | 54 | private: 55 | void changeDvsParameters(); 56 | void callback(davis_ros_driver::DAVIS_ROS_DriverConfig &config, uint32_t level); 57 | void readout(); 58 | void resetTimestamps(); 59 | void caerConnect(); 60 | 61 | ros::NodeHandle nh_; 62 | ros::Publisher event_array_pub_; 63 | ros::Publisher camera_info_pub_; 64 | ros::Publisher imu_pub_; 65 | ros::Publisher image_pub_; 66 | caerDeviceHandle davis_handle_; 67 | 68 | std::string ns; 69 | 70 | volatile bool running_; 71 | 72 | boost::shared_ptr > server_; 73 | dynamic_reconfigure::Server::CallbackType dynamic_reconfigure_callback_; 74 | 75 | ros::Subscriber reset_sub_; 76 | void resetTimestampsCallback(const std_msgs::Empty::ConstPtr& msg); 77 | 78 | ros::Subscriber imu_calibration_sub_; 79 | void imuCalibrationCallback(const std_msgs::Empty::ConstPtr& msg); 80 | int imu_calibration_sample_size_; 81 | bool imu_calibration_running_; 82 | std::vector imu_calibration_samples_; 83 | sensor_msgs::Imu bias; 84 | void updateImuBias(); 85 | template int sgn(T val) { 86 | return (T(0) < val) - (val < T(0)); 87 | } 88 | 89 | ros::Subscriber snapshot_sub_; 90 | void snapshotCallback(const std_msgs::Empty::ConstPtr& msg); 91 | 92 | boost::shared_ptr parameter_thread_; 93 | boost::shared_ptr readout_thread_; 94 | 95 | boost::posix_time::time_duration delta_; 96 | 97 | davis_ros_driver::DAVIS_ROS_DriverConfig current_config_; 98 | camera_info_manager::CameraInfoManager* camera_info_manager_; 99 | 100 | struct caer_davis_info davis_info_; 101 | std::string device_id_; 102 | 103 | ros::Time reset_time_; 104 | 105 | static constexpr double STANDARD_GRAVITY = 9.81; 106 | 107 | ros::Timer timestamp_reset_timer_; 108 | void resetTimerCallback(const ros::TimerEvent& te); 109 | 110 | bool parameter_update_required_; 111 | bool parameter_bias_update_required_; 112 | 113 | }; 114 | 115 | } // namespace 116 | -------------------------------------------------------------------------------- /davis_ros_driver/include/davis_ros_driver/driver_nodelet.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | #include "davis_ros_driver/driver.h" 21 | 22 | namespace davis_ros_driver { 23 | 24 | class DavisRosDriverNodelet : public nodelet::Nodelet { 25 | public: 26 | virtual void onInit(); 27 | 28 | private: 29 | davis_ros_driver::DavisRosDriver* driver_; 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /davis_ros_driver/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | davis_ros_driver 4 | 0.0.0 5 | The davis_ros_driver package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | 11 | roscpp 12 | libcaer_catkin 13 | dvs_msgs 14 | std_msgs 15 | sensor_msgs 16 | dynamic_reconfigure 17 | camera_info_manager 18 | nodelet 19 | 20 | roscpp 21 | libcaer_catkin 22 | dvs_msgs 23 | std_msgs 24 | sensor_msgs 25 | dynamic_reconfigure 26 | camera_info_manager 27 | nodelet 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /davis_ros_driver/src/driver_node.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include 17 | 18 | #include "davis_ros_driver/driver.h" 19 | 20 | int main(int argc, char* argv[]) 21 | { 22 | ros::init(argc, argv, "davis_ros_driver"); 23 | 24 | ros::NodeHandle nh; 25 | ros::NodeHandle nh_private("~"); 26 | 27 | davis_ros_driver::DavisRosDriver* driver = new davis_ros_driver::DavisRosDriver(nh, nh_private); 28 | 29 | ros::spin(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /davis_ros_driver/src/driver_nodelet.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include 17 | 18 | #include "davis_ros_driver/driver_nodelet.h" 19 | 20 | namespace davis_ros_driver 21 | { 22 | 23 | void DavisRosDriverNodelet::onInit() 24 | { 25 | driver_ = new davis_ros_driver::DavisRosDriver(getNodeHandle(), getPrivateNodeHandle()); 26 | 27 | NODELET_INFO_STREAM("Initialized " << getName() << " nodelet."); 28 | } 29 | 30 | PLUGINLIB_DECLARE_CLASS(davis_ros_driver, DavisRosDriverNodelet, davis_ros_driver::DavisRosDriverNodelet, nodelet::Nodelet); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /dvs_driver/88-retina.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="usb|usb_device", ATTR{idVendor}=="152a", ATTR{idProduct}=="8400", MODE="0666", GROUP="plugdev" 2 | 3 | -------------------------------------------------------------------------------- /dvs_driver/88-retinaDAVIS.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="usb|usb_device", ATTR{idVendor}=="152a", ATTR{idProduct}=="840d", MODE="0666", GROUP="plugdev" 2 | 3 | -------------------------------------------------------------------------------- /dvs_driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(dvs_driver) 3 | 4 | # search for everything we need to build the package 5 | find_package(catkin) 6 | 7 | # since we need eigen and boost search them as well 8 | find_package(Boost REQUIRED COMPONENTS thread) 9 | 10 | include(FindPkgConfig) 11 | pkg_check_modules(LIBUSB1 REQUIRED libusb-1.0) 12 | 13 | # export the dependencis of this package for who ever depends on us 14 | catkin_package( 15 | INCLUDE_DIRS include ${LIBUSB1_INCLUDE_DIRS} 16 | DEPENDS libusb-1.0 17 | LIBRARIES dvs_driver 18 | ) 19 | 20 | # tell catkin where to find the headers for this project 21 | include_directories( 22 | include 23 | ${LIBUSB1_INCLUDE_DIRS} 24 | ${Boost_INCLUDE_DIRS} 25 | ) 26 | 27 | # make the library 28 | add_library(dvs_driver 29 | src/dvs_driver.cpp 30 | ) 31 | 32 | target_link_libraries(dvs_driver 33 | ${LIBUSB1_LIBRARIES} 34 | ${Boost_LIBRARIES} 35 | ) 36 | 37 | install(TARGETS dvs_driver 38 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 39 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 40 | RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} 41 | ) 42 | 43 | install(DIRECTORY include/${PROJECT_NAME}/ 44 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 45 | ) 46 | -------------------------------------------------------------------------------- /dvs_driver/include/dvs_driver/dvs_driver.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #ifndef DVS_DRIVER_H_ 17 | #define DVS_DRIVER_H_ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace dvs { 28 | 29 | // DVS USB interface 30 | #define DVS128_VID 0x152A 31 | #define DVS128_PID 0x8400 //this is for DVS 32 | //#define DVS128_PID 0x840D //this is for DAVIS 33 | #define DVS128_DID_TYPE 0x00 34 | 35 | #define USB_IO_ENDPOINT 0x86 36 | 37 | // DVS data decoding masks 38 | #define DVS128_POLARITY_SHIFT 0 39 | #define DVS128_POLARITY_MASK 0x0001 40 | #define DVS128_Y_ADDR_SHIFT 8 41 | #define DVS128_Y_ADDR_MASK 0x007F 42 | #define DVS128_X_ADDR_SHIFT 1 43 | #define DVS128_X_ADDR_MASK 0x007F 44 | #define DVS128_SYNC_EVENT_MASK 0x8000 45 | 46 | // USB vendor requests 47 | #define VENDOR_REQUEST_START_TRANSFER 0xB3 48 | #define VENDOR_REQUEST_STOP_TRANSFER 0xB4 49 | #define VENDOR_REQUEST_SEND_BIASES 0xB8 50 | #define VENDOR_REQUEST_SET_SYNC_ENABLED 0xBE 51 | #define VENDOR_REQUEST_RESET_TIMESTAMPS 0xBB 52 | 53 | struct Event { 54 | uint16_t x, y; 55 | bool polarity; 56 | uint64_t timestamp; 57 | }; 58 | 59 | class DVS_Driver { 60 | public: 61 | DVS_Driver(std::string dvs_serial_number = "", bool master = true); 62 | ~DVS_Driver(); 63 | 64 | std::vector get_events(); 65 | 66 | bool change_parameters(uint32_t cas, uint32_t injGnd, uint32_t reqPd, uint32_t puX, 67 | uint32_t diffOff, uint32_t req, uint32_t refr, uint32_t puY, 68 | uint32_t diffOn, uint32_t diff, uint32_t foll, uint32_t Pr); 69 | 70 | void callback(struct libusb_transfer *transfer); 71 | 72 | void resetTimestamps(); 73 | 74 | inline std::string get_camera_id() { 75 | return camera_id; 76 | } 77 | 78 | private: 79 | bool change_parameter(std::string parameter, uint32_t value); 80 | bool send_parameters(); 81 | 82 | bool open_device(std::string dvs_serial_number = ""); 83 | void close_device(); 84 | 85 | boost::mutex event_buffer_mutex; 86 | boost::mutex device_mutex; 87 | boost::thread* thread; 88 | void run(); 89 | 90 | void event_translator(uint8_t *buffer, size_t bytesSent); 91 | 92 | // USB handle and buffer 93 | libusb_device_handle *device_handle; 94 | struct libusb_transfer *transfer; 95 | unsigned char *buffer; 96 | 97 | // event buffer 98 | std::vector event_buffer; 99 | 100 | // buffers 101 | static const uint32_t bufferNumber = 8; 102 | static const uint32_t bufferSize = 4096; 103 | 104 | uint64_t wrapAdd; 105 | uint64_t lastTimestamp; 106 | 107 | class Parameter { 108 | public: 109 | Parameter(uint32_t min = 0, uint32_t max = 0, uint32_t value = 0) : 110 | _min(min), _max(max), _value(value) {} 111 | 112 | uint32_t get_value() { return _value; } 113 | 114 | bool set_value(uint32_t value) { 115 | if (value >= _min && value <= _max) { 116 | _value = value; 117 | return true; 118 | } 119 | else { 120 | return false; 121 | } 122 | } 123 | private: 124 | uint32_t _min; 125 | uint32_t _max; 126 | uint32_t _value; 127 | 128 | }; 129 | 130 | // parameters 131 | std::map parameters; 132 | 133 | // camera name 134 | std::string camera_id; 135 | }; 136 | 137 | } // namespace 138 | #endif 139 | -------------------------------------------------------------------------------- /dvs_driver/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Copying udev rule (needs root privileges)." 3 | sudo cp 88-retina.rules /etc/udev/rules.d/ 4 | 5 | echo "Reloading udev rules." 6 | sudo udevadm control --reload-rules 7 | sudo udevadm trigger 8 | 9 | echo "Done!" 10 | -------------------------------------------------------------------------------- /dvs_driver/installDAVIS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Copying udev rule (needs root privileges)." 3 | sudo cp 88-retinaDAVIS.rules /etc/udev/rules.d/ 4 | 5 | echo "Reloading udev rules." 6 | sudo udevadm control --reload-rules 7 | sudo udevadm trigger 8 | 9 | echo "Done!" 10 | -------------------------------------------------------------------------------- /dvs_driver/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dvs_driver 4 | 0.0.0 5 | The dvs_driver package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dvs_meanshift/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.intelliSenseEngineFallback": "Disabled" 3 | } -------------------------------------------------------------------------------- /dvs_meanshift/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(dvs_meanshift) 3 | 4 | ## Find catkin macros and libraries 5 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) 6 | ## is used, also find other catkin packages 7 | find_package(catkin REQUIRED COMPONENTS 8 | cv_bridge 9 | dvs_msgs 10 | image_transport 11 | pcl_ros 12 | roscpp 13 | rospy 14 | sensor_msgs 15 | std_msgs 16 | ) 17 | 18 | ## System dependencies are found with CMake's conventions 19 | find_package(Boost REQUIRED) 20 | find_package(OpenCV REQUIRED) 21 | find_package(PCL 1.7 REQUIRED) 22 | 23 | include_directories(${PCL_INCLUDE_DIRS}) 24 | link_directories(${PCL_LIBRARY_DIRS}) 25 | add_definitions(${PCL_DEFINITIONS}) 26 | 27 | ################################### 28 | ## catkin specific configuration ## 29 | ################################### 30 | ## The catkin_package macro generates cmake config files for your package 31 | ## Declare things to be passed to dependent projects 32 | ## INCLUDE_DIRS: uncomment this if you package contains header files 33 | ## LIBRARIES: libraries you create in this project that dependent projects also need 34 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need 35 | ## DEPENDS: system dependencies of this project that dependent projects also need 36 | catkin_package( 37 | INCLUDE_DIRS include 38 | # LIBRARIES dvs_meanshift 39 | CATKIN_DEPENDS cv_bridge dvs_msgs image_transport pcl_ros roscpp rospy sensor_msgs std_msgs 40 | DEPENDS OpenCV boost 41 | ) 42 | 43 | ########### 44 | ## Build ## 45 | ########### 46 | 47 | ## Specify additional locations of header files 48 | ## Your package locations should be listed before other locations 49 | # include_directories(include) 50 | include_directories( 51 | include 52 | ${catkin_INCLUDE_DIRS} 53 | ${OpenCV_INCLUDE_DIRS} 54 | ${Boost_INCLUDE_DIRS} 55 | ) 56 | 57 | ## Add cmake target dependencies of the library 58 | ## as an example, code may need to be generated before libraries 59 | ## either from message generation or dynamic reconfigure 60 | # add_dependencies(dvs_meanshift ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 61 | 62 | ## Declare a C++ executable 63 | # add_executable(dvs_meanshift_node src/dvs_meanshift_node.cpp) 64 | 65 | ## Add cmake target dependencies of the executable 66 | ## same as for the library above 67 | # add_dependencies(dvs_meanshift_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 68 | 69 | ## Specify libraries to link a library or executable target against 70 | # target_link_libraries(dvs_meanshift_node 71 | # ${catkin_LIBRARIES} 72 | # ) 73 | 74 | add_executable(dvs_meanshift src/meanshift.cpp src/meanshift_node.cpp src/color_meanshift.cpp src/segment.cpp src/image_reconst.cpp) 75 | target_link_libraries(dvs_meanshift ${catkin_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${OpenCV_LIBS}) 76 | add_dependencies(dvs_meanshift ${catkin_EXPORTED_TARGETS} ) 77 | -------------------------------------------------------------------------------- /dvs_meanshift/README.md: -------------------------------------------------------------------------------- 1 | # dvs_meanshift -------------------------------------------------------------------------------- /dvs_meanshift/include/dvs_meanshift/color_meanshift.h: -------------------------------------------------------------------------------- 1 | /* 2 | * color_meanshift.h 3 | * 4 | * Created on: Nov 2, 2016 5 | * Author: fran 6 | */ 7 | 8 | #ifndef COLOR_MEANSHIFT_H_ 9 | #define COLOR_MEANSHIFT_H_ 10 | 11 | #include 12 | #include 13 | 14 | void colorMeanShiftFilt(double *newPixelsPtr, const double *pixelsPtr, int mPixels, int maxPixelDim, const double *imagePtr, int numRows, int numCols, float spaceDivider, char *kernelFun, int maxIterNum, float tolFun); 15 | //void colorMeanShiftFilt(double *newPixelsPtr, const double *pixelsPtr, int mPixels, int maxPixelDim, const double *imagePtr, int numRows, int numCols, float spaceDivider, char *kernelFun, int maxIterNum, float tolFun, double *newImagePtr); 16 | void meanshiftCluster_Gaussian(cv::Mat dataPts, std::vector *clusterCenterX, std::vector *clusterCenterY, std::vector *clusterCenterZ, std::vector *point2Clusters, double bandwidth); 17 | 18 | #endif /* COLOR_MEANSHIFT_H_ */ 19 | -------------------------------------------------------------------------------- /dvs_meanshift/include/dvs_meanshift/meanshift.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dvs_meanshift.h 3 | * 4 | * Created on: Nov 2, 2016 5 | * Author: fran 6 | */ 7 | 8 | #ifndef MEANSHIFT_H_ 9 | #define MEANSHIFT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include "graph3d/segment.h" 28 | 29 | #define TEST 0 30 | #define KALMAN_FILTERING 1 31 | #define BG_FILTERING 1 32 | 33 | 34 | #define DVSW 128 //240 35 | #define DVSH 128 //180 36 | 37 | //#define DVSW 240 38 | //#define DVSH 180 39 | 40 | namespace dvs_meanshift 41 | { 42 | 43 | class Meanshift { 44 | public: 45 | Meanshift(ros::NodeHandle & nh, ros::NodeHandle nh_private); 46 | virtual ~Meanshift(); 47 | 48 | private: 49 | ros::NodeHandle nh_; 50 | 51 | void cameraInfoCallback(const sensor_msgs::CameraInfo::ConstPtr& msg); 52 | void eventsCallback(const dvs_msgs::EventArray::ConstPtr& msg); 53 | void eventsCallback_simple(const dvs_msgs::EventArray::ConstPtr& msg); 54 | 55 | //void assignClusterColor(std::vector * positionClusterColor, int numClusters, std::vector matches, std::vector oldPositions); 56 | void assignClusterColor(std::vector * positionClusterColor, int numClusters, std::vector matches, std::vector oldPositions, std::vector activeTrajectories); 57 | //void createKalmanFilter(); 58 | void createKalmanFilter(cv::KalmanFilter *kf, cv::Mat *state, cv::Mat *meas); 59 | 60 | int lastPositionClusterColor; 61 | 62 | cv::Mat camera_matrix_, dist_coeffs_; 63 | 64 | ros::Subscriber event_sub_; 65 | ros::Subscriber camera_info_sub_; 66 | 67 | image_transport::Publisher image_pub_; 68 | image_transport::Publisher image_segmentation_pub_; 69 | 70 | 71 | //DEBUG 72 | image_transport::Publisher image_debug1_pub_; 73 | image_transport::Publisher image_debug2_pub_; 74 | //NOT DEBUG 75 | 76 | 77 | cv::Mat last_image_; 78 | bool used_last_image_; 79 | 80 | enum DisplayMethod 81 | { 82 | GRAYSCALE, RED_BLUE 83 | } display_method_; 84 | 85 | //Meanshift params 86 | //computing image calibration 87 | double *outputFeatures; 88 | int mPixels, maxPixelDim; 89 | double *pixelsPtr; 90 | double *imagePtr; 91 | //double *positionsPtr; 92 | double *initializationPtr; 93 | int numRows, numCols, maxIterNum; 94 | float spaceDivider, timeDivider; 95 | char kernelFun[8]; 96 | float tolFun; 97 | 98 | //Params for graph3d segmentation 99 | static const int MAX_NUM_CLUSTERS = 256; 100 | static const int MAX_NUM_TRAJECTORY_POINTS=16; 101 | std::vector RGBColors; 102 | std::vector *allTrajectories; //It is an array of vectors of Points for storing trajectories (a maximum of 8 points should be stored) 103 | std::vector counterTrajectories; //It stores the last position occupied for each trajectory in allTrajectories 104 | 105 | float sigma; 106 | int k; 107 | int min_region; 108 | int num_components; 109 | 110 | //Clusters 111 | std::vector prev_clustCentX, prev_clustCentY, prev_clustCentZ; 112 | std::vector prev_positionClusterColor; 113 | std::vector clustColor; 114 | std::vector prev_activeTrajectories; 115 | 116 | //Trajectories 117 | //cv::Mat trajectories=cv::Mat(DVSH, DVSW, CV_8UC3); 118 | cv::Mat trajectories; 119 | 120 | //Kalman filter parameters 121 | //cv::KalmanFilter kf; 122 | //cv::Mat state; 123 | //cv::Mat meas; 124 | 125 | std::vector vector_of_kf; 126 | std::vector vector_of_state; 127 | std::vector vector_of_meas; 128 | 129 | //bool foundBlobs; 130 | std::vector vector_of_foundBlobs; 131 | int notFoundBlobsCount; 132 | std::vector foundTrajectory; 133 | //bool foundTrajectory; 134 | int selectedTrajectory; 135 | //double ticks; 136 | std::vector vector_of_ticks; 137 | 138 | //frame of times 139 | cv::Mat BGAFframe; 140 | }; 141 | 142 | } // namespace 143 | 144 | #endif // MEANSHIFT_H_ 145 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/convolve.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* convolution */ 20 | 21 | #ifndef CONVOLVE_H 22 | #define CONVOLVE_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include "graph3d/image.h" 28 | 29 | /* convolve src with mask. dst is flipped! */ 30 | static void convolve_even(image *src, image *dst, 31 | std::vector &mask) { 32 | int width = src->width(); 33 | int height = src->height(); 34 | int len = mask.size(); 35 | 36 | for (int y = 0; y < height; y++) { 37 | for (int x = 0; x < width; x++) { 38 | float sum = mask[0] * imRef(src, x, y); 39 | for (int i = 1; i < len; i++) { 40 | sum += mask[i] * 41 | (imRef(src, std::max(x-i,0), y) + 42 | imRef(src, std::min(x+i, width-1), y)); 43 | } 44 | imRef(dst, y, x) = sum; 45 | } 46 | } 47 | } 48 | 49 | /* convolve src with mask. dst is flipped! */ 50 | static void convolve_odd(image *src, image *dst, 51 | std::vector &mask) { 52 | int width = src->width(); 53 | int height = src->height(); 54 | int len = mask.size(); 55 | 56 | for (int y = 0; y < height; y++) { 57 | for (int x = 0; x < width; x++) { 58 | float sum = mask[0] * imRef(src, x, y); 59 | for (int i = 1; i < len; i++) { 60 | sum += mask[i] * 61 | (imRef(src, std::max(x-i,0), y) - 62 | imRef(src, std::min(x+i, width-1), y)); 63 | } 64 | imRef(dst, y, x) = sum; 65 | } 66 | } 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/disjoint-set.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef DISJOINT_SET 20 | #define DISJOINT_SET 21 | 22 | // disjoint-set forests using union-by-rank and path compression (sort of). 23 | 24 | typedef struct { 25 | int rank; 26 | int p; 27 | int size; 28 | } uni_elt; 29 | 30 | class universe { 31 | public: 32 | universe(int elements); 33 | ~universe(); 34 | int find(int x); 35 | void join(int x, int y); 36 | int size(int x) const { return elts[x].size; } 37 | int num_sets() const { return num; } 38 | 39 | private: 40 | uni_elt *elts; 41 | int num; 42 | }; 43 | 44 | universe::universe(int elements) { 45 | elts = new uni_elt[elements]; 46 | num = elements; 47 | for (int i = 0; i < elements; i++) { 48 | elts[i].rank = 0; 49 | elts[i].size = 1; 50 | elts[i].p = i; 51 | } 52 | } 53 | 54 | universe::~universe() { 55 | delete [] elts; 56 | } 57 | 58 | int universe::find(int x) { 59 | int y = x; 60 | while (y != elts[y].p) 61 | y = elts[y].p; 62 | elts[x].p = y; 63 | return y; 64 | } 65 | 66 | void universe::join(int x, int y) { 67 | if (elts[x].rank > elts[y].rank) { 68 | elts[y].p = x; 69 | elts[x].size += elts[y].size; 70 | } else { 71 | elts[x].p = y; 72 | elts[y].size += elts[x].size; 73 | if (elts[x].rank == elts[y].rank) 74 | elts[y].rank++; 75 | } 76 | num--; 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* simple filters */ 20 | 21 | #ifndef FILTER_H 22 | #define FILTER_H 23 | 24 | #include 25 | #include 26 | #include "graph3d/image.h" 27 | #include "graph3d/misc.h" 28 | #include "graph3d/convolve.h" 29 | #include "graph3d/imconv.h" 30 | 31 | #define WIDTH 4.0 32 | 33 | /* normalize mask so it integrates to one */ 34 | static void normalize(std::vector &mask) { 35 | int len = mask.size(); 36 | float sum = 0; 37 | for (int i = 1; i < len; i++) { 38 | sum += fabs(mask[i]); 39 | } 40 | sum = 2*sum + fabs(mask[0]); 41 | for (int i = 0; i < len; i++) { 42 | mask[i] /= sum; 43 | } 44 | } 45 | 46 | /* make filters */ 47 | #define MAKE_FILTER(name, fun) \ 48 | static std::vector make_ ## name (float sigma) { \ 49 | sigma = std::max(sigma, 0.01F); \ 50 | int len = (int)ceil(sigma * WIDTH) + 1; \ 51 | std::vector mask(len); \ 52 | for (int i = 0; i < len; i++) { \ 53 | mask[i] = fun; \ 54 | } \ 55 | return mask; \ 56 | } 57 | 58 | MAKE_FILTER(fgauss, exp(-0.5*square(i/sigma))); 59 | 60 | /* convolve image with gaussian filter */ 61 | static image *smooth(image *src, float sigma) { 62 | std::vector mask = make_fgauss(sigma); 63 | normalize(mask); 64 | 65 | image *tmp = new image(src->height(), src->width(), false); 66 | image *dst = new image(src->width(), src->height(), false); 67 | convolve_even(src, tmp, mask); 68 | convolve_even(tmp, dst, mask); 69 | 70 | delete tmp; 71 | return dst; 72 | } 73 | 74 | /* convolve image with gaussian filter */ 75 | image *smooth(image *src, float sigma) { 76 | image *tmp = imageUCHARtoFLOAT(src); 77 | image *dst = smooth(tmp, sigma); 78 | delete tmp; 79 | return dst; 80 | } 81 | 82 | /* compute laplacian */ 83 | static image *laplacian(image *src) { 84 | int width = src->width(); 85 | int height = src->height(); 86 | image *dst = new image(width, height); 87 | 88 | for (int y = 1; y < height-1; y++) { 89 | for (int x = 1; x < width-1; x++) { 90 | float d2x = imRef(src, x-1, y) + imRef(src, x+1, y) - 91 | 2*imRef(src, x, y); 92 | float d2y = imRef(src, x, y-1) + imRef(src, x, y+1) - 93 | 2*imRef(src, x, y); 94 | imRef(dst, x, y) = d2x + d2y; 95 | } 96 | } 97 | return dst; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/image.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* a simple image class */ 20 | 21 | #ifndef IMAGE_H 22 | #define IMAGE_H 23 | 24 | #include 25 | 26 | template 27 | class image { 28 | public: 29 | /* create an image */ 30 | image(const int width, const int height, const bool init = true); 31 | 32 | /* delete an image */ 33 | ~image(); 34 | 35 | /* init an image */ 36 | void init(const T &val); 37 | 38 | /* copy an image */ 39 | image *copy() const; 40 | 41 | /* get the width of an image. */ 42 | int width() const { return w; } 43 | 44 | /* get the height of an image. */ 45 | int height() const { return h; } 46 | 47 | /* image data. */ 48 | T *data; 49 | 50 | /* row pointers. */ 51 | T **access; 52 | 53 | private: 54 | int w, h; 55 | }; 56 | 57 | /* use imRef to access image data. */ 58 | #define imRef(im, x, y) (im->access[y][x]) 59 | 60 | /* use imPtr to get pointer to image data. */ 61 | #define imPtr(im, x, y) &(im->access[y][x]) 62 | 63 | template 64 | image::image(const int width, const int height, const bool init) { 65 | w = width; 66 | h = height; 67 | data = new T[w * h]; // allocate space for image data 68 | access = new T*[h]; // allocate space for row pointers 69 | 70 | // initialize row pointers 71 | for (int i = 0; i < h; i++) 72 | access[i] = data + (i * w); 73 | 74 | if (init) 75 | memset(data, 0, w * h * sizeof(T)); 76 | } 77 | 78 | template 79 | image::~image() { 80 | delete [] data; 81 | delete [] access; 82 | } 83 | 84 | template 85 | void image::init(const T &val) { 86 | T *ptr = imPtr(this, 0, 0); 87 | T *end = imPtr(this, w-1, h-1); 88 | while (ptr <= end) 89 | *ptr++ = val; 90 | } 91 | 92 | 93 | template 94 | image *image::copy() const { 95 | image *im = new image(w, h, false); 96 | memcpy(im->data, data, w * h * sizeof(T)); 97 | return im; 98 | } 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/imconv.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* image conversion */ 20 | 21 | #ifndef CONV_H 22 | #define CONV_H 23 | 24 | #include 25 | #include "graph3d/image.h" 26 | #include "graph3d/imutil.h" 27 | #include "graph3d/misc.h" 28 | 29 | #define RED_WEIGHT 0.299 30 | #define GREEN_WEIGHT 0.587 31 | #define BLUE_WEIGHT 0.114 32 | 33 | static image *imageRGBtoGRAY(image *input) { 34 | int width = input->width(); 35 | int height = input->height(); 36 | image *output = new image(width, height, false); 37 | 38 | for (int y = 0; y < height; y++) { 39 | for (int x = 0; x < width; x++) { 40 | imRef(output, x, y) = (uchar) 41 | (imRef(input, x, y).r * RED_WEIGHT + 42 | imRef(input, x, y).g * GREEN_WEIGHT + 43 | imRef(input, x, y).b * BLUE_WEIGHT); 44 | } 45 | } 46 | return output; 47 | } 48 | 49 | static image *imageGRAYtoRGB(image *input) { 50 | int width = input->width(); 51 | int height = input->height(); 52 | image *output = new image(width, height, false); 53 | 54 | for (int y = 0; y < height; y++) { 55 | for (int x = 0; x < width; x++) { 56 | imRef(output, x, y).r = imRef(input, x, y); 57 | imRef(output, x, y).g = imRef(input, x, y); 58 | imRef(output, x, y).b = imRef(input, x, y); 59 | } 60 | } 61 | return output; 62 | } 63 | 64 | static image *imageUCHARtoFLOAT(image *input) { 65 | int width = input->width(); 66 | int height = input->height(); 67 | image *output = new image(width, height, false); 68 | 69 | for (int y = 0; y < height; y++) { 70 | for (int x = 0; x < width; x++) { 71 | imRef(output, x, y) = imRef(input, x, y); 72 | } 73 | } 74 | return output; 75 | } 76 | 77 | static image *imageINTtoFLOAT(image *input) { 78 | int width = input->width(); 79 | int height = input->height(); 80 | image *output = new image(width, height, false); 81 | 82 | for (int y = 0; y < height; y++) { 83 | for (int x = 0; x < width; x++) { 84 | imRef(output, x, y) = imRef(input, x, y); 85 | } 86 | } 87 | return output; 88 | } 89 | 90 | static image *imageFLOATtoUCHAR(image *input, 91 | float min, float max) { 92 | int width = input->width(); 93 | int height = input->height(); 94 | image *output = new image(width, height, false); 95 | 96 | if (max == min) 97 | return output; 98 | 99 | float scale = UCHAR_MAX / (max - min); 100 | for (int y = 0; y < height; y++) { 101 | for (int x = 0; x < width; x++) { 102 | uchar val = (uchar)((imRef(input, x, y) - min) * scale); 103 | imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); 104 | } 105 | } 106 | return output; 107 | } 108 | 109 | static image *imageFLOATtoUCHAR(image *input) { 110 | float min, max; 111 | min_max(input, &min, &max); 112 | return imageFLOATtoUCHAR(input, min, max); 113 | } 114 | 115 | static image *imageUCHARtoLONG(image *input) { 116 | int width = input->width(); 117 | int height = input->height(); 118 | image *output = new image(width, height, false); 119 | 120 | for (int y = 0; y < height; y++) { 121 | for (int x = 0; x < width; x++) { 122 | imRef(output, x, y) = imRef(input, x, y); 123 | } 124 | } 125 | return output; 126 | } 127 | 128 | static image *imageLONGtoUCHAR(image *input, long min, long max) { 129 | int width = input->width(); 130 | int height = input->height(); 131 | image *output = new image(width, height, false); 132 | 133 | if (max == min) 134 | return output; 135 | 136 | float scale = UCHAR_MAX / (float)(max - min); 137 | for (int y = 0; y < height; y++) { 138 | for (int x = 0; x < width; x++) { 139 | uchar val = (uchar)((imRef(input, x, y) - min) * scale); 140 | imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); 141 | } 142 | } 143 | return output; 144 | } 145 | 146 | static image *imageLONGtoUCHAR(image *input) { 147 | long min, max; 148 | min_max(input, &min, &max); 149 | return imageLONGtoUCHAR(input, min, max); 150 | } 151 | 152 | static image *imageSHORTtoUCHAR(image *input, 153 | short min, short max) { 154 | int width = input->width(); 155 | int height = input->height(); 156 | image *output = new image(width, height, false); 157 | 158 | if (max == min) 159 | return output; 160 | 161 | float scale = UCHAR_MAX / (float)(max - min); 162 | for (int y = 0; y < height; y++) { 163 | for (int x = 0; x < width; x++) { 164 | uchar val = (uchar)((imRef(input, x, y) - min) * scale); 165 | imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); 166 | } 167 | } 168 | return output; 169 | } 170 | 171 | static image *imageSHORTtoUCHAR(image *input) { 172 | short min, max; 173 | min_max(input, &min, &max); 174 | return imageSHORTtoUCHAR(input, min, max); 175 | } 176 | 177 | #endif 178 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/imutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* some image utilities */ 20 | 21 | #ifndef IMUTIL_H 22 | #define IMUTIL_H 23 | 24 | #include "graph3d/image.h" 25 | #include "graph3d/misc.h" 26 | 27 | /* compute minimum and maximum value in an image */ 28 | template 29 | void min_max(image *im, T *ret_min, T *ret_max) { 30 | int width = im->width(); 31 | int height = im->height(); 32 | 33 | T min = imRef(im, 0, 0); 34 | T max = imRef(im, 0, 0); 35 | for (int y = 0; y < height; y++) { 36 | for (int x = 0; x < width; x++) { 37 | T val = imRef(im, x, y); 38 | if (min > val) 39 | min = val; 40 | if (max < val) 41 | max = val; 42 | } 43 | } 44 | 45 | *ret_min = min; 46 | *ret_max = max; 47 | } 48 | 49 | /* threshold image */ 50 | template 51 | image *threshold(image *src, int t) { 52 | int width = src->width(); 53 | int height = src->height(); 54 | image *dst = new image(width, height); 55 | 56 | for (int y = 0; y < height; y++) { 57 | for (int x = 0; x < width; x++) { 58 | imRef(dst, x, y) = (imRef(src, x, y) >= t); 59 | } 60 | } 61 | 62 | return dst; 63 | } 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* random stuff */ 20 | 21 | #ifndef MISC_H 22 | #define MISC_H 23 | 24 | #include 25 | 26 | #ifndef M_PI 27 | #define M_PI 3.141592653589793 28 | #endif 29 | 30 | typedef unsigned char uchar; 31 | 32 | typedef struct { uchar r, g, b; } rgb; 33 | 34 | inline bool operator==(const rgb &a, const rgb &b) { 35 | return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b)); 36 | } 37 | 38 | template 39 | inline T abs(const T &x) { return (x > 0 ? x : -x); }; 40 | 41 | template 42 | inline int sign(const T &x) { return (x >= 0 ? 1 : -1); }; 43 | 44 | template 45 | inline T square(const T &x) { return x*x; }; 46 | 47 | template 48 | inline T bound(const T &x, const T &min, const T &max) { 49 | return (x < min ? min : (x > max ? max : x)); 50 | } 51 | 52 | template 53 | inline bool check_bound(const T &x, const T&min, const T &max) { 54 | return ((x < min) || (x > max)); 55 | } 56 | 57 | inline int vlib_round(float x) { return (int)(x + 0.5F); } 58 | 59 | inline int vlib_round(double x) { return (int)(x + 0.5); } 60 | 61 | inline double gaussian(double val, double sigma) { 62 | return exp(-square(val/sigma)/2)/(sqrt(2*M_PI)*sigma); 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/segment-graph.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef SEGMENT_GRAPH 20 | #define SEGMENT_GRAPH 21 | 22 | #include 23 | #include 24 | #include "graph3d/disjoint-set.h" 25 | 26 | // threshold function 27 | #define THRESHOLD(size, c) (c/size) 28 | 29 | typedef struct { 30 | float w; 31 | int a, b; 32 | } edge; 33 | 34 | bool operator<(const edge &a, const edge &b) { 35 | return a.w < b.w; 36 | } 37 | 38 | /* 39 | * Segment a graph 40 | * 41 | * Returns a disjoint-set forest representing the segmentation. 42 | * 43 | * num_vertices: number of vertices in graph. 44 | * num_edges: number of edges in graph 45 | * edges: array of edges. 46 | * c: constant for treshold function. 47 | */ 48 | universe *segment_graph(int num_vertices, int num_edges, edge *edges, 49 | float c) { 50 | // sort edges by weight 51 | std::sort(edges, edges + num_edges); 52 | 53 | // make a disjoint-set forest 54 | universe *u = new universe(num_vertices); 55 | 56 | // init thresholds 57 | float *threshold = new float[num_vertices]; 58 | for (int i = 0; i < num_vertices; i++) 59 | threshold[i] = THRESHOLD(1,c); 60 | 61 | // for each edge, in non-decreasing weight order... 62 | for (int i = 0; i < num_edges; i++) { 63 | edge *pedge = &edges[i]; 64 | 65 | // components conected by this edge 66 | int a = u->find(pedge->a); 67 | int b = u->find(pedge->b); 68 | if (a != b) { 69 | if ((pedge->w <= threshold[a]) && 70 | (pedge->w <= threshold[b])) { 71 | u->join(a, b); 72 | a = u->find(a); 73 | threshold[a] = pedge->w + THRESHOLD(u->size(a), c); 74 | } 75 | } 76 | } 77 | 78 | // free up 79 | delete threshold; 80 | return u; 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/segment-image.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef SEGMENT_IMAGE 20 | #define SEGMENT_IMAGE 21 | 22 | #include 23 | #include "graph3d/image.h" 24 | #include "graph3d/misc.h" 25 | #include "graph3d/filter.h" 26 | #include "graph3d/segment-graph.h" 27 | 28 | // random color 29 | rgb random_rgb(){ 30 | rgb c; 31 | double r; 32 | 33 | c.r = (uchar)random(); 34 | c.g = (uchar)random(); 35 | c.b = (uchar)random(); 36 | 37 | return c; 38 | } 39 | 40 | // dissimilarity measure between pixels 41 | static inline float diff(image *r, image *g, image *b, 42 | int x1, int y1, int x2, int y2) { 43 | return sqrt(square(imRef(r, x1, y1)-imRef(r, x2, y2)) + 44 | square(imRef(g, x1, y1)-imRef(g, x2, y2)) + 45 | square(imRef(b, x1, y1)-imRef(b, x2, y2))); 46 | } 47 | 48 | /* 49 | * Segment an image 50 | * 51 | * Returns a color image representing the segmentation. 52 | * 53 | * im: image to segment. 54 | * sigma: to smooth the image. 55 | * c: constant for treshold function. 56 | * min_size: minimum component size (enforced by post-processing stage). 57 | * num_ccs: number of connected components in the segmentation. 58 | */ 59 | image *segment_image(image *im, float sigma, float c, int min_size, int *num_ccs) { 60 | int width = im->width(); 61 | int height = im->height(); 62 | 63 | image *r = new image(width, height); 64 | image *g = new image(width, height); 65 | image *b = new image(width, height); 66 | 67 | // smooth each color channel 68 | for (int y = 0; y < height; y++) { 69 | for (int x = 0; x < width; x++) { 70 | imRef(r, x, y) = imRef(im, x, y).r; 71 | imRef(g, x, y) = imRef(im, x, y).g; 72 | imRef(b, x, y) = imRef(im, x, y).b; 73 | } 74 | } 75 | image *smooth_r = smooth(r, sigma); 76 | image *smooth_g = smooth(g, sigma); 77 | image *smooth_b = smooth(b, sigma); 78 | delete r; 79 | delete g; 80 | delete b; 81 | 82 | // build graph 83 | edge *edges = new edge[width*height*4]; 84 | int num = 0; 85 | for (int y = 0; y < height; y++) { 86 | for (int x = 0; x < width; x++) { 87 | if (x < width-1) { 88 | edges[num].a = y * width + x; 89 | edges[num].b = y * width + (x+1); 90 | edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y); 91 | num++; 92 | } 93 | 94 | if (y < height-1) { 95 | edges[num].a = y * width + x; 96 | edges[num].b = (y+1) * width + x; 97 | edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x, y+1); 98 | num++; 99 | } 100 | 101 | if ((x < width-1) && (y < height-1)) { 102 | edges[num].a = y * width + x; 103 | edges[num].b = (y+1) * width + (x+1); 104 | edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y+1); 105 | num++; 106 | } 107 | 108 | if ((x < width-1) && (y > 0)) { 109 | edges[num].a = y * width + x; 110 | edges[num].b = (y-1) * width + (x+1); 111 | edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y-1); 112 | num++; 113 | } 114 | } 115 | } 116 | delete smooth_r; 117 | delete smooth_g; 118 | delete smooth_b; 119 | 120 | // segment 121 | universe *u = segment_graph(width*height, num, edges, c); 122 | 123 | // post process small components 124 | for (int i = 0; i < num; i++) { 125 | int a = u->find(edges[i].a); 126 | int b = u->find(edges[i].b); 127 | if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size))) 128 | u->join(a, b); 129 | } 130 | delete [] edges; 131 | *num_ccs = u->num_sets(); 132 | 133 | image *output = new image(width, height); 134 | 135 | // pick random colors for each component 136 | rgb *colors = new rgb[width*height]; 137 | for (int i = 0; i < width*height; i++) 138 | colors[i] = random_rgb(); 139 | 140 | for (int y = 0; y < height; y++) { 141 | for (int x = 0; x < width; x++) { 142 | int comp = u->find(y * width + x); 143 | imRef(output, x, y) = colors[comp]; 144 | } 145 | } 146 | 147 | delete [] colors; 148 | delete u; 149 | 150 | return output; 151 | } 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /dvs_meanshift/include/graph3d/segment.h: -------------------------------------------------------------------------------- 1 | /* 2 | * segment.h 3 | * 4 | * Created on: Nov 3, 2016 5 | * Author: fran 6 | */ 7 | 8 | #ifndef SEGMENT_H_ 9 | #define SEGMENT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | void imadjust(const cv::Mat & src, cv::Mat & dst); 17 | void im2segment(cv::Mat input, cv::Mat cv_image_output, float sigma, float k, int min_size, int *num_ccs); 18 | 19 | #endif /* SEGMENT_H_ */ 20 | -------------------------------------------------------------------------------- /dvs_meanshift/include/image_reconstruct/image_reconst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * image_reconst.h 3 | * 4 | * Created on: Nov 3, 2016 5 | * Author: fran 6 | */ 7 | 8 | #ifndef IMAGE_RECONST_H_ 9 | #define IMAGE_RECONST_H_ 10 | 11 | #include "opencv/cv.h" 12 | #include "opencv/cxcore.h" 13 | #include "opencv/highgui.h" 14 | //#include "opencv2/core/core.hpp" 15 | 16 | 17 | void dst(double *btest, double *bfinal, int h, int w); 18 | void idst(double *btest, double *bfinal, int h, int w); 19 | void transpose(double *mat, double *mat_t, int h, int w); 20 | 21 | void getGradientX(cv::Mat &img, cv::Mat &gx); 22 | void getGradientY(cv::Mat &img, cv::Mat &gy); 23 | void lapx(cv::Mat &gx, cv::Mat &gxx); 24 | void lapy(cv::Mat &gy, cv::Mat &gyy); 25 | 26 | void poisson_solver(cv::Mat &img, cv::Mat &gxx, cv::Mat &gyy, cv::Mat &result); 27 | void poisson_solver_jacobi(cv::Mat &img, cv::Mat &gxx, cv::Mat &gyy, cv::Mat &result); 28 | 29 | 30 | //IPL Image versions (legacy) 31 | void lapx( const IplImage *img, IplImage *gxx); 32 | void lapy( const IplImage *img, IplImage *gyy); 33 | void poisson_solver(const IplImage *img, IplImage *gxx , IplImage *gyy, cv::Mat &result); 34 | #endif /* IMAGE_RECONST_H_ */ 35 | -------------------------------------------------------------------------------- /dvs_meanshift/launch/dvs_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /dvs_meanshift/launch/dvs_segmentation.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /dvs_meanshift/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dvs_meanshift 4 | 0.0.0 5 | The dvs_meanshift package 6 | 7 | 8 | 9 | 10 | fran 11 | 12 | 13 | 14 | 15 | 16 | TODO 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | catkin 43 | cv_bridge 44 | dvs_msgs 45 | image_transport 46 | pcl_ros 47 | roscpp 48 | rospy 49 | sensor_msgs 50 | std_msgs 51 | cv_bridge 52 | dvs_msgs 53 | image_transport 54 | pcl_ros 55 | roscpp 56 | rospy 57 | sensor_msgs 58 | std_msgs 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /dvs_meanshift/src/README: -------------------------------------------------------------------------------- 1 | 2 | Implementation of the segmentation algorithm described in: 3 | 4 | Efficient Graph-Based Image Segmentation 5 | Pedro F. Felzenszwalb and Daniel P. Huttenlocher 6 | International Journal of Computer Vision, 59(2) September 2004. 7 | 8 | The program takes a color image (PPM format) and produces a segmentation 9 | with a random color assigned to each region. 10 | 11 | 1) Type "make" to compile "segment". 12 | 13 | 2) Run "segment sigma k min input output". 14 | 15 | The parameters are: (see the paper for details) 16 | 17 | sigma: Used to smooth the input image before segmenting it. 18 | k: Value for the threshold function. 19 | min: Minimum component size enforced by post-processing. 20 | input: Input image. 21 | output: Output image. 22 | 23 | Typical parameters are sigma = 0.5, k = 500, min = 20. 24 | Larger values for k result in larger components in the result. 25 | 26 | -------------------------------------------------------------------------------- /dvs_meanshift/src/meanshift_node.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "dvs_meanshift/meanshift.h" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | ros::init(argc, argv, "dvs_meanshift"); 8 | 9 | ros::NodeHandle nh; 10 | ros::NodeHandle nh_private("~"); 11 | 12 | dvs_meanshift::Meanshift meanshift(nh, nh_private); 13 | 14 | ros::spin(); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /dvs_meanshift/src/segment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include 20 | #include 21 | #include "graph3d/segment.h" 22 | #include "graph3d/image.h" 23 | #include "graph3d/misc.h" 24 | #include "graph3d/pnmfile.h" 25 | #include "graph3d/segment-image.h" 26 | 27 | 28 | /*#include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "graph3d/image.h" 34 | #include "graph3d/misc.h" 35 | #include "graph3d/pnmfile.h" 36 | #include "graph3d/segment-image.h" 37 | 38 | 39 | int main(int argc, char **argv) { 40 | if (argc != 6) { 41 | fprintf(stderr, "usage: %s sigma k min input(ppm) output(ppm)\n", argv[0]); 42 | return 1; 43 | } 44 | 45 | float sigma = atof(argv[1]); 46 | float k = atof(argv[2]); 47 | int min_size = atoi(argv[3]); 48 | 49 | printf("loading input image.\n"); 50 | image *input = loadPPM(argv[4]); 51 | 52 | printf("processing\n"); 53 | int num_ccs; 54 | image *seg = segment_image(input, sigma, k, min_size, &num_ccs); 55 | savePPM(seg, argv[5]); 56 | 57 | 58 | printf("got %d components\n", num_ccs); 59 | printf("done! uff...thats hard work.\n"); 60 | 61 | return 0; 62 | }*/ 63 | 64 | 65 | 66 | //void imadjust(const cv::Mat & src, cv::Mat & dst, int tol = 1, cv::Vec2i in = cv::Vec2i(0, 255), cv::Vec2i out = cv::Vec2i(0, 255)) 67 | void imadjust(const cv::Mat & src, cv::Mat & dst) 68 | { 69 | // src : input CV_8UC1 image 70 | // dst : output CV_8UC1 imge 71 | // tol : tolerance, from 0 to 100. 72 | // in : src image bounds 73 | // out : dst image buonds 74 | 75 | int in[2]; in[0]=0; in[1]=255; 76 | int out[2]; out[0]=0; out[1]=255; 77 | int tol =1; 78 | 79 | 80 | 81 | dst = src.clone(); 82 | 83 | tol = std::max(0, std::min(100, tol)); 84 | 85 | if (tol > 0) 86 | { 87 | // Compute in and out limits 88 | 89 | // Histogram 90 | std::vector hist(256, 0); 91 | for (int r = 0; r < src.rows; ++r) { 92 | for (int c = 0; c < src.cols; ++c) { 93 | hist[src.at(cv::Point(r,c))]++; 94 | } 95 | } 96 | 97 | // Cumulative histogram 98 | std::vector cum = hist; 99 | for (int i = 1; i < hist.size(); ++i) { 100 | cum[i] = cum[i - 1] + hist[i]; 101 | } 102 | 103 | // Compute bounds 104 | int total = src.rows * src.cols; 105 | int low_bound = total * tol / 100; 106 | int upp_bound = total * (100-tol) / 100; 107 | in[0] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), low_bound)); 108 | in[1] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), upp_bound)); 109 | 110 | } 111 | 112 | // Stretching 113 | float scale = float(out[1] - out[0]) / float(in[1] - in[0]); 114 | for (int r = 0; r < dst.rows; ++r) 115 | { 116 | for (int c = 0; c < dst.cols; ++c) 117 | { 118 | int vs = std::max(src.at(cv::Point(r, c)) - in[0], 0); 119 | 120 | 121 | int vd = std::min(int(vs * scale + 0.5f) + out[0], out[1]); 122 | dst.at(cv::Point(r, c)) = cv::saturate_cast(vd); 123 | } 124 | } 125 | } 126 | 127 | //This function is just an interface to call the segment_image function 128 | void im2segment(cv::Mat input, cv::Mat cv_image_output, float sigma, float k, int min_size, int *num_ccs) 129 | { 130 | 131 | image *inputIm=new image(input.cols, input.rows); 132 | 133 | 134 | for (int y = 0; y < input.rows; y++) { 135 | for (int x = 0; x < input.cols; x++) { 136 | imRef(inputIm, x, y).r = input.at(cv::Point(x, y)); 137 | imRef(inputIm, x, y).g = input.at(cv::Point(x, y)); 138 | imRef(inputIm, x, y).b = input.at(cv::Point(x, y)); 139 | } 140 | } 141 | 142 | std::cout<<"I'm here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"< *seg = segment_image(inputIm, sigma, k, min_size, num_ccs); 146 | 147 | //cv_image_output.encoding = "bgr8"; 148 | //cv_image_output.image =cv::Mat(input.rows, input.cols, CV_8UC3); 149 | 150 | for (int y = 0; y < input.rows; y++) { 151 | for (int x = 0; x < input.cols; x++) { 152 | //output.at(cv::Point(x, y))=imRef(seg, x, y); 153 | cv_image_output.at(cv::Point(x, y)) = ( \ 154 | cv::Vec3b(imRef(seg,x,y).b, imRef(seg,x,y).g, imRef(seg,x,y).r)); 155 | } 156 | } 157 | 158 | 159 | /*image *inputTmp=new image(input.cols, input.rows);; 160 | for (int y = 0; y < input.rows; y++) { 161 | for (int x = 0; x < input.cols; x++) { 162 | imRef(inputTmp, x, y) = input.at(cv::Point(x, y)); 163 | } 164 | } 165 | savePGM(inputTmp, "/home/fran/input_image.ppm"); 166 | */ 167 | 168 | //printf("got %d components\n", num_ccs); 169 | //printf("done! uff...thats hard work.\n"); 170 | } 171 | 172 | -------------------------------------------------------------------------------- /dvs_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(dvs_msgs) 3 | 4 | # search for everything we need to build the messages, dont forget the message_generation 5 | find_package(catkin REQUIRED COMPONENTS 6 | message_generation 7 | std_msgs 8 | ) 9 | 10 | # search for all msg files 11 | FILE(GLOB messages_to_build RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/msg" 12 | "${CMAKE_CURRENT_SOURCE_DIR}/msg/*.msg") 13 | 14 | # notify catkin to look at the previously found msg files 15 | add_message_files( 16 | FILES 17 | ${messages_to_build} 18 | ) 19 | 20 | # build the header files from the msg files, and notify catkin about the dependencies 21 | generate_messages( 22 | DEPENDENCIES 23 | std_msgs 24 | ) 25 | 26 | # export the dependencis of this package for who ever depends on us 27 | catkin_package( 28 | CATKIN_DEPENDS message_runtime std_msgs 29 | ) 30 | 31 | include_directories( 32 | ${catkin_INCLUDE_DIRS} 33 | ) 34 | 35 | -------------------------------------------------------------------------------- /dvs_msgs/EventArrayRule.bmr: -------------------------------------------------------------------------------- 1 | class update_dvs_msgs_EventArray_d2e726b2040dbc135644f4709c150a10(MessageUpdateRule): 2 | old_type = "dvs_msgs/EventArray" 3 | old_full_text = """ 4 | # an array of events 5 | Event[] events 6 | 7 | ================================================================================ 8 | MSG: dvs_msgs/Event 9 | # A DVS event 10 | uint16 x 11 | uint16 y 12 | uint64 time 13 | bool polarity 14 | """ 15 | 16 | new_type = "dvs_msgs/EventArray" 17 | new_full_text = """ 18 | # This message contains an array of events 19 | # (0, 0) is at top-left corner of image 20 | # 21 | 22 | Header header 23 | 24 | uint32 height # image height, that is, number of rows 25 | uint32 width # image width, that is, number of columns 26 | 27 | # an array of events 28 | Event[] events 29 | 30 | ================================================================================ 31 | MSG: std_msgs/Header 32 | # Standard metadata for higher-level stamped data types. 33 | # This is generally used to communicate timestamped data 34 | # in a particular coordinate frame. 35 | # 36 | # sequence ID: consecutively increasing ID 37 | uint32 seq 38 | #Two-integer timestamp that is expressed as: 39 | # * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs') 40 | # * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs') 41 | # time-handling sugar is provided by the client library 42 | time stamp 43 | #Frame this data is associated with 44 | # 0: no frame 45 | # 1: global frame 46 | string frame_id 47 | 48 | ================================================================================ 49 | MSG: dvs_msgs/Event 50 | # A DVS event 51 | uint16 x 52 | uint16 y 53 | time ts 54 | bool polarity 55 | """ 56 | 57 | order = 0 58 | migrated_types = [ 59 | ("Event","Event"),] 60 | 61 | valid = True 62 | 63 | def update(self, old_msg, new_msg): 64 | #No matching field name in old message 65 | new_msg.header = self.get_new_class('std_msgs/Header')() 66 | new_msg.height = 128 #resolution of the DVS 67 | new_msg.width = 128 68 | self.migrate_array(old_msg.events, new_msg.events, "dvs_msgs/Event") 69 | class update_dvs_msgs_Event_77331a9e8b243d7e378ead150e50b8ef(MessageUpdateRule): 70 | old_type = "dvs_msgs/Event" 71 | old_full_text = """ 72 | # A DVS event 73 | uint16 x 74 | uint16 y 75 | uint64 time 76 | bool polarity 77 | """ 78 | 79 | new_type = "dvs_msgs/Event" 80 | new_full_text = """ 81 | # A DVS event 82 | uint16 x 83 | uint16 y 84 | time ts 85 | bool polarity 86 | """ 87 | 88 | order = 0 89 | migrated_types = [] 90 | 91 | valid = True 92 | 93 | def update(self, old_msg, new_msg): 94 | new_msg.x = old_msg.x 95 | new_msg.y = old_msg.y 96 | new_msg.ts.secs = int(old_msg.time/1e6) 97 | t = old_msg.time - long(new_msg.ts.secs)*1e6 98 | new_msg.ts.nsecs = t*1e3 99 | new_msg.polarity = old_msg.polarity 100 | -------------------------------------------------------------------------------- /dvs_msgs/msg/Event.msg: -------------------------------------------------------------------------------- 1 | # A DVS event 2 | uint16 x 3 | uint16 y 4 | time ts 5 | bool polarity 6 | -------------------------------------------------------------------------------- /dvs_msgs/msg/EventArray.msg: -------------------------------------------------------------------------------- 1 | # This message contains an array of events 2 | # (0, 0) is at top-left corner of image 3 | # 4 | 5 | Header header 6 | 7 | uint32 height # image height, that is, number of rows 8 | uint32 width # image width, that is, number of columns 9 | 10 | # an array of events 11 | Event[] events 12 | -------------------------------------------------------------------------------- /dvs_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dvs_msgs 4 | 0.0.0 5 | The dvs_msgs package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | 11 | message_generation 12 | std_msgs 13 | 14 | message_runtime 15 | std_msgs 16 | rosbag 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dvs_renderer/.CMakeLists.txt.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbarranco/dvs_clustering_tracking/da631781858e2c970145621221b11f12b3241d74/dvs_renderer/.CMakeLists.txt.swp -------------------------------------------------------------------------------- /dvs_renderer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(dvs_renderer) 3 | 4 | # search for everything we need to build the package 5 | find_package(catkin REQUIRED COMPONENTS 6 | roscpp 7 | sensor_msgs 8 | dvs_msgs 9 | cv_bridge 10 | image_transport 11 | nodelet 12 | ) 13 | 14 | # since we need eigen and boost search them as well 15 | # find_package makes the ${..._INCLUDE_DIRS} ${..._LIBRARIES} variables we use later 16 | #find_package(OpenCV 2 REQUIRED) 17 | find_package(OpenCV 3 REQUIRED) 18 | 19 | # export the dependencis of this package for who ever depends on us 20 | catkin_package( 21 | INCLUDE_DIRS 22 | include 23 | CATKIN_DEPENDS 24 | roscpp 25 | sensor_msgs 26 | dvs_msgs 27 | cv_bridge 28 | image_transport 29 | nodelet 30 | DEPENDS 31 | OpenCV 32 | ) 33 | 34 | # tell catkin where to find the headers for this project 35 | include_directories( 36 | include 37 | ${catkin_INCLUDE_DIRS} 38 | ${OpenCV_INCLUDE_DIRS} 39 | ) 40 | 41 | set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") 42 | 43 | # make the executable 44 | add_executable(dvs_renderer 45 | src/image_tracking.cpp 46 | src/renderer.cpp 47 | src/renderer_node.cpp 48 | ) 49 | 50 | # make the nodelet into a library 51 | add_library(dvs_renderer_nodelet 52 | src/image_tracking.cpp 53 | src/renderer_nodelet.cpp 54 | src/renderer.cpp 55 | ) 56 | 57 | # to build the executable we depend on other packets, 58 | # they need to be build beforehand, especially the messages 59 | add_dependencies(dvs_renderer 60 | ${catkin_EXPORTED_TARGETS} 61 | ) 62 | 63 | add_dependencies(dvs_renderer_nodelet 64 | ${catkin_EXPORTED_TARGETS} 65 | ) 66 | 67 | # link the executable to the necesarry libs 68 | target_link_libraries(dvs_renderer 69 | ${catkin_LIBRARIES} 70 | ${OpenCV_LIBRARIES} 71 | ) 72 | 73 | target_link_libraries(dvs_renderer_nodelet 74 | ${catkin_LIBRARIES} 75 | ${OpenCV_LIBRARIES} 76 | ) 77 | 78 | # Install the nodelet library 79 | install(TARGETS dvs_renderer_nodelet 80 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 81 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 82 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 83 | ) 84 | 85 | # Install other support files for installation 86 | install(FILES dvs_renderer_nodelet.xml nodelet_stereo.launch nodelet_mono.launch 87 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 88 | ) 89 | -------------------------------------------------------------------------------- /dvs_renderer/dvs_renderer_nodelet.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A nodelet wrapper for the dvs_renderer. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dvs_renderer/include/dvs_renderer/image_tracking.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | namespace dvs_renderer 32 | { 33 | 34 | /** 35 | * @class ImageTracking 36 | * Track frames over 1 sec, then project all events during this time into 37 | * the latest frame & output the accumulated events per pixel. 38 | * This requires the scene to be planar, and for best results, the camera motion 39 | * is perpendicular to the plane's surface normal. 40 | */ 41 | class ImageTracking { 42 | public: 43 | ImageTracking(ros::NodeHandle & nh); 44 | void eventsCallback(const dvs_msgs::EventArray::ConstPtr& msg); 45 | void imageCallback(const sensor_msgs::Image::ConstPtr& msg); 46 | private: 47 | 48 | void render(); 49 | void reset(); 50 | 51 | struct ImgData { 52 | cv::Mat img; 53 | ros::Time t; 54 | std::vector points; 55 | cv::Mat homography; //homography from previous image to this 56 | cv::Mat homography_accumulated; //homography from previous image to the second last 57 | cv::Point2f translation; //mean translation, previous to this 58 | }; 59 | std::vector images_; 60 | std::vector events_; 61 | double start_time_; 62 | cv::Mat edges_; 63 | image_transport::Publisher image_pub_; 64 | image_transport::Publisher image_pub_events_edges_; 65 | }; 66 | 67 | 68 | } // namespace 69 | -------------------------------------------------------------------------------- /dvs_renderer/include/dvs_renderer/renderer.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #ifndef DVS_RENDERER_H_ 17 | #define DVS_RENDERER_H_ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include "image_tracking.h" 32 | 33 | #include 34 | #include 35 | 36 | namespace dvs_renderer 37 | { 38 | 39 | class Renderer { 40 | public: 41 | Renderer(ros::NodeHandle & nh, ros::NodeHandle nh_private); 42 | virtual ~Renderer(); 43 | 44 | private: 45 | ros::NodeHandle nh_; 46 | 47 | void cameraInfoCallback(const sensor_msgs::CameraInfo::ConstPtr& msg); 48 | void eventsCallback(const dvs_msgs::EventArray::ConstPtr& msg); 49 | //void imageCallback(const sensor_msgs::Image::ConstPtr& msg); 50 | 51 | void publishStats(); 52 | 53 | bool got_camera_info_; 54 | cv::Mat camera_matrix_, dist_coeffs_; 55 | 56 | ros::Subscriber event_sub_; 57 | ros::Subscriber camera_info_sub_; 58 | 59 | image_transport::Publisher image_pub_; 60 | image_transport::Publisher undistorted_image_pub_; 61 | 62 | image_transport::Subscriber image_sub_; 63 | cv::Mat last_image_; 64 | bool used_last_image_; 65 | 66 | struct EventStats { 67 | ros::Publisher events_mean_[2]; /**< event stats output */ 68 | int events_counter_[2]; /**< event counters for on/off events */ 69 | double events_mean_lasttime_; 70 | double dt; 71 | }; 72 | EventStats event_stats_[2]; /**< event statistics for 1 and 5 sec */ 73 | 74 | enum DisplayMethod 75 | { 76 | GRAYSCALE, RED_BLUE 77 | } display_method_; 78 | 79 | //ImageTracking image_tracking_; 80 | }; 81 | 82 | } // namespace 83 | 84 | #endif // DVS_RENDERER_H_ 85 | -------------------------------------------------------------------------------- /dvs_renderer/include/dvs_renderer/renderer_nodelet.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #ifndef DVS_RENDERER_NODELET_H_ 17 | #define DVS_RENDERER_NODELET_H_ 18 | 19 | #include 20 | 21 | #include "dvs_renderer/renderer.h" 22 | 23 | namespace dvs_renderer { 24 | 25 | class DvsRendererNodelet : public nodelet::Nodelet { 26 | public: 27 | virtual void onInit(); 28 | 29 | private: 30 | dvs_renderer::Renderer* renderer; 31 | }; 32 | 33 | } 34 | 35 | #endif // DVS_RENDERER_NODELET_H_ 36 | -------------------------------------------------------------------------------- /dvs_renderer/launch/bias_tuning.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /dvs_renderer/launch/davis_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dvs_renderer/launch/dvs_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dvs_renderer/launch/mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dvs_renderer/launch/nodelet_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /dvs_renderer/launch/nodelet_stereo.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /dvs_renderer/launch/renderer_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dvs_renderer/launch/renderer_stereo.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dvs_renderer/launch/rgbd-dvs-rig.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /dvs_renderer/launch/stereo.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /dvs_renderer/launch/viewer_mono.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dvs_renderer/launch/viewer_stereo.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dvs_renderer/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dvs_renderer 4 | 0.0.0 5 | The dvs_renderer package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | 11 | roscpp 12 | sensor_msgs 13 | dvs_msgs 14 | cv_bridge 15 | image_transport 16 | nodelet 17 | 18 | roscpp 19 | sensor_msgs 20 | dvs_msgs 21 | cv_bridge 22 | image_transport 23 | nodelet 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /dvs_renderer/src/renderer_node.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include "dvs_renderer/renderer.h" 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | ros::init(argc, argv, "dvs_renderer"); 21 | 22 | ros::NodeHandle nh; 23 | ros::NodeHandle nh_private("~"); 24 | 25 | dvs_renderer::Renderer renderer(nh, nh_private); 26 | 27 | ros::spin(); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /dvs_renderer/src/renderer_nodelet.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include 17 | 18 | #include "dvs_renderer/renderer_nodelet.h" 19 | 20 | namespace dvs_renderer 21 | { 22 | 23 | void DvsRendererNodelet::onInit() 24 | { 25 | renderer = new dvs_renderer::Renderer(getNodeHandle(), getPrivateNodeHandle()); 26 | NODELET_INFO_STREAM("Initialized " << getName() << " nodelet."); 27 | } 28 | 29 | PLUGINLIB_DECLARE_CLASS(dvs_renderer, DvsRendererNodelet, dvs_renderer::DvsRendererNodelet, nodelet::Nodelet); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /dvs_ros_driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(dvs_ros_driver) 3 | 4 | # search for everything we need to build the package 5 | find_package(catkin REQUIRED COMPONENTS 6 | roscpp 7 | libcaer_catkin 8 | dvs_msgs 9 | std_msgs 10 | dynamic_reconfigure 11 | camera_info_manager 12 | nodelet 13 | ) 14 | 15 | generate_dynamic_reconfigure_options( 16 | cfg/DVS_ROS_Driver.cfg 17 | ) 18 | 19 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") 20 | 21 | # since we need eigen and boost search them as well 22 | # find_package makes the ${..._INCLUDE_DIRS} ${..._LIBRARIES} variables we use later 23 | find_package(Boost REQUIRED COMPONENTS system thread) 24 | 25 | # export the dependencis of this package for who ever depends on us 26 | catkin_package( 27 | INCLUDE_DIRS 28 | include 29 | CATKIN_DEPENDS 30 | roscpp 31 | libcaer_catkin 32 | dvs_msgs 33 | std_msgs 34 | dynamic_reconfigure 35 | camera_info_manager 36 | nodelet 37 | DEPENDS 38 | boost 39 | ) 40 | 41 | # tell catkin where to find the headers for this project 42 | include_directories( 43 | include 44 | ${catkin_INCLUDE_DIRS} 45 | ${Boost_INCLUDE_DIRS} 46 | ) 47 | 48 | # make the executable 49 | add_executable(dvs_ros_driver 50 | src/driver_node.cpp 51 | src/driver.cpp 52 | ) 53 | 54 | # make the nodelet into a library 55 | add_library(dvs_ros_driver_nodelet 56 | src/driver_nodelet.cpp 57 | src/driver.cpp 58 | ) 59 | 60 | # to build the executable we depend on other packets, 61 | # they need to be build beforehand, especially the messages 62 | add_dependencies(dvs_ros_driver 63 | ${catkin_EXPORTED_TARGETS} 64 | ${PROJECT_NAME}_gencfg 65 | ) 66 | 67 | add_dependencies(dvs_ros_driver_nodelet 68 | ${catkin_EXPORTED_TARGETS} 69 | ${PROJECT_NAME}_gencfg 70 | ) 71 | 72 | # link the executable to the necesarry libs 73 | target_link_libraries(dvs_ros_driver 74 | ${catkin_LIBRARIES} 75 | ${Boost_LIBRARIES} 76 | ${CATKIN_DEVEL_PREFIX}/lib/libcaer${CMAKE_SHARED_LIBRARY_SUFFIX} 77 | ) 78 | 79 | # link the executable to the necesarry libs 80 | target_link_libraries(dvs_ros_driver_nodelet 81 | ${catkin_LIBRARIES} 82 | ${Boost_LIBRARIES} 83 | ${CATKIN_DEVEL_PREFIX}/lib/libcaer${CMAKE_SHARED_LIBRARY_SUFFIX} 84 | ) 85 | 86 | # Install the nodelet library 87 | install(TARGETS dvs_ros_driver_nodelet 88 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 89 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 90 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 91 | ) 92 | 93 | # Install other support files for installation 94 | install(FILES dvs_ros_driver_nodelet.xml 95 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 96 | ) 97 | -------------------------------------------------------------------------------- /dvs_ros_driver/cfg/DVS_ROS_Driver.cfg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | PACKAGE = "dvs_ros_driver" 3 | 4 | from dynamic_reconfigure.parameter_generator_catkin import * 5 | 6 | gen = ParameterGenerator() 7 | 8 | gen.add("streaming_rate", int_t, 0, "integration time", 30, 1, 10000) 9 | 10 | gen.add("cas", int_t, 0, "cas (Photoreceptor cascode)", 1992, 0, 16777215) 11 | gen.add("injGnd", int_t, 0, "injGnd (Differentiator switch level, higher to turn on more)", 1108364, 0, 16777215) 12 | gen.add("reqPd", int_t, 0, "reqPd (AER request pulldown)", 16777215, 0, 16777215) 13 | gen.add("puX", int_t, 0, "puX (2nd dimension AER static pullup)", 8159221, 0, 16777215) 14 | gen.add("diffOff", int_t, 0, "diffOff (OFF threshold, lower to raise threshold)", 132, 0, 16777215) 15 | gen.add("req", int_t, 0, "req (OFF request inverter bias)", 309590, 0, 16777215) 16 | gen.add("refr", int_t, 0, "refr (Refractory period)", 969, 0, 16777215) 17 | gen.add("puY", int_t, 0, "puY (1st dimension AER static pullup)", 16777215, 0, 16777215) 18 | gen.add("diffOn", int_t, 0, "diffOn (ON threshold - higher to raise threshold)", 209996, 0, 16777215) 19 | gen.add("diff", int_t, 0, "diff (Differentiator)", 13125, 0, 16777215) 20 | gen.add("foll", int_t, 0, "foll (Src follower buffer between photoreceptor and differentiator)", 271, 0, 16777215) 21 | gen.add("Pr", int_t, 0, "Pr (Photoreceptor)", 217, 0, 16777215) 22 | 23 | exit(gen.generate(PACKAGE, "dvs_ros_driver", "DVS_ROS_Driver")) 24 | -------------------------------------------------------------------------------- /dvs_ros_driver/config/fast.yaml: -------------------------------------------------------------------------------- 1 | cas: 1992 2 | injGnd: 1108364 3 | reqPd: 16777215 4 | puX: 8159221 5 | diffOff: 132 6 | req: 309590 7 | refr: 969 8 | puY: 16777215 9 | diffOn: 209996 10 | diff: 13125 11 | foll: 271 12 | Pr: 217 13 | -------------------------------------------------------------------------------- /dvs_ros_driver/config/slow.yaml: -------------------------------------------------------------------------------- 1 | cas: 54 2 | injGnd: 1108364 3 | reqPd: 16777215 4 | puX: 8159221 5 | diffOff: 132 6 | req: 159147 7 | refr: 6 8 | puY: 16777215 9 | diffOn: 482443 10 | diff: 30153 11 | foll: 51 12 | Pr: 3 13 | -------------------------------------------------------------------------------- /dvs_ros_driver/config/standard.yaml: -------------------------------------------------------------------------------- 1 | cas: 54 2 | injGnd: 1108364 3 | reqPd: 16777215 4 | puX: 8159221 5 | diffOff: 132 6 | req: 159147 7 | refr: 6 8 | puY: 16777215 9 | diffOn: 262144 10 | diff: 30153 11 | foll: 51 12 | Pr: 3 13 | -------------------------------------------------------------------------------- /dvs_ros_driver/config/stereo.yaml: -------------------------------------------------------------------------------- 1 | cas: 54 2 | injGnd: 1108364 3 | reqPd: 16777215 4 | puX: 8159221 5 | diffOff: 1783 6 | req: 159147 7 | refr: 6 8 | puY: 16777215 9 | diffOn: 482443 10 | diff: 30153 11 | foll: 51 12 | Pr: 3 13 | -------------------------------------------------------------------------------- /dvs_ros_driver/dvs_ros_driver_nodelet.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A nodelet wrapper for the dvs_ros_driver. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dvs_ros_driver/include/dvs_ros_driver/driver.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | // boost 22 | #include 23 | #include 24 | #include 25 | 26 | // messages 27 | #include 28 | #include 29 | #include 30 | 31 | // DVS driver 32 | #include 33 | #include 34 | 35 | // dynamic reconfigure 36 | #include 37 | #include 38 | 39 | // camera info manager 40 | #include 41 | #include 42 | 43 | namespace dvs_ros_driver { 44 | 45 | class DvsRosDriver { 46 | public: 47 | DvsRosDriver(ros::NodeHandle & nh, ros::NodeHandle nh_private); 48 | ~DvsRosDriver(); 49 | 50 | private: 51 | void changeDvsParameters(); 52 | void callback(dvs_ros_driver::DVS_ROS_DriverConfig &config, uint32_t level); 53 | void readout(); 54 | void resetTimestamps(); 55 | 56 | ros::NodeHandle nh_; 57 | ros::Publisher event_array_pub_; 58 | ros::Publisher camera_info_pub_; 59 | caerDeviceHandle dvs128_handle; 60 | 61 | volatile bool running_; 62 | 63 | boost::shared_ptr > server_; 64 | dynamic_reconfigure::Server::CallbackType dynamic_reconfigure_callback_; 65 | 66 | ros::Subscriber reset_sub_; 67 | void resetTimestampsCallback(std_msgs::Empty msg); 68 | 69 | boost::shared_ptr parameter_thread_; 70 | boost::shared_ptr readout_thread_; 71 | 72 | boost::posix_time::time_duration delta_; 73 | 74 | dvs_ros_driver::DVS_ROS_DriverConfig current_config_; 75 | camera_info_manager::CameraInfoManager* camera_info_manager_; 76 | 77 | struct caer_dvs128_info dvs128_info_; 78 | std::string device_id_; 79 | 80 | ros::Time reset_time_; 81 | 82 | ros::Timer timestamp_reset_timer_; 83 | void resetTimerCallback(const ros::TimerEvent& te); 84 | 85 | bool parameter_update_required_; 86 | 87 | }; 88 | 89 | } // namespace 90 | -------------------------------------------------------------------------------- /dvs_ros_driver/include/dvs_ros_driver/driver_nodelet.h: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | #include "dvs_ros_driver/driver.h" 21 | 22 | namespace dvs_ros_driver { 23 | 24 | class DvsRosDriverNodelet : public nodelet::Nodelet { 25 | public: 26 | virtual void onInit(); 27 | 28 | private: 29 | dvs_ros_driver::DvsRosDriver* driver_; 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /dvs_ros_driver/launch/stereo.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dvs_ros_driver/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dvs_ros_driver 4 | 0.0.0 5 | The dvs_ros_driver package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | 11 | roscpp 12 | libcaer_catkin 13 | dvs_msgs 14 | std_msgs 15 | dynamic_reconfigure 16 | camera_info_manager 17 | nodelet 18 | 19 | roscpp 20 | libcaer_catkin 21 | dvs_msgs 22 | std_msgs 23 | dynamic_reconfigure 24 | camera_info_manager 25 | nodelet 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /dvs_ros_driver/src/driver_node.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include 17 | #include "dvs_ros_driver/driver.h" 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | ros::init(argc, argv, "dvs_ros_driver"); 22 | 23 | ros::NodeHandle nh; 24 | ros::NodeHandle nh_private("~"); 25 | 26 | dvs_ros_driver::DvsRosDriver* driver = new dvs_ros_driver::DvsRosDriver(nh, nh_private); 27 | 28 | ros::spin(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /dvs_ros_driver/src/driver_nodelet.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DVS-ROS - the RPG DVS ROS Package 2 | // 3 | // DVS-ROS is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // DVS-ROS is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with DVS-ROS. If not, see . 15 | 16 | #include 17 | 18 | #include "dvs_ros_driver/driver_nodelet.h" 19 | 20 | namespace dvs_ros_driver 21 | { 22 | 23 | void DvsRosDriverNodelet::onInit() 24 | { 25 | driver_ = new dvs_ros_driver::DvsRosDriver(getNodeHandle(), getPrivateNodeHandle()); 26 | 27 | NODELET_INFO_STREAM("Initialized " << getName() << " nodelet."); 28 | } 29 | 30 | PLUGINLIB_DECLARE_CLASS(dvs_ros_driver, DvsRosDriverNodelet, dvs_ros_driver::DvsRosDriverNodelet, nodelet::Nodelet); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /libcaer/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /libcaer/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | CMakeCache.txt 3 | CMakeFiles/ 4 | Makefile 5 | cmake_install.cmake 6 | /install_manifest.txt 7 | /libcaer.pc 8 | *~ 9 | *.swp 10 | *.swo 11 | *.sh 12 | -------------------------------------------------------------------------------- /libcaer/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | libcaer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 15 | full,incremental, 16 | 17 | 18 | 19 | 20 | 21 | org.eclipse.cdt.core.cnature 22 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 23 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 24 | org.eclipse.cdt.codan.core.codanNature 25 | 26 | 27 | -------------------------------------------------------------------------------- /libcaer/.settings/language.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /libcaer/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015, Luca Longinotti, iniLabs Ltd. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /libcaer/ChangeLog: -------------------------------------------------------------------------------- 1 | Release 1.0.3 - 28.03.2016 2 | INCOMPATIBLE CHANGES 3 | - davis_fx2.c: removed specific FX2 code, now uses same backend as FX3 4 | for sending all configuration values, due to new firmware version 3 5 | for FX2 DAVIS small-board cameras. A firmware update is required, 6 | please follow the instructions at http://inilabs.com/support/reflashing/. 7 | 8 | NEW FEATURES 9 | - frame.h: add function caerFrameEventGetPixelArrayCGFormat() to 10 | Frame Event, allows to get a copy of the pixels array in the 11 | standard computer graphics format (pixel (0, 0) in upper left 12 | corner) efficently. 13 | - davis.h: add DAVIS_CONFIG_APS_ADC_TEST_MODE parameter to APS module. 14 | 15 | Release 1.0.2 - 08.01.2016 16 | IMCOMPATIBLE CHANGES 17 | - frame.h: rename channel number to color channels and add color 18 | filter information, to better specify the information needed 19 | to reconstruct color frames. The 'enum caer_frame_event_color_channels' 20 | and 'enum caer_frame_event_color_filter' hold the possible values. 21 | This change is backwards-compatible with older frame format! 22 | - davis.h, dvs128.h: changed info data structure's integers to be 23 | signed for better cross-language compatibility. Also 'deviceID' 24 | can now be compared directly with 'sourceID' from event packets. 25 | - davis.h: changed type of 'apsColorFilter' in info data structure 26 | to take advantage of new 'enum caer_frame_event_color_filter'. 27 | 28 | NEW FEATURES 29 | - common.h: add generic functions for event packet copying, with 30 | support for packet size reductions (copy only valid). 31 | - libcaer.h: add generic clear, get and set functions for bitfields, 32 | and use them in all the event functions to avoid errors. 33 | - config.h: add device configuration event type, for tracking 34 | of device configuration changes in the event stream. 35 | - log.c: add timezone information to log message time information. 36 | - dvs128_simple.cpp, davis_simple.cpp: add C++11 example variants. 37 | - Enable more Clang compiler warnings. 38 | 39 | BUG FIXES 40 | - davis_common.c: only update the ROI size information if ROI 41 | updates actually came in from the device. 42 | - Fix and improve documentation, especially for the frame event. 43 | - Fix off-by-one in event's GetEvent() function's warning log message. 44 | - device.c: mark global function pointer arrays static. 45 | - common.h, frame.h: fix compilation of inline functions in 46 | strict C++11 mode. 47 | 48 | 49 | Release 1.0.1 - 06.11.2015 50 | INCOMPATIBLE CHANGES 51 | - Requires firmware version 2 and logic revision 7449. 52 | - usb.h: improved caerDeviceDataStart() API to also allow for 53 | notification of data acquisition shutdown, to be able to react 54 | to abnormal shutdown cases, like when a device is unplugged. 55 | - frame.h: changed in-memory format for easier handling and compatibility 56 | with the other event formats (all-in-one memory block). 57 | - davis.h: rename DAVIS240 APSOVERFLOWLEVEL to APSOVERFLOWLEVELBN. 58 | 59 | NEW FEATURES 60 | - Headers are C++ compatible and stand-alone now. 61 | - MacOS X support. 62 | - Added pkg-config file for library. 63 | - Full API documentation (see docs/ for PDF). 64 | - Various cmake/build improvements. Support out-of-tree builds. 65 | - Add iterator macros for EventPackets. 66 | - frame.h: added ROI region ID tracking, as well as ROI position. 67 | Added caerFrameEventGetExposureLength() and caerFrameEventGetTimestamp(), 68 | which is defined as the median of the exposure times. 69 | Added caerFrameEventPacketGetPixelsSize() and caerFrameEventPacketGetPixelsMaxIndex() 70 | for EventPacket-level size information. 71 | Added caerFrameEventGetPixelsSize() and caerFrameEventGetPixelsMaxIndex() 72 | for Event-level size information. 73 | - log.h: added caerLogFileDescriptorsSet() to allow logging to 74 | up to two different file descriptors (defaults to STDERR only). 75 | - davis.h: added chipID check macros. 76 | - davis.h: added DAVIS_CONFIG_APS_SNAPSHOT to take one frame snapshots. 77 | - dvs128.h: added DVS128_CONFIG_DVS_TS_MASTER to select timestamp 78 | master or slave behavior (timestamp synchronization). 79 | - davis_common.c: added support for outputting only reset read or 80 | signal read frames, for debugging purposes. 81 | - c11threads_posix.h: C11-compatible thread abstraction, for 82 | both Linux and MacOS X, based on POSIX Threads. 83 | 84 | BUG FIXES 85 | - Relaxed atomic operations memory constraints for better 86 | performance on weakly-ordered architectures (like ARM). 87 | - log.c: call tzset() before localtime_r(), as per standard. 88 | - davis_common.c: improved Region of Interest support (APS). 89 | - davis_fx2.c: keep GlobalShutter flag correctly in-sync. 90 | - davis_fx3.c: fixed support for new FX3 devices. 91 | - packetContainer.h: handle container being NULL by returning NULL. 92 | 93 | 94 | Release 1.0.0 - 02.10.2015 95 | - Initial release. 96 | -------------------------------------------------------------------------------- /libcaer/README: -------------------------------------------------------------------------------- 1 | libcaer 2 | ==== 3 | 4 | Minimal C library to access, configure and get data out of AER sensors, 5 | such as the Dynamic Vision Sensor (DVS) or DAVIS cameras. 6 | 7 | REQUIREMENTS: 8 | 9 | cmake >= 2.6 10 | gcc >= 4.9 or clang >= 3.6 11 | libusb >= 1.0.17 12 | 13 | Please make sure that you have the various development packages installed 14 | for the above dependencies. They are usually called PKG-dev or PKG-devel. 15 | 16 | INSTALLATION: 17 | 18 | 1) configure: 19 | 20 | $ cmake -DCMAKE_INSTALL_PREFIX=/usr . 21 | 22 | 2) build: 23 | 24 | $ make 25 | 26 | 3) install: 27 | 28 | $ make install 29 | 30 | DOCUMENTATION: 31 | 32 | The API documentation for a release can be found at docs/libcaer_api_manual.pdf. 33 | Also check the examples/ directory and the iniLabs Support website. 34 | 35 | For the development tree, you can generate the documentation using: 36 | 37 | $ make doc - to generate docs/latex/ and docs/html/ documentation files. 38 | $ make pdf - to generate a PDF from the LaTeX sources at docs/latex/refman.pdf. 39 | 40 | USAGE: 41 | 42 | See examples/ directory. Usual usage is (simplified): 43 | 44 | h = caerDeviceOpen(TYPE); 45 | caerDeviceSendDefaultConfig(h); 46 | caerDeviceDataStart(h); 47 | 48 | loop: 49 | c = caerDeviceDataGet(h); 50 | work with c (container) and its event packets 51 | 52 | caerDeviceDataStop(h); 53 | caerDeviceClose(&h); 54 | 55 | All configuration parameters and event types are specified in the 56 | public headers and documented there. 57 | -------------------------------------------------------------------------------- /libcaer/docs/.gitignore: -------------------------------------------------------------------------------- 1 | /libcaer_api.doxy 2 | /html/ 3 | /latex/ 4 | -------------------------------------------------------------------------------- /libcaer/docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (NOT DOXYGEN_FOUND) 2 | # Only support call from main cmake. 3 | RETURN() 4 | ENDIF() 5 | 6 | # Doxygen directories and configuration. HTML and Latex are generated. 7 | SET(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/docs/) 8 | SET(DOXYGEN_CONFIG ${DOXYGEN_OUTPUT_DIR}/libcaer_api.doxy) 9 | SET(DOXYGEN_LATEX_OUTPUT_DIR ${DOXYGEN_OUTPUT_DIR}/latex/) 10 | SET(DOXYGEN_LATEX_OUTPUT ${DOXYGEN_LATEX_OUTPUT_DIR}/refman.tex) 11 | SET(DOXYGEN_HTML_OUTPUT_DIR ${DOXYGEN_OUTPUT_DIR}/html/) 12 | SET(DOXYGEN_HTML_OUTPUT ${DOXYGEN_HTML_OUTPUT_DIR}/index.html) 13 | 14 | CONFIGURE_FILE(libcaer_api.doxy.in libcaer_api.doxy @ONLY) 15 | 16 | ADD_CUSTOM_COMMAND( 17 | OUTPUT ${DOXYGEN_LATEX_OUTPUT} ${DOXYGEN_HTML_OUTPUT} 18 | COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_CONFIG} 19 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/include/ 20 | DEPENDS ${DOXYGEN_CONFIG}) 21 | 22 | # Generate documentation with 'make doc'. 23 | ADD_CUSTOM_TARGET(doc DEPENDS ${DOXYGEN_LATEX_OUTPUT} ${DOXYGEN_HTML_OUTPUT}) 24 | 25 | # Automatically generate PDF from Latex. 26 | FIND_PACKAGE(LATEX) 27 | 28 | IF (NOT LATEX_COMPILER) 29 | MESSAGE(STATUS "latex command LATEX_COMPILER not found, but usually required by Doxygen.") 30 | ENDIF() 31 | 32 | IF (NOT MAKEINDEX_COMPILER) 33 | MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found, but usually required by Doxygen.") 34 | ENDIF() 35 | 36 | IF (NOT DVIPS_CONVERTER) 37 | MESSAGE(STATUS "dvips command DVIPS_CONVERTER not found, but usually required by Doxygen.") 38 | ENDIF() 39 | 40 | # Generate PDF documentation. 41 | ADD_CUSTOM_COMMAND( 42 | OUTPUT ${DOXYGEN_LATEX_OUTPUT_DIR}/refman.pdf 43 | COMMAND make 44 | WORKING_DIRECTORY ${DOXYGEN_LATEX_OUTPUT_DIR} 45 | DEPENDS ${DOXYGEN_LATEX_OUTPUT}) 46 | 47 | # Generate PDF from Latex with 'make pdf'. 48 | ADD_CUSTOM_TARGET(pdf DEPENDS ${DOXYGEN_LATEX_OUTPUT_DIR}/refman.pdf) 49 | -------------------------------------------------------------------------------- /libcaer/docs/libcaer_api_manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbarranco/dvs_clustering_tracking/da631781858e2c970145621221b11f12b3241d74/libcaer/docs/libcaer_api_manual.pdf -------------------------------------------------------------------------------- /libcaer/examples/.gitignore: -------------------------------------------------------------------------------- 1 | /dvs128_simple 2 | /davis_simple 3 | /*.exe -------------------------------------------------------------------------------- /libcaer/examples/README: -------------------------------------------------------------------------------- 1 | DVS128 example: 2 | C: gcc -std=c11 -pedantic -Wall -Wextra -O2 -o dvs128_simple dvs128_simple.c -D_POSIX_C_SOURCE=1 -D_BSD_SOURCE=1 -lcaer 3 | C++: g++ -std=c++11 -pedantic -Wall -Wextra -O2 -o dvs128_simple dvs128_simple.cpp -D_POSIX_C_SOURCE=1 -D_BSD_SOURCE=1 -lcaer 4 | 5 | DAVIS example: 6 | C: gcc -std=c11 -pedantic -Wall -Wextra -O2 -o davis_simple davis_simple.c -D_POSIX_C_SOURCE=1 -D_BSD_SOURCE=1 -lcaer 7 | C++: g++ -std=c++11 -pedantic -Wall -Wextra -O2 -o davis_simple davis_simple.cpp -D_POSIX_C_SOURCE=1 -D_BSD_SOURCE=1 -lcaer 8 | -------------------------------------------------------------------------------- /libcaer/examples/davis_simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static atomic_bool globalShutdown = ATOMIC_VAR_INIT(false); 8 | 9 | static void globalShutdownSignalHandler(int signal) { 10 | // Simply set the running flag to false on SIGTERM and SIGINT (CTRL+C) for global shutdown. 11 | if (signal == SIGTERM || signal == SIGINT) { 12 | atomic_store(&globalShutdown, true); 13 | } 14 | } 15 | 16 | int main(void) { 17 | // Install signal handler for global shutdown. 18 | #ifdef _WIN32 19 | signal(SIGTERM, globalShutdownSignalHandler); 20 | signal(SIGINT, globalShutdownSignalHandler); 21 | #else 22 | struct sigaction shutdownAction; 23 | 24 | shutdownAction.sa_handler = &globalShutdownSignalHandler; 25 | shutdownAction.sa_flags = 0; 26 | sigemptyset(&shutdownAction.sa_mask); 27 | sigaddset(&shutdownAction.sa_mask, SIGTERM); 28 | sigaddset(&shutdownAction.sa_mask, SIGINT); 29 | 30 | if (sigaction(SIGTERM, &shutdownAction, NULL) == -1) { 31 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); 32 | return (EXIT_FAILURE); 33 | } 34 | 35 | if (sigaction(SIGINT, &shutdownAction, NULL) == -1) { 36 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); 37 | return (EXIT_FAILURE); 38 | } 39 | #endif 40 | 41 | // Open a DAVIS, give it a device ID of 1, and don't care about USB bus or SN restrictions. 42 | caerDeviceHandle davis_handle = caerDeviceOpen(1, CAER_DEVICE_DAVIS_FX2, 0, 0, NULL); 43 | if (davis_handle == NULL) { 44 | return (EXIT_FAILURE); 45 | } 46 | 47 | // Let's take a look at the information we have on the device. 48 | struct caer_davis_info davis_info = caerDavisInfoGet(davis_handle); 49 | 50 | printf("%s --- ID: %d, Master: %d, DVS X: %d, DVS Y: %d, Logic: %d.\n", davis_info.deviceString, 51 | davis_info.deviceID, davis_info.deviceIsMaster, davis_info.dvsSizeX, davis_info.dvsSizeY, 52 | davis_info.logicVersion); 53 | 54 | // Send the default configuration before using the device. 55 | // No configuration is sent automatically! 56 | caerDeviceSendDefaultConfig(davis_handle); 57 | 58 | // Tweak some biases, to increase bandwidth in this case. 59 | struct caer_bias_coarsefine coarseFineBias; 60 | 61 | coarseFineBias.coarseValue = 2; 62 | coarseFineBias.fineValue = 116; 63 | coarseFineBias.enabled = true; 64 | coarseFineBias.sexN = false; 65 | coarseFineBias.typeNormal = true; 66 | coarseFineBias.currentLevelNormal = true; 67 | caerDeviceConfigSet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRBP, 68 | caerBiasCoarseFineGenerate(coarseFineBias)); 69 | 70 | coarseFineBias.coarseValue = 1; 71 | coarseFineBias.fineValue = 33; 72 | coarseFineBias.enabled = true; 73 | coarseFineBias.sexN = false; 74 | coarseFineBias.typeNormal = true; 75 | coarseFineBias.currentLevelNormal = true; 76 | caerDeviceConfigSet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRSFBP, 77 | caerBiasCoarseFineGenerate(coarseFineBias)); 78 | 79 | // Let's verify they really changed! 80 | uint32_t prBias, prsfBias; 81 | caerDeviceConfigGet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRBP, &prBias); 82 | caerDeviceConfigGet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRSFBP, &prsfBias); 83 | 84 | printf("New bias values --- PR-coarse: %d, PR-fine: %d, PRSF-coarse: %d, PRSF-fine: %d.\n", 85 | caerBiasCoarseFineParse(prBias).coarseValue, caerBiasCoarseFineParse(prBias).fineValue, 86 | caerBiasCoarseFineParse(prsfBias).coarseValue, caerBiasCoarseFineParse(prsfBias).fineValue); 87 | 88 | // Now let's get start getting some data from the device. We just loop, no notification needed. 89 | caerDeviceDataStart(davis_handle, NULL, NULL, NULL, NULL, NULL); 90 | 91 | // Let's turn on blocking data-get mode to avoid wasting resources. 92 | caerDeviceConfigSet(davis_handle, CAER_HOST_CONFIG_DATAEXCHANGE, CAER_HOST_CONFIG_DATAEXCHANGE_BLOCKING, true); 93 | 94 | while (!atomic_load_explicit(&globalShutdown, memory_order_relaxed)) { 95 | caerEventPacketContainer packetContainer = caerDeviceDataGet(davis_handle); 96 | if (packetContainer == NULL) { 97 | continue; // Skip if nothing there. 98 | } 99 | 100 | int32_t packetNum = caerEventPacketContainerGetEventPacketsNumber(packetContainer); 101 | 102 | printf("\nGot event container with %d packets (allocated).\n", packetNum); 103 | 104 | for (int32_t i = 0; i < packetNum; i++) { 105 | caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(packetContainer, i); 106 | if (packetHeader == NULL) { 107 | printf("Packet %d is empty (not present).\n", i); 108 | continue; // Skip if nothing there. 109 | } 110 | 111 | printf("Packet %d of type %d -> size is %d.\n", i, caerEventPacketHeaderGetEventType(packetHeader), 112 | caerEventPacketHeaderGetEventNumber(packetHeader)); 113 | 114 | // Packet 0 is always the special events packet for DVS128, while packet is the polarity events packet. 115 | if (i == POLARITY_EVENT) { 116 | caerPolarityEventPacket polarity = (caerPolarityEventPacket) packetHeader; 117 | 118 | // Get full timestamp and addresses of first event. 119 | caerPolarityEvent firstEvent = caerPolarityEventPacketGetEvent(polarity, 0); 120 | 121 | int32_t ts = caerPolarityEventGetTimestamp(firstEvent); 122 | uint16_t x = caerPolarityEventGetX(firstEvent); 123 | uint16_t y = caerPolarityEventGetY(firstEvent); 124 | bool pol = caerPolarityEventGetPolarity(firstEvent); 125 | 126 | printf("First polarity event - ts: %d, x: %d, y: %d, pol: %d.\n", ts, x, y, pol); 127 | } 128 | } 129 | 130 | caerEventPacketContainerFree(packetContainer); 131 | } 132 | 133 | caerDeviceDataStop(davis_handle); 134 | 135 | caerDeviceClose(&davis_handle); 136 | 137 | printf("Shutdown successful.\n"); 138 | 139 | return (EXIT_SUCCESS); 140 | } 141 | -------------------------------------------------------------------------------- /libcaer/examples/davis_simple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | static atomic_bool globalShutdown(false); 10 | 11 | static void globalShutdownSignalHandler(int signal) { 12 | // Simply set the running flag to false on SIGTERM and SIGINT (CTRL+C) for global shutdown. 13 | if (signal == SIGTERM || signal == SIGINT) { 14 | globalShutdown.store(true); 15 | } 16 | } 17 | 18 | int main(void) { 19 | #ifdef _WIN32 20 | signal(SIGTERM, globalShutdownSignalHandler); 21 | signal(SIGINT, globalShutdownSignalHandler); 22 | #else 23 | // Install signal handler for global shutdown. 24 | struct sigaction shutdownAction; 25 | 26 | shutdownAction.sa_handler = &globalShutdownSignalHandler; 27 | shutdownAction.sa_flags = 0; 28 | sigemptyset(&shutdownAction.sa_mask); 29 | sigaddset(&shutdownAction.sa_mask, SIGTERM); 30 | sigaddset(&shutdownAction.sa_mask, SIGINT); 31 | 32 | if (sigaction(SIGTERM, &shutdownAction, NULL) == -1) { 33 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); 34 | return (EXIT_FAILURE); 35 | } 36 | 37 | if (sigaction(SIGINT, &shutdownAction, NULL) == -1) { 38 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); 39 | return (EXIT_FAILURE); 40 | } 41 | #endif 42 | 43 | // Open a DAVIS, give it a device ID of 1, and don't care about USB bus or SN restrictions. 44 | caerDeviceHandle davis_handle = caerDeviceOpen(1, CAER_DEVICE_DAVIS_FX2, 0, 0, NULL); 45 | if (davis_handle == NULL) { 46 | return (EXIT_FAILURE); 47 | } 48 | 49 | // Let's take a look at the information we have on the device. 50 | struct caer_davis_info davis_info = caerDavisInfoGet(davis_handle); 51 | 52 | printf("%s --- ID: %d, Master: %d, DVS X: %d, DVS Y: %d, Logic: %d.\n", davis_info.deviceString, 53 | davis_info.deviceID, davis_info.deviceIsMaster, davis_info.dvsSizeX, davis_info.dvsSizeY, 54 | davis_info.logicVersion); 55 | 56 | // Send the default configuration before using the device. 57 | // No configuration is sent automatically! 58 | caerDeviceSendDefaultConfig(davis_handle); 59 | 60 | // Tweak some biases, to increase bandwidth in this case. 61 | struct caer_bias_coarsefine coarseFineBias; 62 | 63 | coarseFineBias.coarseValue = 2; 64 | coarseFineBias.fineValue = 116; 65 | coarseFineBias.enabled = true; 66 | coarseFineBias.sexN = false; 67 | coarseFineBias.typeNormal = true; 68 | coarseFineBias.currentLevelNormal = true; 69 | caerDeviceConfigSet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRBP, 70 | caerBiasCoarseFineGenerate(coarseFineBias)); 71 | 72 | coarseFineBias.coarseValue = 1; 73 | coarseFineBias.fineValue = 33; 74 | coarseFineBias.enabled = true; 75 | coarseFineBias.sexN = false; 76 | coarseFineBias.typeNormal = true; 77 | coarseFineBias.currentLevelNormal = true; 78 | caerDeviceConfigSet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRSFBP, 79 | caerBiasCoarseFineGenerate(coarseFineBias)); 80 | 81 | // Let's verify they really changed! 82 | uint32_t prBias, prsfBias; 83 | caerDeviceConfigGet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRBP, &prBias); 84 | caerDeviceConfigGet(davis_handle, DAVIS_CONFIG_BIAS, DAVIS240_CONFIG_BIAS_PRSFBP, &prsfBias); 85 | 86 | printf("New bias values --- PR-coarse: %d, PR-fine: %d, PRSF-coarse: %d, PRSF-fine: %d.\n", 87 | caerBiasCoarseFineParse(prBias).coarseValue, caerBiasCoarseFineParse(prBias).fineValue, 88 | caerBiasCoarseFineParse(prsfBias).coarseValue, caerBiasCoarseFineParse(prsfBias).fineValue); 89 | 90 | // Now let's get start getting some data from the device. We just loop, no notification needed. 91 | caerDeviceDataStart(davis_handle, NULL, NULL, NULL, NULL, NULL); 92 | 93 | // Let's turn on blocking data-get mode to avoid wasting resources. 94 | caerDeviceConfigSet(davis_handle, CAER_HOST_CONFIG_DATAEXCHANGE, CAER_HOST_CONFIG_DATAEXCHANGE_BLOCKING, true); 95 | 96 | while (!globalShutdown.load(memory_order_relaxed)) { 97 | caerEventPacketContainer packetContainer = caerDeviceDataGet(davis_handle); 98 | if (packetContainer == NULL) { 99 | continue; // Skip if nothing there. 100 | } 101 | 102 | int32_t packetNum = caerEventPacketContainerGetEventPacketsNumber(packetContainer); 103 | 104 | printf("\nGot event container with %d packets (allocated).\n", packetNum); 105 | 106 | for (int32_t i = 0; i < packetNum; i++) { 107 | caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(packetContainer, i); 108 | if (packetHeader == NULL) { 109 | printf("Packet %d is empty (not present).\n", i); 110 | continue; // Skip if nothing there. 111 | } 112 | 113 | printf("Packet %d of type %d -> size is %d.\n", i, caerEventPacketHeaderGetEventType(packetHeader), 114 | caerEventPacketHeaderGetEventNumber(packetHeader)); 115 | 116 | // Packet 0 is always the special events packet for DVS128, while packet is the polarity events packet. 117 | if (i == POLARITY_EVENT) { 118 | caerPolarityEventPacket polarity = (caerPolarityEventPacket) packetHeader; 119 | 120 | // Get full timestamp and addresses of first event. 121 | caerPolarityEvent firstEvent = caerPolarityEventPacketGetEvent(polarity, 0); 122 | 123 | int32_t ts = caerPolarityEventGetTimestamp(firstEvent); 124 | uint16_t x = caerPolarityEventGetX(firstEvent); 125 | uint16_t y = caerPolarityEventGetY(firstEvent); 126 | bool pol = caerPolarityEventGetPolarity(firstEvent); 127 | 128 | printf("First polarity event - ts: %d, x: %d, y: %d, pol: %d.\n", ts, x, y, pol); 129 | } 130 | } 131 | 132 | caerEventPacketContainerFree(packetContainer); 133 | } 134 | 135 | caerDeviceDataStop(davis_handle); 136 | 137 | caerDeviceClose(&davis_handle); 138 | 139 | printf("Shutdown successful.\n"); 140 | 141 | return (EXIT_SUCCESS); 142 | } 143 | -------------------------------------------------------------------------------- /libcaer/examples/dvs128_simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static atomic_bool globalShutdown = ATOMIC_VAR_INIT(false); 8 | 9 | static void globalShutdownSignalHandler(int signal) { 10 | // Simply set the running flag to false on SIGTERM and SIGINT (CTRL+C) for global shutdown. 11 | if (signal == SIGTERM || signal == SIGINT) { 12 | atomic_store(&globalShutdown, true); 13 | } 14 | } 15 | 16 | int main(void) { 17 | // Install signal handler for global shutdown. 18 | struct sigaction shutdownAction; 19 | 20 | shutdownAction.sa_handler = &globalShutdownSignalHandler; 21 | shutdownAction.sa_flags = 0; 22 | sigemptyset(&shutdownAction.sa_mask); 23 | sigaddset(&shutdownAction.sa_mask, SIGTERM); 24 | sigaddset(&shutdownAction.sa_mask, SIGINT); 25 | 26 | if (sigaction(SIGTERM, &shutdownAction, NULL) == -1) { 27 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); 28 | return (EXIT_FAILURE); 29 | } 30 | 31 | if (sigaction(SIGINT, &shutdownAction, NULL) == -1) { 32 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); 33 | return (EXIT_FAILURE); 34 | } 35 | 36 | // Open a DVS128, give it a device ID of 1, and don't care about USB bus or SN restrictions. 37 | caerDeviceHandle dvs128_handle = caerDeviceOpen(1, CAER_DEVICE_DVS128, 0, 0, NULL); 38 | if (dvs128_handle == NULL) { 39 | return (EXIT_FAILURE); 40 | } 41 | 42 | // Let's take a look at the information we have on the device. 43 | struct caer_dvs128_info dvs128_info = caerDVS128InfoGet(dvs128_handle); 44 | 45 | printf("%s --- ID: %d, Master: %d, DVS X: %d, DVS Y: %d, Logic: %d.\n", dvs128_info.deviceString, 46 | dvs128_info.deviceID, dvs128_info.deviceIsMaster, dvs128_info.dvsSizeX, dvs128_info.dvsSizeY, 47 | dvs128_info.logicVersion); 48 | 49 | // Send the default configuration before using the device. 50 | // No configuration is sent automatically! 51 | caerDeviceSendDefaultConfig(dvs128_handle); 52 | 53 | // Tweak some biases, to increase bandwidth in this case. 54 | caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, 695); 55 | caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, 867); 56 | 57 | // Let's verify they really changed! 58 | uint32_t prBias, follBias; 59 | caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, &prBias); 60 | caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, &follBias); 61 | 62 | printf("New bias values --- PR: %d, FOLL: %d.\n", prBias, follBias); 63 | 64 | // Now let's get start getting some data from the device. We just loop, no notification needed. 65 | caerDeviceDataStart(dvs128_handle, NULL, NULL, NULL, NULL, NULL); 66 | 67 | // Let's turn on blocking data-get mode to avoid wasting resources. 68 | caerDeviceConfigSet(dvs128_handle, CAER_HOST_CONFIG_DATAEXCHANGE, CAER_HOST_CONFIG_DATAEXCHANGE_BLOCKING, true); 69 | 70 | while (!atomic_load_explicit(&globalShutdown, memory_order_relaxed)) { 71 | caerEventPacketContainer packetContainer = caerDeviceDataGet(dvs128_handle); 72 | if (packetContainer == NULL) { 73 | continue; // Skip if nothing there. 74 | } 75 | 76 | int32_t packetNum = caerEventPacketContainerGetEventPacketsNumber(packetContainer); 77 | 78 | printf("\nGot event container with %d packets (allocated).\n", packetNum); 79 | 80 | for (int32_t i = 0; i < packetNum; i++) { 81 | caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(packetContainer, i); 82 | if (packetHeader == NULL) { 83 | printf("Packet %d is empty (not present).\n", i); 84 | continue; // Skip if nothing there. 85 | } 86 | 87 | printf("Packet %d of type %d -> size is %d.\n", i, caerEventPacketHeaderGetEventType(packetHeader), 88 | caerEventPacketHeaderGetEventNumber(packetHeader)); 89 | 90 | // Packet 0 is always the special events packet for DVS128, while packet is the polarity events packet. 91 | if (i == POLARITY_EVENT) { 92 | caerPolarityEventPacket polarity = (caerPolarityEventPacket) packetHeader; 93 | 94 | // Get full timestamp and addresses of first event. 95 | caerPolarityEvent firstEvent = caerPolarityEventPacketGetEvent(polarity, 0); 96 | 97 | int32_t ts = caerPolarityEventGetTimestamp(firstEvent); 98 | uint16_t x = caerPolarityEventGetX(firstEvent); 99 | uint16_t y = caerPolarityEventGetY(firstEvent); 100 | bool pol = caerPolarityEventGetPolarity(firstEvent); 101 | 102 | printf("First polarity event - ts: %d, x: %d, y: %d, pol: %d.\n", ts, x, y, pol); 103 | } 104 | } 105 | 106 | caerEventPacketContainerFree(packetContainer); 107 | } 108 | 109 | caerDeviceDataStop(dvs128_handle); 110 | 111 | caerDeviceClose(&dvs128_handle); 112 | 113 | printf("Shutdown successful.\n"); 114 | 115 | return (EXIT_SUCCESS); 116 | } 117 | -------------------------------------------------------------------------------- /libcaer/examples/dvs128_simple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | static atomic_bool globalShutdown(false); 10 | 11 | static void globalShutdownSignalHandler(int signal) { 12 | // Simply set the running flag to false on SIGTERM and SIGINT (CTRL+C) for global shutdown. 13 | if (signal == SIGTERM || signal == SIGINT) { 14 | globalShutdown.store(true); 15 | } 16 | } 17 | 18 | int main(void) { 19 | // Install signal handler for global shutdown. 20 | struct sigaction shutdownAction; 21 | 22 | shutdownAction.sa_handler = &globalShutdownSignalHandler; 23 | shutdownAction.sa_flags = 0; 24 | sigemptyset(&shutdownAction.sa_mask); 25 | sigaddset(&shutdownAction.sa_mask, SIGTERM); 26 | sigaddset(&shutdownAction.sa_mask, SIGINT); 27 | 28 | if (sigaction(SIGTERM, &shutdownAction, NULL) == -1) { 29 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); 30 | return (EXIT_FAILURE); 31 | } 32 | 33 | if (sigaction(SIGINT, &shutdownAction, NULL) == -1) { 34 | caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); 35 | return (EXIT_FAILURE); 36 | } 37 | 38 | // Open a DVS128, give it a device ID of 1, and don't care about USB bus or SN restrictions. 39 | caerDeviceHandle dvs128_handle = caerDeviceOpen(1, CAER_DEVICE_DVS128, 0, 0, NULL); 40 | if (dvs128_handle == NULL) { 41 | return (EXIT_FAILURE); 42 | } 43 | 44 | // Let's take a look at the information we have on the device. 45 | struct caer_dvs128_info dvs128_info = caerDVS128InfoGet(dvs128_handle); 46 | 47 | printf("%s --- ID: %d, Master: %d, DVS X: %d, DVS Y: %d, Logic: %d.\n", dvs128_info.deviceString, 48 | dvs128_info.deviceID, dvs128_info.deviceIsMaster, dvs128_info.dvsSizeX, dvs128_info.dvsSizeY, 49 | dvs128_info.logicVersion); 50 | 51 | // Send the default configuration before using the device. 52 | // No configuration is sent automatically! 53 | caerDeviceSendDefaultConfig(dvs128_handle); 54 | 55 | // Tweak some biases, to increase bandwidth in this case. 56 | caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, 695); 57 | caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, 867); 58 | 59 | // Let's verify they really changed! 60 | uint32_t prBias, follBias; 61 | caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, &prBias); 62 | caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, &follBias); 63 | 64 | printf("New bias values --- PR: %d, FOLL: %d.\n", prBias, follBias); 65 | 66 | // Now let's get start getting some data from the device. We just loop, no notification needed. 67 | caerDeviceDataStart(dvs128_handle, NULL, NULL, NULL, NULL, NULL); 68 | 69 | // Let's turn on blocking data-get mode to avoid wasting resources. 70 | caerDeviceConfigSet(dvs128_handle, CAER_HOST_CONFIG_DATAEXCHANGE, CAER_HOST_CONFIG_DATAEXCHANGE_BLOCKING, true); 71 | 72 | while (!globalShutdown.load(memory_order_relaxed)) { 73 | caerEventPacketContainer packetContainer = caerDeviceDataGet(dvs128_handle); 74 | if (packetContainer == NULL) { 75 | continue; // Skip if nothing there. 76 | } 77 | 78 | int32_t packetNum = caerEventPacketContainerGetEventPacketsNumber(packetContainer); 79 | 80 | printf("\nGot event container with %d packets (allocated).\n", packetNum); 81 | 82 | for (int32_t i = 0; i < packetNum; i++) { 83 | caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(packetContainer, i); 84 | if (packetHeader == NULL) { 85 | printf("Packet %d is empty (not present).\n", i); 86 | continue; // Skip if nothing there. 87 | } 88 | 89 | printf("Packet %d of type %d -> size is %d.\n", i, caerEventPacketHeaderGetEventType(packetHeader), 90 | caerEventPacketHeaderGetEventNumber(packetHeader)); 91 | 92 | // Packet 0 is always the special events packet for DVS128, while packet is the polarity events packet. 93 | if (i == POLARITY_EVENT) { 94 | caerPolarityEventPacket polarity = (caerPolarityEventPacket) packetHeader; 95 | 96 | // Get full timestamp and addresses of first event. 97 | caerPolarityEvent firstEvent = caerPolarityEventPacketGetEvent(polarity, 0); 98 | 99 | int32_t ts = caerPolarityEventGetTimestamp(firstEvent); 100 | uint16_t x = caerPolarityEventGetX(firstEvent); 101 | uint16_t y = caerPolarityEventGetY(firstEvent); 102 | bool pol = caerPolarityEventGetPolarity(firstEvent); 103 | 104 | printf("First polarity event - ts: %d, x: %d, y: %d, pol: %d.\n", ts, x, y, pol); 105 | } 106 | } 107 | 108 | caerEventPacketContainerFree(packetContainer); 109 | } 110 | 111 | caerDeviceDataStop(dvs128_handle); 112 | 113 | caerDeviceClose(&dvs128_handle); 114 | 115 | printf("Shutdown successful.\n"); 116 | 117 | return (EXIT_SUCCESS); 118 | } 119 | -------------------------------------------------------------------------------- /libcaer/include/.gitignore: -------------------------------------------------------------------------------- 1 | /libcaer.h 2 | -------------------------------------------------------------------------------- /libcaer/include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(libcaer_in.h ${CMAKE_CURRENT_SOURCE_DIR}/libcaer.h @ONLY) 2 | 3 | SET(INC_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}) 4 | INSTALL(FILES libcaer.h log.h portable_endian.h frame_utils.h DESTINATION ${INC_INSTALL_DIR}) 5 | INSTALL(DIRECTORY events DESTINATION ${INC_INSTALL_DIR}) 6 | INSTALL(DIRECTORY devices DESTINATION ${INC_INSTALL_DIR}) 7 | 8 | IF (ENABLE_OPENCV) 9 | INSTALL(FILES frame_utils_opencv.h DESTINATION ${INC_INSTALL_DIR}) 10 | ENDIF() 11 | -------------------------------------------------------------------------------- /libcaer/include/devices/dvs128.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dvs128.h 3 | * 4 | * DVS128 specific configuration defines and information structures. 5 | */ 6 | 7 | #ifndef LIBCAER_DEVICES_DVS128_H_ 8 | #define LIBCAER_DEVICES_DVS128_H_ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #include "usb.h" 15 | #include "../events/polarity.h" 16 | #include "../events/special.h" 17 | 18 | /** 19 | * Device type definition for iniLabs DVS128. 20 | */ 21 | #define CAER_DEVICE_DVS128 0 22 | 23 | /** 24 | * Module address: device-side DVS configuration. 25 | */ 26 | #define DVS128_CONFIG_DVS 0 27 | /** 28 | * Module address: device-side chip bias generator configuration. 29 | */ 30 | #define DVS128_CONFIG_BIAS 1 31 | 32 | /** 33 | * Parameter address for module DVS128_CONFIG_DVS: 34 | * run the DVS chip and generate polarity event data. 35 | */ 36 | #define DVS128_CONFIG_DVS_RUN 0 37 | /** 38 | * Parameter address for module DVS128_CONFIG_DVS: 39 | * reset the time-stamp counter of the device. This is a temporary 40 | * configuration switch and will reset itself right away. 41 | */ 42 | #define DVS128_CONFIG_DVS_TIMESTAMP_RESET 1 43 | /** 44 | * Parameter address for module DVS128_CONFIG_DVS: 45 | * reset the whole DVS pixel array. This is a temporary 46 | * configuration switch and will reset itself right away. 47 | */ 48 | #define DVS128_CONFIG_DVS_ARRAY_RESET 2 49 | /** 50 | * Parameter address for module DVS128_CONFIG_DVS: 51 | * control if this DVS is a timestamp master device. 52 | * Default is enabled. 53 | */ 54 | #define DVS128_CONFIG_DVS_TS_MASTER 3 55 | 56 | /** 57 | * Parameter address for module DVS128_CONFIG_BIAS: 58 | * First stage amplifier cascode bias. 59 | * See 'http://inilabs.com/support/biasing/' for more details. 60 | */ 61 | #define DVS128_CONFIG_BIAS_CAS 0 62 | /** 63 | * Parameter address for module DVS128_CONFIG_BIAS: 64 | * Injected ground bias. 65 | * See 'http://inilabs.com/support/biasing/' for more details. 66 | */ 67 | #define DVS128_CONFIG_BIAS_INJGND 1 68 | /** 69 | * Parameter address for module DVS128_CONFIG_BIAS: 70 | * Pull down on chip request (AER). 71 | * See 'http://inilabs.com/support/biasing/' for more details. 72 | */ 73 | #define DVS128_CONFIG_BIAS_REQPD 2 74 | /** 75 | * Parameter address for module DVS128_CONFIG_BIAS: 76 | * Pull up on request from X arbiter (AER). 77 | * See 'http://inilabs.com/support/biasing/' for more details. 78 | */ 79 | #define DVS128_CONFIG_BIAS_PUX 3 80 | /** 81 | * Parameter address for module DVS128_CONFIG_BIAS: 82 | * Off events threshold bias. 83 | * See 'http://inilabs.com/support/biasing/' for more details. 84 | */ 85 | #define DVS128_CONFIG_BIAS_DIFFOFF 4 86 | /** 87 | * Parameter address for module DVS128_CONFIG_BIAS: 88 | * Pull down for passive load inverters in digital AER pixel circuitry. 89 | * See 'http://inilabs.com/support/biasing/' for more details. 90 | */ 91 | #define DVS128_CONFIG_BIAS_REQ 5 92 | /** 93 | * Parameter address for module DVS128_CONFIG_BIAS: 94 | * Refractory period bias. 95 | * See 'http://inilabs.com/support/biasing/' for more details. 96 | */ 97 | #define DVS128_CONFIG_BIAS_REFR 6 98 | /** 99 | * Parameter address for module DVS128_CONFIG_BIAS: 100 | * Pull up on request from Y arbiter (AER). 101 | * See 'http://inilabs.com/support/biasing/' for more details. 102 | */ 103 | #define DVS128_CONFIG_BIAS_PUY 7 104 | /** 105 | * Parameter address for module DVS128_CONFIG_BIAS: 106 | * On events threshold bias. 107 | * See 'http://inilabs.com/support/biasing/' for more details. 108 | */ 109 | #define DVS128_CONFIG_BIAS_DIFFON 8 110 | /** 111 | * Parameter address for module DVS128_CONFIG_BIAS: 112 | * Differential (second stage amplifier) bias. 113 | * See 'http://inilabs.com/support/biasing/' for more details. 114 | */ 115 | #define DVS128_CONFIG_BIAS_DIFF 9 116 | /** 117 | * Parameter address for module DVS128_CONFIG_BIAS: 118 | * Source follower bias. 119 | * See 'http://inilabs.com/support/biasing/' for more details. 120 | */ 121 | #define DVS128_CONFIG_BIAS_FOLL 10 122 | /** 123 | * Parameter address for module DVS128_CONFIG_BIAS: 124 | * Photoreceptor bias. 125 | * See 'http://inilabs.com/support/biasing/' for more details. 126 | */ 127 | #define DVS128_CONFIG_BIAS_PR 11 128 | 129 | /** 130 | * DVS128 device-related information. 131 | */ 132 | struct caer_dvs128_info { 133 | /// Unique device identifier. Also 'source' for events. 134 | int16_t deviceID; 135 | /// Device serial number. 136 | char deviceSerialNumber[8 + 1]; 137 | /// Device USB bus number. 138 | uint8_t deviceUSBBusNumber; 139 | /// Device USB device address. 140 | uint8_t deviceUSBDeviceAddress; 141 | /// Device information string, for logging purposes. 142 | char *deviceString; 143 | /// Logic (FPGA/CPLD) version. 144 | int16_t logicVersion; 145 | /// Whether the device is a time-stamp master or slave. 146 | bool deviceIsMaster; 147 | /// DVS X axis resolution. 148 | int16_t dvsSizeX; 149 | /// DVS Y axis resolution. 150 | int16_t dvsSizeY; 151 | }; 152 | 153 | /** 154 | * Return basic information on the device, such as its ID, its 155 | * resolution, the logic version, and so on. See the 'struct 156 | * caer_dvs128_info' documentation for more details. 157 | * 158 | * @param handle a valid device handle. 159 | * 160 | * @return a copy of the device information structure if successful, 161 | * an empty structure (all zeros) on failure. 162 | */ 163 | struct caer_dvs128_info caerDVS128InfoGet(caerDeviceHandle handle); 164 | 165 | #ifdef __cplusplus 166 | } 167 | #endif 168 | 169 | #endif /* LIBCAER_DEVICES_DVS128_H_ */ 170 | -------------------------------------------------------------------------------- /libcaer/include/frame_utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file frame_utils.h 3 | * 4 | * Basic functions for frame enhancement and demosaicing, that don't 5 | * require any external dependencies, such as OpenCV. 6 | * Use of the OpenCV variants is recommended for quality and performance. 7 | */ 8 | 9 | #ifndef LIBCAER_FRAME_UTILS_H_ 10 | #define LIBCAER_FRAME_UTILS_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include "events/frame.h" 17 | 18 | caerFrameEventPacket caerFrameUtilsDemosaic(caerFrameEventPacket framePacket); 19 | void caerFrameUtilsContrast(caerFrameEventPacket framePacket); 20 | void caerFrameUtilsWhiteBalance(caerFrameEventPacket framePacket); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif /* LIBCAER_FRAME_UTILS_H_ */ 27 | -------------------------------------------------------------------------------- /libcaer/include/frame_utils_opencv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file frame_utils_opencv.h 3 | * 4 | * Functions for frame enhancement and demosaicing, using 5 | * the popular OpenCV image processing library. 6 | */ 7 | 8 | #ifndef LIBCAER_FRAME_UTILS_OPENCV_H_ 9 | #define LIBCAER_FRAME_UTILS_OPENCV_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include "events/frame.h" 16 | 17 | enum caer_frame_utils_opencv_demosaic { 18 | DEMOSAIC_NORMAL, DEMOSAIC_EDGE_AWARE, // DEMOSAIC_VARIABLE_NUMBER_OF_GRADIENTS not supported on 16bit images currently. 19 | }; 20 | 21 | enum caer_frame_utils_opencv_contrast { 22 | CONTRAST_NORMALIZATION, CONTRAST_HISTOGRAM_EQUALIZATION, CONTRAST_CLAHE, 23 | }; 24 | 25 | enum caer_frame_utils_opencv_white_balance { 26 | WHITEBALANCE_SIMPLE, WHITEBALANCE_GRAYWORLD, 27 | }; 28 | 29 | caerFrameEventPacket caerFrameUtilsOpenCVDemosaic(caerFrameEventPacket framePacket, 30 | enum caer_frame_utils_opencv_demosaic demosaicType); 31 | void caerFrameUtilsOpenCVContrast(caerFrameEventPacket framePacket, enum caer_frame_utils_opencv_contrast contrastType); 32 | void caerFrameUtilsOpenCVWhiteBalance(caerFrameEventPacket framePacket, 33 | enum caer_frame_utils_opencv_white_balance whiteBalanceType); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* LIBCAER_FRAME_UTILS_OPENCV_H_ */ 40 | -------------------------------------------------------------------------------- /libcaer/include/log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file log.h 3 | * 4 | * Logging functions to print useful messages for the user. 5 | */ 6 | 7 | #ifndef LIBCAER_LOG_H_ 8 | #define LIBCAER_LOG_H_ 9 | 10 | #ifdef __cplusplus 11 | 12 | #include 13 | 14 | extern "C" { 15 | #endif 16 | 17 | #include 18 | 19 | //@{ 20 | /** 21 | * Log levels for caerLog() logging function. 22 | * Log messages only get printed if their log level is equal or 23 | * above the global system log level, which can be set with 24 | * caerLogLevelSet(). 25 | * The default log level is CAER_LOG_ERROR. 26 | * CAER_LOG_EMERGENCY is the most urgent log level and will always 27 | * be printed, while CAER_LOG_DEBUG is the least urgent log 28 | * level and will only be delivered if configured by the user. 29 | */ 30 | #define CAER_LOG_EMERGENCY (0) 31 | #define CAER_LOG_ALERT (1) 32 | #define CAER_LOG_CRITICAL (2) 33 | #define CAER_LOG_ERROR (3) 34 | #define CAER_LOG_WARNING (4) 35 | #define CAER_LOG_NOTICE (5) 36 | #define CAER_LOG_INFO (6) 37 | #define CAER_LOG_DEBUG (7) 38 | //@} 39 | 40 | /** 41 | * Set the system-wide log level. 42 | * Log messages will only be printed if their level is equal or above 43 | * this level. 44 | * 45 | * @param logLevel the system-wide log level. 46 | */ 47 | void caerLogLevelSet(uint8_t logLevel); 48 | 49 | /** 50 | * Get the current system-wide log level. 51 | * Log messages are only printed if their level is equal or above 52 | * this level. 53 | * 54 | * @return the current system-wide log level. 55 | */ 56 | uint8_t caerLogLevelGet(void); 57 | 58 | /** 59 | * Set to which file descriptors log messages are sent. 60 | * Up to two different file descriptors can be configured here. 61 | * By default logging to STDERR only is enabled. 62 | * If both file descriptors are identical, logging to it will 63 | * only happen once, as if the second one was disabled. 64 | * 65 | * @param fd1 first file descriptor to log to. A negative value will disable it. 66 | * @param fd2 second file descriptor to log to. A negative value will disable it. 67 | */ 68 | void caerLogFileDescriptorsSet(int fd1, int fd2); 69 | 70 | /** 71 | * Main logging function. 72 | * This function takes messages, formats them and sends them out to a file descriptor, 73 | * respecting the system-wide log level setting and prepending the current time, the 74 | * log level and a user-specified common string to the actual formatted output. 75 | * The format is specified exactly as with the printf() family of functions. 76 | * Please see their manual-page for more information. 77 | * 78 | * @param logLevel the message-specific log level. 79 | * @param subSystem a common, user-specified string to prepend before the message. 80 | * @param format the message format string (see printf()). 81 | * @param ... the parameters to be formatted according to the format string (see printf()). 82 | */ 83 | void caerLog(uint8_t logLevel, const char *subSystem, const char *format, ...) __attribute__ ((format (printf, 3, 4))); 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /* LIBCAER_LOG_H_ */ 90 | -------------------------------------------------------------------------------- /libcaer/include/portable_endian.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file portable_endian.h 3 | * 4 | * Endianness conversion functions for a wide variety of systems, 5 | * including Linux, FreeBSD, MacOS X and Windows. 6 | */ 7 | 8 | // "License": Public Domain 9 | // I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. 10 | // In case there are jurisdictions that don't support putting things in the public domain you can also consider it to 11 | // be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it 12 | // an example on how to get the endian conversion functions on different platforms. 13 | 14 | #ifndef PORTABLE_ENDIAN_H__ 15 | #define PORTABLE_ENDIAN_H__ 16 | 17 | #if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) 18 | #define __WINDOWS__ 19 | #endif 20 | 21 | #if defined(__linux__) || defined(__CYGWIN__) 22 | #include 23 | #elif defined(__APPLE__) 24 | #include 25 | 26 | #define htobe16(x) OSSwapHostToBigInt16(x) 27 | #define htole16(x) OSSwapHostToLittleInt16(x) 28 | #define be16toh(x) OSSwapBigToHostInt16(x) 29 | #define le16toh(x) OSSwapLittleToHostInt16(x) 30 | 31 | #define htobe32(x) OSSwapHostToBigInt32(x) 32 | #define htole32(x) OSSwapHostToLittleInt32(x) 33 | #define be32toh(x) OSSwapBigToHostInt32(x) 34 | #define le32toh(x) OSSwapLittleToHostInt32(x) 35 | 36 | #define htobe64(x) OSSwapHostToBigInt64(x) 37 | #define htole64(x) OSSwapHostToLittleInt64(x) 38 | #define be64toh(x) OSSwapBigToHostInt64(x) 39 | #define le64toh(x) OSSwapLittleToHostInt64(x) 40 | 41 | #define __BYTE_ORDER BYTE_ORDER 42 | #define __BIG_ENDIAN BIG_ENDIAN 43 | #define __LITTLE_ENDIAN LITTLE_ENDIAN 44 | #define __PDP_ENDIAN PDP_ENDIAN 45 | #elif defined(__OpenBSD__) 46 | #include 47 | #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) 48 | #include 49 | 50 | #define be16toh(x) betoh16(x) 51 | #define le16toh(x) letoh16(x) 52 | 53 | #define be32toh(x) betoh32(x) 54 | #define le32toh(x) letoh32(x) 55 | 56 | #define be64toh(x) betoh64(x) 57 | #define le64toh(x) letoh64(x) 58 | #elif defined(__WINDOWS__) 59 | #include 60 | #include 61 | 62 | #if BYTE_ORDER == LITTLE_ENDIAN 63 | #define htobe16(x) htons(x) 64 | #define htole16(x) (x) 65 | #define be16toh(x) ntohs(x) 66 | #define le16toh(x) (x) 67 | 68 | #define htobe32(x) htonl(x) 69 | #define htole32(x) (x) 70 | #define be32toh(x) ntohl(x) 71 | #define le32toh(x) (x) 72 | 73 | #define htobe64(x) htonll(x) 74 | #define htole64(x) (x) 75 | #define be64toh(x) ntohll(x) 76 | #define le64toh(x) (x) 77 | #elif BYTE_ORDER == BIG_ENDIAN 78 | /* That would be Xbox 360. */ 79 | #define htobe16(x) (x) 80 | #define htole16(x) __builtin_bswap16(x) 81 | #define be16toh(x) (x) 82 | #define le16toh(x) __builtin_bswap16(x) 83 | 84 | #define htobe32(x) (x) 85 | #define htole32(x) __builtin_bswap32(x) 86 | #define be32toh(x) (x) 87 | #define le32toh(x) __builtin_bswap32(x) 88 | 89 | #define htobe64(x) (x) 90 | #define htole64(x) __builtin_bswap64(x) 91 | #define be64toh(x) (x) 92 | #define le64toh(x) __builtin_bswap64(x) 93 | #else 94 | #error byte order not supported 95 | #endif 96 | 97 | #define __BYTE_ORDER BYTE_ORDER 98 | #define __BIG_ENDIAN BIG_ENDIAN 99 | #define __LITTLE_ENDIAN LITTLE_ENDIAN 100 | #define __PDP_ENDIAN PDP_ENDIAN 101 | #else 102 | #error platform not supported 103 | #endif 104 | 105 | #endif /* PORTABLE_ENDIAN_H__ */ 106 | -------------------------------------------------------------------------------- /libcaer/libcaer.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 4 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 5 | 6 | Name: @CMAKE_PROJECT_NAME@ 7 | Description: Minimal C API for low-level access to DVS128, DAVIS devices. 8 | Version: @PROJECT_VERSION_NOREV@ 9 | Requires.private: libusb-1.0 >= 1.0.17 10 | Libs: -L${libdir} -lcaer 11 | Libs.private: @PRIVATE_LIBS@ 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /libcaer/libcaer_opencv.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 4 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 5 | 6 | Name: @CMAKE_PROJECT_NAME@ 7 | Description: Minimal C API for low-level access to DVS128, DAVIS devices. Uses OpenCV for frame enhancement. 8 | Version: @PROJECT_VERSION_NOREV@ 9 | Requires.private: libusb-1.0 >= 1.0.17, opencv >= 3.1 10 | Libs: -L${libdir} -lcaer 11 | Libs.private: @PRIVATE_LIBS@ 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /libcaer/src/.gitignore: -------------------------------------------------------------------------------- 1 | /*.dylib 2 | /libcaer.so* 3 | -------------------------------------------------------------------------------- /libcaer/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIBCAER_SRC_FILES 2 | ringbuffer/ringbuffer.c 3 | log.c 4 | events.c 5 | frame_utils.c 6 | device.c 7 | dvs128.c 8 | davis_common.c 9 | davis_fx2.c 10 | davis_fx3.c) 11 | 12 | IF (ENABLE_OPENCV) 13 | # Add C++ OpenCV file and its C wrapper. 14 | SET(LIBCAER_SRC_FILES ${LIBCAER_SRC_FILES} frame_utils_opencv.cpp) 15 | ENDIF() 16 | 17 | SET(LIBCAER_SRC_FILES ${LIBCAER_SRC_FILES} PARENT_SCOPE) 18 | 19 | IF (UNIX AND NOT APPLE) 20 | # Add --as-needed to linker flags for library. 21 | SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed") 22 | ENDIF() 23 | 24 | ADD_LIBRARY(caer SHARED ${LIBCAER_SRC_FILES}) 25 | 26 | SET_TARGET_PROPERTIES(caer 27 | PROPERTIES 28 | SOVERSION ${PROJECT_VERSION_MAJOR} 29 | VERSION ${PROJECT_VERSION_NOREV} 30 | ) 31 | 32 | TARGET_LINK_LIBRARIES(caer ${LIBCAER_LIBS}) 33 | 34 | IF (OS_WINDOWS) 35 | INSTALL(TARGETS caer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) 36 | ELSE() 37 | INSTALL(TARGETS caer DESTINATION ${CMAKE_INSTALL_LIBDIR}) 38 | ENDIF() 39 | -------------------------------------------------------------------------------- /libcaer/src/davis_common.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBCAER_SRC_DAVIS_COMMON_H_ 2 | #define LIBCAER_SRC_DAVIS_COMMON_H_ 3 | 4 | #include "devices/davis.h" 5 | #include "ringbuffer/ringbuffer.h" 6 | #include 7 | #include 8 | 9 | #ifdef HAVE_PTHREADS 10 | #include "c11threads_posix.h" 11 | #endif 12 | 13 | #define APS_READOUT_TYPES_NUM 2 14 | #define APS_READOUT_RESET 0 15 | #define APS_READOUT_SIGNAL 1 16 | 17 | /** 18 | * Enable APS frame debugging by only looking at the reset or signal 19 | * frames, and not at the resulting correlated frame. 20 | * Supported values: 21 | * 0 - both/CDS (default) 22 | * 1 - reset read only 23 | * 2 - signal read only 24 | */ 25 | #define APS_DEBUG_FRAME 0 26 | 27 | #define APS_ADC_DEPTH 10 28 | 29 | #define APS_ADC_CHANNELS 1 30 | 31 | #define APS_ROI_REGIONS_MAX 4 32 | 33 | #define IMU6_COUNT 15 34 | #define IMU9_COUNT 21 35 | 36 | #define DAVIS_EVENT_TYPES 4 37 | 38 | #define DAVIS_POLARITY_DEFAULT_SIZE 4096 39 | #define DAVIS_SPECIAL_DEFAULT_SIZE 128 40 | #define DAVIS_FRAME_DEFAULT_SIZE 4 41 | #define DAVIS_IMU_DEFAULT_SIZE 64 42 | 43 | #define DAVIS_DATA_ENDPOINT 0x82 44 | 45 | #define VENDOR_REQUEST_FPGA_CONFIG 0xBF 46 | #define VENDOR_REQUEST_FPGA_CONFIG_MULTIPLE 0xC2 47 | 48 | struct davis_state { 49 | // Data Acquisition Thread -> Mainloop Exchange 50 | RingBuffer dataExchangeBuffer; 51 | atomic_uint_fast32_t dataExchangeBufferSize; // Only takes effect on DataStart() calls! 52 | atomic_bool dataExchangeBlocking; 53 | atomic_bool dataExchangeStartProducers; 54 | atomic_bool dataExchangeStopProducers; 55 | void (*dataNotifyIncrease)(void *ptr); 56 | void (*dataNotifyDecrease)(void *ptr); 57 | void *dataNotifyUserPtr; 58 | void (*dataShutdownNotify)(void *ptr); 59 | void *dataShutdownUserPtr; 60 | // USB Device State 61 | char deviceThreadName[15 + 1]; // +1 for terminating NUL character. 62 | libusb_context *deviceContext; 63 | libusb_device_handle *deviceHandle; 64 | // USB Transfer Settings 65 | atomic_uint_fast32_t usbBufferNumber; 66 | atomic_uint_fast32_t usbBufferSize; 67 | // Data Acquisition Thread 68 | thrd_t dataAcquisitionThread; 69 | atomic_bool dataAcquisitionThreadRun; 70 | atomic_uint_fast32_t dataAcquisitionThreadConfigUpdate; 71 | struct libusb_transfer **dataTransfers; 72 | size_t dataTransfersLength; 73 | size_t activeDataTransfers; 74 | // Timestamp fields 75 | int32_t wrapOverflow; 76 | int32_t wrapAdd; 77 | int32_t lastTimestamp; 78 | int32_t currentTimestamp; 79 | // DVS specific fields 80 | uint16_t dvsLastY; 81 | bool dvsGotY; 82 | int16_t dvsSizeX; 83 | int16_t dvsSizeY; 84 | bool dvsInvertXY; 85 | // APS specific fields 86 | int16_t apsSizeX; 87 | int16_t apsSizeY; 88 | bool apsInvertXY; 89 | bool apsFlipX; 90 | bool apsFlipY; 91 | bool apsIgnoreEvents; 92 | bool apsGlobalShutter; 93 | bool apsResetRead; 94 | bool apsRGBPixelOffsetDirection; // 0 is increasing, 1 is decreasing. 95 | int16_t apsRGBPixelOffset; 96 | uint16_t apsCurrentReadoutType; 97 | uint16_t apsCountX[APS_READOUT_TYPES_NUM]; 98 | uint16_t apsCountY[APS_READOUT_TYPES_NUM]; 99 | uint16_t *apsCurrentResetFrame; 100 | uint16_t apsROIUpdate; 101 | uint16_t apsROITmpData; 102 | uint16_t apsROISizeX[APS_ROI_REGIONS_MAX]; 103 | uint16_t apsROISizeY[APS_ROI_REGIONS_MAX]; 104 | uint16_t apsROIPositionX[APS_ROI_REGIONS_MAX]; 105 | uint16_t apsROIPositionY[APS_ROI_REGIONS_MAX]; 106 | // IMU specific fields 107 | bool imuIgnoreEvents; 108 | uint8_t imuCount; 109 | uint8_t imuTmpData; 110 | float imuAccelScale; 111 | float imuGyroScale; 112 | // Packet Container state 113 | caerEventPacketContainer currentPacketContainer; 114 | atomic_int_fast32_t maxPacketContainerPacketSize; 115 | atomic_int_fast32_t maxPacketContainerInterval; 116 | int64_t currentPacketContainerCommitTimestamp; 117 | // Polarity Packet state 118 | caerPolarityEventPacket currentPolarityPacket; 119 | int32_t currentPolarityPacketPosition; 120 | // Frame Packet state 121 | caerFrameEventPacket currentFramePacket; 122 | int32_t currentFramePacketPosition; 123 | // IMU6 Packet state 124 | caerIMU6EventPacket currentIMU6Packet; 125 | int32_t currentIMU6PacketPosition; 126 | // Special Packet state 127 | caerSpecialEventPacket currentSpecialPacket; 128 | int32_t currentSpecialPacketPosition; 129 | // Current composite events, for later copy, to not loose them on commits. 130 | caerFrameEvent currentFrameEvent[APS_ROI_REGIONS_MAX]; 131 | struct caer_imu6_event currentIMU6Event; 132 | }; 133 | 134 | typedef struct davis_state *davisState; 135 | 136 | struct davis_handle { 137 | uint16_t deviceType; 138 | // Information fields 139 | struct caer_davis_info info; 140 | // State for data management, common to all DAVIS. 141 | struct davis_state state; 142 | }; 143 | 144 | typedef struct davis_handle *davisHandle; 145 | 146 | bool davisCommonOpen(davisHandle handle, uint16_t VID, uint16_t PID, uint8_t DID_TYPE, const char *deviceName, 147 | uint16_t deviceID, uint8_t busNumberRestrict, uint8_t devAddressRestrict, const char *serialNumberRestrict, 148 | uint16_t requiredLogicRevision, uint16_t requiredFirmwareVersion); 149 | bool davisCommonClose(davisHandle handle); 150 | 151 | bool davisCommonSendDefaultFPGAConfig(caerDeviceHandle cdh, 152 | bool (*configSet)(caerDeviceHandle cdh, int8_t modAddr, uint8_t paramAddr, uint32_t param)); 153 | bool davisCommonSendDefaultChipConfig(caerDeviceHandle cdh, 154 | bool (*configSet)(caerDeviceHandle cdh, int8_t modAddr, uint8_t paramAddr, uint32_t param)); 155 | 156 | bool davisCommonConfigSet(davisHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t param); 157 | bool davisCommonConfigGet(davisHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t *param); 158 | 159 | bool davisCommonDataStart(caerDeviceHandle handle, void (*dataNotifyIncrease)(void *ptr), 160 | void (*dataNotifyDecrease)(void *ptr), void *dataNotifyUserPtr, void (*dataShutdownNotify)(void *ptr), 161 | void *dataShutdownUserPtr); 162 | bool davisCommonDataStop(caerDeviceHandle handle); 163 | caerEventPacketContainer davisCommonDataGet(caerDeviceHandle handle); 164 | 165 | #endif /* LIBCAER_SRC_DAVIS_COMMON_H_ */ 166 | -------------------------------------------------------------------------------- /libcaer/src/davis_fx2.c: -------------------------------------------------------------------------------- 1 | #include "davis_fx2.h" 2 | 3 | caerDeviceHandle davisFX2Open(uint16_t deviceID, uint8_t busNumberRestrict, uint8_t devAddressRestrict, 4 | const char *serialNumberRestrict) { 5 | caerLog(CAER_LOG_DEBUG, __func__, "Initializing %s.", DAVIS_FX2_DEVICE_NAME); 6 | 7 | davisFX2Handle handle = calloc(1, sizeof(*handle)); 8 | if (handle == NULL) { 9 | // Failed to allocate memory for device handle! 10 | caerLog(CAER_LOG_CRITICAL, __func__, "Failed to allocate memory for device handle."); 11 | return (NULL); 12 | } 13 | 14 | // Set main deviceType correctly right away. 15 | handle->h.deviceType = CAER_DEVICE_DAVIS_FX2; 16 | 17 | bool openRetVal = davisCommonOpen((davisHandle) handle, DAVIS_FX2_DEVICE_VID, DAVIS_FX2_DEVICE_PID, 18 | DAVIS_FX2_DEVICE_DID_TYPE, DAVIS_FX2_DEVICE_NAME, deviceID, busNumberRestrict, devAddressRestrict, 19 | serialNumberRestrict, DAVIS_FX2_REQUIRED_LOGIC_REVISION, 20 | DAVIS_FX2_REQUIRED_FIRMWARE_VERSION); 21 | if (!openRetVal) { 22 | free(handle); 23 | 24 | // Failed to open device and grab basic information! 25 | return (NULL); 26 | } 27 | 28 | return ((caerDeviceHandle) handle); 29 | } 30 | 31 | bool davisFX2Close(caerDeviceHandle cdh) { 32 | caerLog(CAER_LOG_DEBUG, ((davisHandle) cdh)->info.deviceString, "Shutting down ..."); 33 | 34 | return (davisCommonClose((davisHandle) cdh)); 35 | } 36 | 37 | bool davisFX2SendDefaultConfig(caerDeviceHandle cdh) { 38 | // First send default chip/bias config. 39 | if (!davisCommonSendDefaultChipConfig(cdh, &davisFX2ConfigSet)) { 40 | return (false); 41 | } 42 | 43 | // Send default FPGA config. 44 | if (!davisCommonSendDefaultFPGAConfig(cdh, &davisFX2ConfigSet)) { 45 | return (false); 46 | } 47 | 48 | // FX2 specific FPGA configuration. 49 | if (!davisFX2ConfigSet(cdh, DAVIS_CONFIG_DVS, DAVIS_CONFIG_DVS_ACK_DELAY_ROW, 14)) { 50 | return (false); 51 | } 52 | 53 | if (!davisFX2ConfigSet(cdh, DAVIS_CONFIG_DVS, DAVIS_CONFIG_DVS_ACK_EXTENSION_ROW, 4)) { 54 | return (false); 55 | } 56 | 57 | return (true); 58 | } 59 | 60 | bool davisFX2ConfigSet(caerDeviceHandle cdh, int8_t modAddr, uint8_t paramAddr, uint32_t param) { 61 | davisHandle handle = (davisHandle) cdh; 62 | 63 | return (davisCommonConfigSet(handle, modAddr, paramAddr, param)); 64 | } 65 | 66 | bool davisFX2ConfigGet(caerDeviceHandle cdh, int8_t modAddr, uint8_t paramAddr, uint32_t *param) { 67 | davisHandle handle = (davisHandle) cdh; 68 | 69 | return (davisCommonConfigGet(handle, modAddr, paramAddr, param)); 70 | } 71 | -------------------------------------------------------------------------------- /libcaer/src/davis_fx2.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBCAER_SRC_DAVIS_FX2_H_ 2 | #define LIBCAER_SRC_DAVIS_FX2_H_ 3 | 4 | #include "davis_common.h" 5 | 6 | #define DAVIS_FX2_DEVICE_NAME "DAVIS FX2" 7 | 8 | #define DAVIS_FX2_DEVICE_VID 0x152A 9 | #define DAVIS_FX2_DEVICE_PID 0x841B 10 | #define DAVIS_FX2_DEVICE_DID_TYPE 0x00 11 | 12 | #define DAVIS_FX2_REQUIRED_LOGIC_REVISION 7449 13 | #define DAVIS_FX2_REQUIRED_FIRMWARE_VERSION 3 14 | 15 | #define VENDOR_REQUEST_CHIP_BIAS 0xC0 16 | #define VENDOR_REQUEST_CHIP_DIAG 0xC1 17 | 18 | struct davis_fx2_handle { 19 | // Common info and state structure (handle). 20 | struct davis_handle h; 21 | }; 22 | 23 | typedef struct davis_fx2_handle *davisFX2Handle; 24 | 25 | caerDeviceHandle davisFX2Open(uint16_t deviceID, uint8_t busNumberRestrict, uint8_t devAddressRestrict, 26 | const char *serialNumberRestrict); 27 | bool davisFX2Close(caerDeviceHandle handle); 28 | 29 | bool davisFX2SendDefaultConfig(caerDeviceHandle handle); 30 | // Negative addresses are used for host-side configuration. 31 | // Positive addresses (including zero) are used for device-side configuration. 32 | bool davisFX2ConfigSet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t param); 33 | bool davisFX2ConfigGet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t *param); 34 | 35 | #endif /* LIBCAER_SRC_DAVIS_FX2_H_ */ 36 | -------------------------------------------------------------------------------- /libcaer/src/davis_fx3.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBCAER_SRC_DAVIS_FX3_H_ 2 | #define LIBCAER_SRC_DAVIS_FX3_H_ 3 | 4 | #include "davis_common.h" 5 | 6 | #define DAVIS_FX3_DEVICE_NAME "DAVIS FX3" 7 | 8 | #define DAVIS_FX3_DEVICE_VID 0x152A 9 | #define DAVIS_FX3_DEVICE_PID 0x841A 10 | #define DAVIS_FX3_DEVICE_DID_TYPE 0x01 11 | 12 | #define DAVIS_FX3_REQUIRED_LOGIC_REVISION 7449 13 | #define DAVIS_FX3_REQUIRED_FIRMWARE_VERSION 2 14 | 15 | #define DEBUG_ENDPOINT 0x81 16 | #define DEBUG_TRANSFER_NUM 4 17 | #define DEBUG_TRANSFER_SIZE 64 18 | 19 | struct davis_fx3_handle { 20 | // Common info and state structure (handle). 21 | struct davis_handle h; 22 | // Debug transfer support (FX3 only). 23 | struct libusb_transfer *debugTransfers[DEBUG_TRANSFER_NUM]; 24 | size_t activeDebugTransfers; 25 | }; 26 | 27 | typedef struct davis_fx3_handle *davisFX3Handle; 28 | 29 | caerDeviceHandle davisFX3Open(uint16_t deviceID, uint8_t busNumberRestrict, uint8_t devAddressRestrict, 30 | const char *serialNumberRestrict); 31 | bool davisFX3Close(caerDeviceHandle handle); 32 | 33 | bool davisFX3SendDefaultConfig(caerDeviceHandle handle); 34 | // Negative addresses are used for host-side configuration. 35 | // Positive addresses (including zero) are used for device-side configuration. 36 | bool davisFX3ConfigSet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t param); 37 | bool davisFX3ConfigGet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t *param); 38 | 39 | #endif /* LIBCAER_SRC_DAVIS_FX3_H_ */ 40 | -------------------------------------------------------------------------------- /libcaer/src/dvs128.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBCAER_SRC_DVS128_H_ 2 | #define LIBCAER_SRC_DVS128_H_ 3 | 4 | #include "devices/dvs128.h" 5 | #include "ringbuffer/ringbuffer.h" 6 | #include 7 | #include 8 | 9 | #ifdef HAVE_PTHREADS 10 | #include "c11threads_posix.h" 11 | #endif 12 | 13 | #define DVS_DEVICE_NAME "DVS128" 14 | 15 | #define DVS_DEVICE_VID 0x152A 16 | #define DVS_DEVICE_PID 0x8400 17 | #define DVS_DEVICE_DID_TYPE 0x00 18 | 19 | // #define DVS_REQUIRED_LOGIC_REVISION 1 20 | #define DVS_REQUIRED_FIRMWARE_VERSION 14 21 | 22 | #define DVS_ARRAY_SIZE_X 128 23 | #define DVS_ARRAY_SIZE_Y 128 24 | 25 | #define DVS_EVENT_TYPES 2 26 | 27 | #define DVS_POLARITY_DEFAULT_SIZE 4096 28 | #define DVS_SPECIAL_DEFAULT_SIZE 128 29 | 30 | #define DVS_DATA_ENDPOINT 0x86 31 | 32 | #define VENDOR_REQUEST_START_TRANSFER 0xB3 33 | #define VENDOR_REQUEST_STOP_TRANSFER 0xB4 34 | #define VENDOR_REQUEST_SEND_BIASES 0xB8 35 | #define VENDOR_REQUEST_RESET_TS 0xBB 36 | #define VENDOR_REQUEST_RESET_ARRAY 0xBD 37 | #define VENDOR_REQUEST_TS_MASTER 0xBE 38 | 39 | #define BIAS_NUMBER 12 40 | #define BIAS_LENGTH 3 41 | 42 | struct dvs128_state { 43 | // Data Acquisition Thread -> Mainloop Exchange 44 | RingBuffer dataExchangeBuffer; 45 | atomic_uint_fast32_t dataExchangeBufferSize; // Only takes effect on DataStart() calls! 46 | atomic_bool dataExchangeBlocking; 47 | atomic_bool dataExchangeStartProducers; 48 | atomic_bool dataExchangeStopProducers; 49 | void (*dataNotifyIncrease)(void *ptr); 50 | void (*dataNotifyDecrease)(void *ptr); 51 | void *dataNotifyUserPtr; 52 | void (*dataShutdownNotify)(void *ptr); 53 | void *dataShutdownUserPtr; 54 | // USB Device State 55 | char deviceThreadName[15 + 1]; // +1 for terminating NUL character. 56 | libusb_context *deviceContext; 57 | libusb_device_handle *deviceHandle; 58 | // USB Transfer Settings 59 | atomic_uint_fast32_t usbBufferNumber; 60 | atomic_uint_fast32_t usbBufferSize; 61 | // Data Acquisition Thread 62 | thrd_t dataAcquisitionThread; 63 | atomic_bool dataAcquisitionThreadRun; 64 | atomic_uint_fast32_t dataAcquisitionThreadConfigUpdate; 65 | struct libusb_transfer **dataTransfers; 66 | size_t dataTransfersLength; 67 | size_t activeDataTransfers; 68 | // Timestamp fields 69 | int32_t wrapOverflow; 70 | int32_t wrapAdd; 71 | int32_t lastTimestamp; 72 | int32_t currentTimestamp; 73 | // Packet Container state 74 | caerEventPacketContainer currentPacketContainer; 75 | atomic_int_fast32_t maxPacketContainerPacketSize; 76 | atomic_int_fast32_t maxPacketContainerInterval; 77 | int64_t currentPacketContainerCommitTimestamp; 78 | // Polarity Packet State 79 | caerPolarityEventPacket currentPolarityPacket; 80 | int32_t currentPolarityPacketPosition; 81 | // Special Packet State 82 | caerSpecialEventPacket currentSpecialPacket; 83 | int32_t currentSpecialPacketPosition; 84 | // Camera bias and settings memory (for getter operations) 85 | // TODO: replace with real device calls once DVS128 logic rewritten. 86 | uint8_t biases[BIAS_NUMBER][BIAS_LENGTH]; 87 | atomic_bool dvsRunning; 88 | atomic_bool dvsIsMaster; 89 | }; 90 | 91 | typedef struct dvs128_state *dvs128State; 92 | 93 | struct dvs128_handle { 94 | uint16_t deviceType; 95 | // Information fields 96 | struct caer_dvs128_info info; 97 | // State for data management. 98 | struct dvs128_state state; 99 | }; 100 | 101 | typedef struct dvs128_handle *dvs128Handle; 102 | 103 | caerDeviceHandle dvs128Open(uint16_t deviceID, uint8_t busNumberRestrict, uint8_t devAddressRestrict, 104 | const char *serialNumberRestrict); 105 | bool dvs128Close(caerDeviceHandle handle); 106 | 107 | bool dvs128SendDefaultConfig(caerDeviceHandle handle); 108 | // Negative addresses are used for host-side configuration. 109 | // Positive addresses (including zero) are used for device-side configuration. 110 | bool dvs128ConfigSet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t param); 111 | bool dvs128ConfigGet(caerDeviceHandle handle, int8_t modAddr, uint8_t paramAddr, uint32_t *param); 112 | 113 | bool dvs128DataStart(caerDeviceHandle handle, void (*dataNotifyIncrease)(void *ptr), 114 | void (*dataNotifyDecrease)(void *ptr), void *dataNotifyUserPtr, void (*dataShutdownNotify)(void *ptr), 115 | void *dataShutdownUserPtr); 116 | bool dvs128DataStop(caerDeviceHandle handle); 117 | caerEventPacketContainer dvs128DataGet(caerDeviceHandle handle); 118 | 119 | #endif /* LIBCAER_SRC_DVS128_H_ */ 120 | -------------------------------------------------------------------------------- /libcaer/src/log.c: -------------------------------------------------------------------------------- 1 | #include "libcaer.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static atomic_uint_fast8_t caerLogLevel = ATOMIC_VAR_INIT(CAER_LOG_ERROR); 8 | static atomic_int caerLogFileDescriptor1 = ATOMIC_VAR_INIT(STDERR_FILENO); 9 | static atomic_int caerLogFileDescriptor2 = ATOMIC_VAR_INIT(-1); 10 | 11 | void caerLogLevelSet(uint8_t logLevel) { 12 | atomic_store_explicit(&caerLogLevel, logLevel, memory_order_relaxed); 13 | } 14 | 15 | uint8_t caerLogLevelGet(void) { 16 | return (atomic_load_explicit(&caerLogLevel, memory_order_relaxed)); 17 | } 18 | 19 | void caerLogFileDescriptorsSet(int fd1, int fd2) { 20 | if (fd1 == fd2) { 21 | // If the same fd is passed twice, just disable it the second time. 22 | fd2 = -1; 23 | } 24 | 25 | atomic_store_explicit(&caerLogFileDescriptor1, fd1, memory_order_relaxed); 26 | atomic_store_explicit(&caerLogFileDescriptor2, fd2, memory_order_relaxed); 27 | } 28 | 29 | void caerLog(uint8_t logLevel, const char *subSystem, const char *format, ...) { 30 | // Check that subSystem and format are defined correctly. 31 | if (subSystem == NULL || format == NULL) { 32 | caerLog(CAER_LOG_ERROR, "Logger", "Missing subSystem or format strings. Neither can be NULL."); 33 | return; 34 | } 35 | 36 | // Only log messages if there is a destination (file-descriptor) to write them to. 37 | int logFileDescriptor1 = atomic_load_explicit(&caerLogFileDescriptor1, memory_order_relaxed); 38 | int logFileDescriptor2 = atomic_load_explicit(&caerLogFileDescriptor2, memory_order_relaxed); 39 | 40 | if (logFileDescriptor1 < 0 && logFileDescriptor2 < 0) { 41 | // Logging is disabled. 42 | return; 43 | } 44 | 45 | // Only log messages above the specified severity level. 46 | if (logLevel > atomic_load_explicit(&caerLogLevel, memory_order_relaxed)) { 47 | return; 48 | } 49 | 50 | // First prepend the time. 51 | time_t currentTimeEpoch = time(NULL); 52 | 53 | // From localtime_r() man-page: "According to POSIX.1-2004, localtime() 54 | // is required to behave as though tzset(3) was called, while 55 | // localtime_r() does not have this requirement." 56 | // So we make sure to call it here, to be portable. 57 | tzset(); 58 | 59 | #if defined(OS_WINDOWS) 60 | // localtime() is thread-safe on Windows (and there is no localtime_r() at all). 61 | struct tm *currentTime = localtime(¤tTimeEpoch); 62 | #else 63 | struct tm currentTimeStruct; 64 | struct tm *currentTime = ¤tTimeStruct; 65 | localtime_r(¤tTimeEpoch, currentTime); 66 | #endif 67 | 68 | // Following time format uses exactly 29 characters (8 separators/punctuation, 69 | // 4 year, 2 month, 2 day, 2 hours, 2 minutes, 2 seconds, 2 'TZ', 5 timezone). 70 | size_t currentTimeStringLength = 29; 71 | char currentTimeString[currentTimeStringLength + 1]; // + 1 for terminating NUL byte. 72 | strftime(currentTimeString, currentTimeStringLength + 1, "%Y-%m-%d %H:%M:%S (TZ%z)", currentTime); 73 | 74 | // Prepend debug level as a string to format. 75 | const char *logLevelString; 76 | switch (logLevel) { 77 | case CAER_LOG_EMERGENCY: 78 | logLevelString = "EMERGENCY"; 79 | break; 80 | 81 | case CAER_LOG_ALERT: 82 | logLevelString = "ALERT"; 83 | break; 84 | 85 | case CAER_LOG_CRITICAL: 86 | logLevelString = "CRITICAL"; 87 | break; 88 | 89 | case CAER_LOG_ERROR: 90 | logLevelString = "ERROR"; 91 | break; 92 | 93 | case CAER_LOG_WARNING: 94 | logLevelString = "WARNING"; 95 | break; 96 | 97 | case CAER_LOG_NOTICE: 98 | logLevelString = "NOTICE"; 99 | break; 100 | 101 | case CAER_LOG_INFO: 102 | logLevelString = "INFO"; 103 | break; 104 | 105 | case CAER_LOG_DEBUG: 106 | logLevelString = "DEBUG"; 107 | break; 108 | 109 | default: 110 | logLevelString = "UNKNOWN"; 111 | break; 112 | } 113 | 114 | // Copy all strings into one and ensure NUL termination. 115 | size_t logLength = (size_t) snprintf(NULL, 0, "%s: %s: %s: %s\n", currentTimeString, logLevelString, subSystem, 116 | format); 117 | char logString[logLength + 1]; 118 | snprintf(logString, logLength + 1, "%s: %s: %s: %s\n", currentTimeString, logLevelString, subSystem, format); 119 | 120 | va_list argptr; 121 | 122 | if (logFileDescriptor1 >= 0) { 123 | va_start(argptr, format); 124 | #if defined(OS_WINDOWS) 125 | FILE *logFilePointer1 = fdopen(logFileDescriptor1, "a"); 126 | vfprintf(logFilePointer1, logString, argptr); 127 | #else 128 | vdprintf(logFileDescriptor1, logString, argptr); 129 | #endif 130 | va_end(argptr); 131 | } 132 | 133 | if (logFileDescriptor2 >= 0) { 134 | va_start(argptr, format); 135 | #if defined(OS_WINDOWS) 136 | FILE *logFilePointer2 = fdopen(logFileDescriptor2, "a"); 137 | vfprintf(logFilePointer2, logString, argptr); 138 | #else 139 | vdprintf(logFileDescriptor2, logString, argptr); 140 | #endif 141 | va_end(argptr); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /libcaer/src/ringbuffer/portable_aligned_alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTABLE_ALIGNED_ALLOC_H_ 2 | #define PORTABLE_ALIGNED_ALLOC_H_ 3 | 4 | #if (!defined(__APPLE__) && !defined(_WIN32) && (__STDC_VERSION__ >= 201112L || defined(_ISOC11_SOURCE))) 5 | #include 6 | 7 | static inline void *portable_aligned_alloc(size_t alignment, size_t size) { 8 | return (aligned_alloc(alignment, size)); 9 | } 10 | #elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) 11 | #include 12 | 13 | static inline void *portable_aligned_alloc(size_t alignment, size_t size) { 14 | void* mem; 15 | 16 | if (posix_memalign(&mem, alignment, size) == 0) { 17 | // Success! 18 | return (mem); 19 | } 20 | 21 | // Failure. 22 | return (NULL); 23 | } 24 | #elif defined(_WIN32) || defined(__CYGWIN__) 25 | #include 26 | 27 | static inline void *portable_aligned_alloc(size_t alignment, size_t size) { 28 | return (_aligned_malloc(size, alignment)); 29 | } 30 | #else 31 | #error "No portable way of getting aligned memory found." 32 | #endif 33 | 34 | #endif /* PORTABLE_ALIGNED_ALLOC_H_ */ 35 | -------------------------------------------------------------------------------- /libcaer/src/ringbuffer/ringbuffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ringbuffer.c 3 | * 4 | * Created on: Dec 10, 2013 5 | * Author: llongi 6 | */ 7 | 8 | #include "ringbuffer.h" 9 | #include "portable_aligned_alloc.h" 10 | #include 11 | #include // To get alignas() macro. 12 | 13 | // Alignment specification support (with defines for cache line alignment). 14 | #undef CACHELINE_ALIGNED 15 | #undef CACHELINE_ALONE 16 | 17 | #if !defined(CACHELINE_SIZE) 18 | #define CACHELINE_SIZE 64 // Default (big enough for almost all processors). 19 | // Must be power of two! 20 | #endif 21 | 22 | #define CACHELINE_ALIGNED alignas(CACHELINE_SIZE) 23 | #define CACHELINE_ALONE(t, v) CACHELINE_ALIGNED t v; uint8_t PAD_##v[CACHELINE_SIZE - (sizeof(t) & (CACHELINE_SIZE - 1))] 24 | 25 | struct ring_buffer { 26 | CACHELINE_ALONE(size_t, putPos); 27 | CACHELINE_ALONE(size_t, getPos); 28 | CACHELINE_ALONE(size_t, size); 29 | atomic_uintptr_t elements[]; 30 | }; 31 | 32 | RingBuffer ringBufferInit(size_t size) { 33 | // Force multiple of two size for performance. 34 | if (size == 0 || (size & (size - 1)) != 0) { 35 | return (NULL); 36 | } 37 | 38 | RingBuffer rBuf = portable_aligned_alloc(CACHELINE_SIZE, 39 | sizeof(struct ring_buffer) + (size * sizeof(atomic_uintptr_t))); 40 | if (rBuf == NULL) { 41 | return (NULL); 42 | } 43 | 44 | // Initialize counter variables. 45 | rBuf->putPos = 0; 46 | rBuf->getPos = 0; 47 | rBuf->size = size; 48 | 49 | // Initialize pointers. 50 | for (size_t i = 0; i < size; i++) { 51 | atomic_store_explicit(&rBuf->elements[i], (uintptr_t) NULL, memory_order_relaxed); 52 | } 53 | 54 | atomic_thread_fence(memory_order_release); 55 | 56 | return (rBuf); 57 | } 58 | 59 | void ringBufferFree(RingBuffer rBuf) { 60 | free(rBuf); 61 | } 62 | 63 | bool ringBufferPut(RingBuffer rBuf, void *elem) { 64 | if (elem == NULL) { 65 | // NULL elements are disallowed (used as place-holders). 66 | // Critical error, should never happen -> exit! 67 | exit(EXIT_FAILURE); 68 | } 69 | 70 | void *curr = (void *) atomic_load_explicit(&rBuf->elements[rBuf->putPos], memory_order_acquire); 71 | 72 | // If the place where we want to put the new element is NULL, it's still 73 | // free and we can use it. 74 | if (curr == NULL) { 75 | atomic_store_explicit(&rBuf->elements[rBuf->putPos], (uintptr_t ) elem, memory_order_release); 76 | 77 | // Increase local put pointer. 78 | rBuf->putPos = ((rBuf->putPos + 1) & (rBuf->size - 1)); 79 | 80 | return (true); 81 | } 82 | 83 | // Else, buffer is full. 84 | return (false); 85 | } 86 | 87 | void *ringBufferGet(RingBuffer rBuf) { 88 | void *curr = (void *) atomic_load_explicit(&rBuf->elements[rBuf->getPos], memory_order_acquire); 89 | 90 | // If the place where we want to get an element from is not NULL, there 91 | // is valid content there, which we return, and reset the place to NULL. 92 | if (curr != NULL) { 93 | atomic_store_explicit(&rBuf->elements[rBuf->getPos], (uintptr_t) NULL, memory_order_release); 94 | 95 | // Increase local get pointer. 96 | rBuf->getPos = ((rBuf->getPos + 1) & (rBuf->size - 1)); 97 | 98 | return (curr); 99 | } 100 | 101 | // Else, buffer is empty. 102 | return (NULL); 103 | } 104 | 105 | void *ringBufferLook(RingBuffer rBuf) { 106 | void *curr = (void *) atomic_load_explicit(&rBuf->elements[rBuf->getPos], memory_order_acquire); 107 | 108 | // If the place where we want to get an element from is not NULL, there 109 | // is valid content there, which we return, without removing it from the 110 | // ring buffer. 111 | if (curr != NULL) { 112 | return (curr); 113 | } 114 | 115 | // Else, buffer is empty. 116 | return (NULL); 117 | } 118 | -------------------------------------------------------------------------------- /libcaer/src/ringbuffer/ringbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ringbuffer.h 3 | * 4 | * Created on: Dec 10, 2013 5 | * Author: llongi 6 | */ 7 | 8 | #ifndef RINGBUFFER_H_ 9 | #define RINGBUFFER_H_ 10 | 11 | // Common includes, useful for everyone. 12 | #include 13 | #include 14 | #include 15 | 16 | typedef struct ring_buffer *RingBuffer; 17 | 18 | RingBuffer ringBufferInit(size_t size); 19 | void ringBufferFree(RingBuffer rBuf); 20 | bool ringBufferPut(RingBuffer rBuf, void *elem); 21 | void *ringBufferGet(RingBuffer rBuf); 22 | void *ringBufferLook(RingBuffer rBuf); 23 | 24 | #endif /* RINGBUFFER_H_ */ 25 | -------------------------------------------------------------------------------- /libcaer_catkin/65-inilabs.rules: -------------------------------------------------------------------------------- 1 | # All DVS/DAVIS systems 2 | 3 | SUBSYSTEM=="usb", ATTR{idVendor}=="152a", ATTR{idProduct}=="84[0-1]?", MODE="0666" 4 | -------------------------------------------------------------------------------- /libcaer_catkin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(libcaer_catkin) 3 | 4 | find_package(catkin_simple REQUIRED) 5 | 6 | catkin_simple() 7 | 8 | include(ExternalProject) 9 | 10 | file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/libcaer) 11 | 12 | ExternalProject_Add(libcaer_src 13 | GIT_REPOSITORY https://github.com/inilabs/libcaer.git 14 | GIT_TAG 57466910da84c25231aab57e99f246239722a628 15 | UPDATE_COMMAND "" 16 | CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CATKIN_DEVEL_PREFIX} -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_LIBDIR=${CATKIN_DEVEL_PREFIX}/lib 17 | BUILD_COMMAND make 18 | INSTALL_COMMAND make install 19 | ) 20 | 21 | cs_install() 22 | install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/libcaer 23 | DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION} 24 | FILES_MATCHING 25 | PATTERN "*.h" 26 | PATTERN ".svn" EXCLUDE 27 | ) 28 | 29 | cs_export(INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include/libcaer/ 30 | CFG_EXTRAS libcaer-extras.cmake) 31 | -------------------------------------------------------------------------------- /libcaer_catkin/cmake/libcaer-extras.cmake: -------------------------------------------------------------------------------- 1 | # This overrides the dependency tracker with the caer library file. 2 | set(@PROJECT_NAME@_LIBRARIES 3 | @CATKIN_DEVEL_PREFIX@/lib/libcaer${CMAKE_SHARED_LIBRARY_SUFFIX}) 4 | set(@PROJECT_NAME@_INCLUDE_DIR @CATKIN_DEVEL_PREFIX@/include) 5 | -------------------------------------------------------------------------------- /libcaer_catkin/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Copying udev rule (needs root privileges)." 3 | sudo cp 65-inilabs.rules /etc/udev/rules.d/ 4 | 5 | echo "Reloading udev rules." 6 | sudo udevadm control --reload-rules 7 | sudo udevadm trigger 8 | 9 | echo "Done!" 10 | -------------------------------------------------------------------------------- /libcaer_catkin/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | libcaer_catkin 4 | 0.0.0 5 | The libcaer_catkin package 6 | Elias Mueggler 7 | GNU GPL 8 | 9 | catkin 10 | catkin_simple 11 | 12 | --------------------------------------------------------------------------------