diff --git a/ifm3d_ros_driver/CMakeLists.txt b/ifm3d_ros_driver/CMakeLists.txt index 78ccdb0..634c40c 100644 --- a/ifm3d_ros_driver/CMakeLists.txt +++ b/ifm3d_ros_driver/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(catkin REQUIRED COMPONENTS ifm3d_ros_msgs ) -catkin_python_setup() +# catkin_python_setup() option(CATKIN_ENABLE_TESTING "Build tests" OFF) diff --git a/ifm3d_ros_driver/doc/dump_and_config.md b/ifm3d_ros_driver/doc/dump_and_config.md index 9439bcf..5ca1094 100644 --- a/ifm3d_ros_driver/doc/dump_and_config.md +++ b/ifm3d_ros_driver/doc/dump_and_config.md @@ -18,187 +18,63 @@ Per camera head connected to the visual processing unit (VPU) of the O3R platfor As you can see the two services `Dump` and `Config` are also part of this list. ### Dump -Call this service via, e.g. for camera1: +Calling the native rosservice `/ifm3d_ros_examples/camera/Dump` for a certain `camera` will return a string containing with the camera configuration as a JSON string. Please notice the use of backslashes (`\` before each `"`) to esacpe each upper quotation mark. This is necessary to allow us to keep the JSON syntax native to the underlying API (ifm3d). + +>Note: We have mapped some camera configurations to native rosservice calls to make their handling easier, e.g. `rosservice call /ifm3d_ros_examples/camera/SoftOn`. If you think you will benefit from similar rosservices, please let us know so we can add more comfort handling. + +Call this service via, e.g. for camera: ``` -$ rosservice call /ifm3d_ros_examples/camera1/Dump +$ rosservice call /ifm3d_ros_examples/camera/Dump status: 0 -{ - "device": { - "clock": { - "currentTime": 1581193835185485800 - }, - "diagnostic": { - "temperatures": [], - "upTime": 103190000000000 - }, - "info": { - "device": "0301", - "deviceTreeBinaryBlob": "tegra186-quill-p3310-1000-c03-00-base.dtb", - "features": {}, - "name": "", - " partNumber": "M03975", - "productionState": "AA", - "serialNumber": "000201234160", - "vendor": "0001" - }, - "network": { - "authorized_keys": "", - "ipAddressConfig": 0, - "macEth0": "00:04:4B:EA:9F:0E", - "macEth1": "00:02:01:23:41:60", - "networkSpeed": 1000, - "staticIPv4Address": "192.168.0.69", - "staticIPv4Gateway": "192.168.0.201", - "staticIPv4SubNetMask": "255.255.255.0", - "useDHCP": false - }, - "state": { - "errorMessage": "", - "errorNumber": "" - }, - "swVersion": { - "kernel": "4.9.140-l4t-r32.4+gc35f5eb9d1d9", - "l4t": "r32.4.3", - "os": "0.13.13-221", - "schema": "v0.1.0", - "swu": "0.15.12" - } - }, - "ports": { - "port0": { - "acquisition": { - "framerate": 10, - "version": { - "major": 0, - "minor": 0, - "patch": 0 - } - }, - "data": { - "algoDebugConfig": {}, - "availablePCICOutput": [], - "pcicTCPPort": 50010 - }, - "info": { - "device": "2301", - "deviceTreeBinaryBlobOverlay": "001-ov9782.dtbo", - "features": { - "fov": { - "horizontal": 127, - "vertical": 80 - }, - " resolution": { - "height": 800, - "width": 1280 - }, - "type": "2D" - }, - "name": "", - "partNumber": "M03969", - "productionState": "AA", - "sensor": "OV9782", - "sensorID": "OV9782_127x80_noIllu_Csample", - "serialNumber": "000000000382", - "vendor": "0001" - }, - "mode": "experimental_autoexposure2D", - "processing": { - "extrinsicHeadToUser": { - "rotX": 0, - "rotY": 0, - "rotZ": 0, - " transX": 0, - "transY": 0, - "transZ": 0 - }, - "version": { - "major": 0, - "minor": 0, - " patch": 0 - } - }, - "state": "RUN" - }, - "port2": { - "acquisition": { - "exposureLong": 5000, - " exposureShort": 400, - "framerate": 10, - "offset": 0, - "version": { - "major": 0, - " minor": 0, - "patch": 0 - } - }, - "data": { - "algoDebugConfig": {}, - "availablePCICOutput": [], - "pcicTCPPort": 50012 - }, - "info": { - "device": "3101", - "deviceTreeBinaryBlobOverlay": "001-irs2381c.dtbo", - "features": { - "fov": { - "horizontal": 105, - "vertical": 78 - }, - " resolution": { - "height": 172, - "width": 224 - }, - "type": "3D" - }, - "name": "", - "partNumber": "M03969", - "productionState": "AA", - "sensor": "IRS2381C", - "sensorID": "IRS2381C_105x78_4x2W_110x90_C7", - "serialNumber": "000000000382", - "vendor": "0001" - }, - "mode": "standard_range4m", - "processing": { - "diParam": { - "anfFilterSizeDiv2": 2, - "enableDynamicSymmetry": true, - "enableStraylight": true, - "enableTemporalFilter": true, - "excessiveCorrectionThreshAmp": 0.3, - "excessiveCorrectionThreshDist": 0.08, - "maxDistNoise": 0.02, - "maxSymmetry": 0.4, - "medianSizeDiv2": 0, - "minAmplitude": 20, - "minReflectivity": 0, - "mixedPixelFilterMode": 1, - "mixedPixelThresholdRad": 0.15 - }, - "extrinsicHeadToUser": { - "rotX": 1, - "rotY": 0, - "rotZ": 0, - "transX": 100, - "transY": 0, - "transZ": 0 - }, - "version": { - " major": 0, - "minor": 0, - "patch": 0 - } - }, - "state": "RUN" - } - } -} +config: "{\"device\":{\"clock\":{\"currentTime\":1581287336449588512},\"diagnostic\":{\"temperatures\"\ + :[],\"upTime\":196692000000000},\"info\":{\"device\":\"0301\",\"deviceTreeBinaryBlob\"\ + :\"tegra186-quill-p3310-1000-c03-00-base.dtb\",\"features\":{},\"name\":\"test\"\ + ,\"partNumber\":\"M03975\",\"productionState\":\"AA\",\"serialNumber\":\"000201234160\"\ + ,\"vendor\":\"0001\"},\"network\":{\"authorized_keys\":\"\",\"ipAddressConfig\"\ + :0,\"macEth0\":\"00:04:4B:EA:9F:0E\",\"macEth1\":\"00:02:01:23:41:60\",\"networkSpeed\"\ + :1000,\"staticIPv4Address\":\"192.168.0.69\",\"staticIPv4Gateway\":\"192.168.0.201\"\ + ,\"staticIPv4SubNetMask\":\"255.255.255.0\",\"useDHCP\":false},\"state\":{\"errorMessage\"\ + :\"\",\"errorNumber\":\"\"},\"swVersion\":{\"kernel\":\"4.9.140-l4t-r32.4+gc35f5eb9d1d9\"\ + ,\"l4t\":\"r32.4.3\",\"os\":\"0.13.13-221\",\"schema\":\"v0.1.0\",\"swu\":\"0.15.12\"\ + }},\"ports\":{\"port0\":{\"acquisition\":{\"framerate\":10.0,\"version\":{\"major\"\ + :0,\"minor\":0,\"patch\":0}},\"data\":{\"algoDebugConfig\":{},\"availablePCICOutput\"\ + :[],\"pcicTCPPort\":50010},\"info\":{\"device\":\"2301\",\"deviceTreeBinaryBlobOverlay\"\ + :\"001-ov9782.dtbo\",\"features\":{\"fov\":{\"horizontal\":127,\"vertical\":80},\"\ + resolution\":{\"height\":800,\"width\":1280},\"type\":\"2D\"},\"name\":\"\",\"partNumber\"\ + :\"M03969\",\"productionState\":\"AA\",\"sensor\":\"OV9782\",\"sensorID\":\"OV9782_127x80_noIllu_Csample\"\ + ,\"serialNumber\":\"000000000382\",\"vendor\":\"0001\"},\"mode\":\"experimental_autoexposure2D\"\ + ,\"processing\":{\"extrinsicHeadToUser\":{\"rotX\":0.0,\"rotY\":0.0,\"rotZ\":0.0,\"\ + transX\":0.0,\"transY\":0.0,\"transZ\":0.0},\"version\":{\"major\":0,\"minor\":0,\"\ + patch\":0}},\"state\":\"RUN\"},\"port2\":{\"acquisition\":{\"exposureLong\":5000,\"\ + exposureShort\":400,\"framerate\":10.0,\"offset\":0.0,\"version\":{\"major\":0,\"\ + minor\":0,\"patch\":0}},\"data\":{\"algoDebugConfig\":{},\"availablePCICOutput\"\ + :[],\"pcicTCPPort\":50012},\"info\":{\"device\":\"3101\",\"deviceTreeBinaryBlobOverlay\"\ + :\"001-irs2381c.dtbo\",\"features\":{\"fov\":{\"horizontal\":105,\"vertical\":78},\"\ + resolution\":{\"height\":172,\"width\":224},\"type\":\"3D\"},\"name\":\"\",\"partNumber\"\ + :\"M03969\",\"productionState\":\"AA\",\"sensor\":\"IRS2381C\",\"sensorID\":\"IRS2381C_105x78_4x2W_110x90_C7\"\ + ,\"serialNumber\":\"000000000382\",\"vendor\":\"0001\"},\"mode\":\"standard_range2m\"\ + ,\"processing\":{\"diParam\":{\"anfFilterSizeDiv2\":2,\"enableDynamicSymmetry\"\ + :true,\"enableStraylight\":true,\"enableTemporalFilter\":true,\"excessiveCorrectionThreshAmp\"\ + :0.3,\"excessiveCorrectionThreshDist\":0.08,\"maxDistNoise\":0.02,\"maxSymmetry\"\ + :0.4,\"medianSizeDiv2\":0,\"minAmplitude\":20.0,\"minReflectivity\":0.0,\"mixedPixelFilterMode\"\ + :1,\"mixedPixelThresholdRad\":0.15},\"extrinsicHeadToUser\":{\"rotX\":0.0,\"rotY\"\ + :0.0,\"rotZ\":0.0,\"transX\":0.0,\"transY\":0.0,\"transZ\":0.0},\"version\":{\"\ + major\":0,\"minor\":0,\"patch\":0}},\"state\":\"RUN\"}}}" ``` ## Config Below you can see an example on how to configure your camera via a rosservice call. The JSON string can be a partial JSON string. It only needs to follow basic JSON syntax. ``` -rosservice call /ifm3d_ros_examples/camera2/Config "json: '{"ports": {"port2": {"state": "RUN"}}}'" +$ rosservice call /ifm3d_ros_examples/camera/Config "json: '{\"ports\":{\"port2\":{\"mode\":\"standard_range2m\"}}}'" +status: 0 +msg: "OK" +``` + +This is equivalent to: +``` +$ rosservice call /ifm3d_ros_examples/camera/Config '"{\"ports\":{\"port2\":{\"mode\":\"standard_range2m\"}}}"' +status: 0 +msg: "OK" ``` @@ -211,7 +87,10 @@ They are part of the `ifm3d_ros_msgs` subpackage, so if you can't access them pl For example, to dump the state of the camera: (exemplary output from an O3R perception platform with one camera head connected is shown) +>Note: The service proxying only works on the `/ifm3d_ros_examples/camera/` namespace at the moment. + ``` +$ roslaunch ifm3d_ros_examples camera.launch & $ rosrun ifm3d_ros_msgs dump { "device": { diff --git a/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_ConfigClient.cpython-38.pyc b/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_ConfigClient.cpython-38.pyc deleted file mode 100644 index 5630c50..0000000 Binary files a/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_ConfigClient.cpython-38.pyc and /dev/null differ diff --git a/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_DumpClient.cpython-38.pyc b/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_DumpClient.cpython-38.pyc deleted file mode 100644 index 92db5cf..0000000 Binary files a/ifm3d_ros_driver/pylib/ifm3d/__pycache__/_DumpClient.cpython-38.pyc and /dev/null differ diff --git a/ifm3d_ros_driver/src/camera_nodelet.cpp b/ifm3d_ros_driver/src/camera_nodelet.cpp index a7bc321..bd4d7e6 100644 --- a/ifm3d_ros_driver/src/camera_nodelet.cpp +++ b/ifm3d_ros_driver/src/camera_nodelet.cpp @@ -183,7 +183,7 @@ bool ifm3d_ros::CameraNodelet::Config(ifm3d_ros_msgs::Config::Request& req, ifm3 try { - this->cam_->FromJSON(req.json); + this->cam_->FromJSON(json::parse(req.json)); } catch (const ifm3d::error_t& ex) { diff --git a/ifm3d_ros_examples/launch/four_cameras.launch b/ifm3d_ros_examples/launch/four_cameras.launch index 3a82ca4..6ee2d6f 100644 --- a/ifm3d_ros_examples/launch/four_cameras.launch +++ b/ifm3d_ros_examples/launch/four_cameras.launch @@ -1,6 +1,6 @@ - + diff --git a/ifm3d_ros_examples/launch/six_cameras.launch b/ifm3d_ros_examples/launch/six_cameras.launch index ca81835..b8a2807 100644 --- a/ifm3d_ros_examples/launch/six_cameras.launch +++ b/ifm3d_ros_examples/launch/six_cameras.launch @@ -8,6 +8,8 @@ + + @@ -86,7 +88,7 @@ - + @@ -101,7 +103,7 @@ - + @@ -117,38 +119,38 @@ diff --git a/ifm3d_ros_msgs/CMakeLists.txt b/ifm3d_ros_msgs/CMakeLists.txt index 0091b92..df3e3f0 100644 --- a/ifm3d_ros_msgs/CMakeLists.txt +++ b/ifm3d_ros_msgs/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(catkin REQUIRED COMPONENTS ####################################### ## Declare ROS messages and services ## ####################################### +catkin_python_setup() add_message_files( DIRECTORY msg diff --git a/ifm3d_ros_msgs/bin/config b/ifm3d_ros_msgs/bin/config index ac5c29c..470fb17 100755 --- a/ifm3d_ros_msgs/bin/config +++ b/ifm3d_ros_msgs/bin/config @@ -6,7 +6,7 @@ import sys -from ifm3d import ConfigClient +from ifm3d_ros_utils import ConfigClient if __name__ == '__main__': sys.exit(ConfigClient().run()) diff --git a/ifm3d_ros_msgs/bin/dump b/ifm3d_ros_msgs/bin/dump index 2fd1789..396285c 100755 --- a/ifm3d_ros_msgs/bin/dump +++ b/ifm3d_ros_msgs/bin/dump @@ -6,7 +6,7 @@ import sys -from ifm3d import DumpClient +from ifm3d_ros_utils import DumpClient if __name__ == '__main__': sys.exit(DumpClient().run()) diff --git a/ifm3d_ros_driver/setup.py b/ifm3d_ros_msgs/setup.py similarity index 73% rename from ifm3d_ros_driver/setup.py rename to ifm3d_ros_msgs/setup.py index 3a020c2..412b54b 100644 --- a/ifm3d_ros_driver/setup.py +++ b/ifm3d_ros_msgs/setup.py @@ -3,8 +3,8 @@ # reads package.xml setup_args = generate_distutils_setup( - packages=['ifm3d'], - package_dir={'': 'pylib'}, + packages=['ifm3d_ros_utils'], + package_dir={'': 'utils'}, ) setup(**setup_args) diff --git a/ifm3d_ros_driver/pylib/ifm3d/_ConfigClient.py b/ifm3d_ros_msgs/utils/ifm3d_ros_utils/_ConfigClient.py similarity index 88% rename from ifm3d_ros_driver/pylib/ifm3d/_ConfigClient.py rename to ifm3d_ros_msgs/utils/ifm3d_ros_utils/_ConfigClient.py index f4cf455..1f5fbe1 100644 --- a/ifm3d_ros_driver/pylib/ifm3d/_ConfigClient.py +++ b/ifm3d_ros_msgs/utils/ifm3d_ros_utils/_ConfigClient.py @@ -9,10 +9,10 @@ import json import rospy import sys -from ifm3d.srv import Config +from ifm3d_ros_msgs.srv import Config SRV_TIMEOUT = 2.0 # seconds -SRV_NAME = "/ifm3d/camera/Config" +SRV_NAME = "/ifm3d_ros_examples/camera/Config" class ConfigClient(object): diff --git a/ifm3d_ros_driver/pylib/ifm3d/_DumpClient.py b/ifm3d_ros_msgs/utils/ifm3d_ros_utils/_DumpClient.py similarity index 91% rename from ifm3d_ros_driver/pylib/ifm3d/_DumpClient.py rename to ifm3d_ros_msgs/utils/ifm3d_ros_utils/_DumpClient.py index b16941a..3b45a8f 100644 --- a/ifm3d_ros_driver/pylib/ifm3d/_DumpClient.py +++ b/ifm3d_ros_msgs/utils/ifm3d_ros_utils/_DumpClient.py @@ -8,10 +8,10 @@ import json import rospy import sys -from ifm3d.srv import Dump +from ifm3d_ros_msgs.srv import Dump SRV_TIMEOUT = 2.0 # seconds -SRV_NAME = "/ifm3d/camera/Dump" +SRV_NAME = "/ifm3d_ros_examples/camera/Dump" class DumpClient(object): diff --git a/ifm3d_ros_driver/pylib/ifm3d/__init__.py b/ifm3d_ros_msgs/utils/ifm3d_ros_utils/__init__.py similarity index 100% rename from ifm3d_ros_driver/pylib/ifm3d/__init__.py rename to ifm3d_ros_msgs/utils/ifm3d_ros_utils/__init__.py