I use pointpillars for object detection on pointcloud data (https://github.com/shangjie-li/pointpillars/tree/master). I have successfully trained and tested the deep network.
I would like to run the deep learning code (execute test.py
and demo.py
) in a Ros2 node (Ubuntu 22.04, Ros2 Humble). I created a Ros2 python subscriber (pc_subscriber.py
, setup.py
, package.xml
). I copied all files from pointpillars to the same folder of pc_subscriber.py
. Also, I have removed all imported python modules from test.py
and demo.py
and put them in pc_subscriber.py
(code below between two hash lines). However, it seems the Ros node can not import these python codes/modules which are located in different folders/subfolders and I get error (for example :
from . import iou3d_nms_cuda
ImportError: cannot import name 'iou3d_nms_cuda' from 'ops.iou3d_nms' (unknown location)
). I do not know where to locate the deep learning folders/subfolders and also how to modify pc_subscriber.py
, setup.py
, and package.xml
in this regard. How can I solve this issue?
I appreciate any help in advance.
Thanks,
Abbas
pc_subscriber.py
import rclpy
from rclpy.qos import QoSProfile, QoSReliabilityPolicy, QoSHistoryPolicy
import sensor_msgs_py.point_cloud2 as pc2
import struct
from sensor_msgs.msg import PointCloud2, PointField
import numpy as np
import open3d as o3d
import ctypes
import shutil
import numpy as np
import glob
import os
import subprocess
from subprocess import call
import argparse
import datetime
import glob
import os
import re
import time
from pathlib import Path
import numpy as np
import torch
from tensorboardX import SummaryWriter
###############################################################################
# from .data import cfg, cfg_from_list, cfg_from_yaml_file, log_config_to_file
# from .data import build_dataloader
# from .utils import common_utils
# from .utils import eval_utils
# from .data import KittiDataset
# from .pointpillar import build_network, load_data_to_gpu
###############################################################################
source_folder = r'/home/abbas/pointpillars-master1/Bin_data/'
destination_folder = r'/home/abbas/pointpillars-master1/data/kitti/training/velodyne/'
source_pd_labels= r'/home/abbas/pointpillars-master1/output/eval/epoch_150/val/final_result/data/'
destination_pd_labels= r'/home/abbas/pointpillars-master1/Predicted_labels/'
j=0
def callback(msg):
# Save pointclou data as bin files
global j
xyz_intensity = []
gen = pc2.read_points(msg, field_names=("x", "y", "z", "intensity"), skip_nans=True)
int_data = list(gen)
for x in int_data:
# Extract x, y, z, intensity values
point = [x[0], x[1], x[2], x[3]]
xyz_intensity.append(point)
# Convert to NumPy array
xyz_intensity = np.array(xyz_intensity, dtype=np.float32)
# Save as BIN file
bin_file_name = "/home/abbas/pointpillars-master1/Bin_data/{:06d}.bin".format(j)
with open(bin_file_name, "wb") as bin_file:
for point in xyz_intensity:
# Pack x, y, z, intensity values into binary format
packed_data = struct.pack('ffff', *point)
bin_file.write(packed_data)
#Copy the bin files to velodyn folder for prediction
source = bin_file_name
destination = destination_folder + '000001.bin'
if os.path.isfile(source):
shutil.copy(source, destination)
#Predict the labels and save them (inference)
exec(open('/home/abbas/DeepLearning_ws/src/dl_bd/dl_bd/test.py').read())
#save the predicted labels
sourceLabel = source_pd_labels +'000001.txt'
destinationLabel = "/home/abbas/pointpillars-master1/Predicted_labels/{:06d}.txt".format(j)
if os.path.isfile(sourceLabel):
shutil.copy(sourceLabel, destinationLabel)
# show the detected objects (demo)
exec(open('/home/abbas/DeepLearning_ws/src/dl_bd/dl_bd/demo.py').read())
j += 1 # Increment j for the next file
def main(args=None):
rclpy.init(args=args)
node = rclpy.create_node('bin_converter')
qos_profile = QoSProfile(
reliability=QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT,
history=QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST,
depth=1
)
subscription = node.create_subscription(
PointCloud2,
#'/ouster_front/points',
'/ouster_front/filtered_obstacle_points',
callback,
qos_profile=qos_profile
)
subscription # Prevent unused variable warning
print("Listening for PointCloud2 messages...")
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
setup.py
from setuptools import find_packages, setup
package_name = 'dl_bd'
setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
data_files=[ ('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='abbas',
maintainer_email='ToDo',
description='Deep learning node for 3d object detection',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'listener = dl_bd.pc_subscriber:main',
],
},
)
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>dl_bd</name>
<version>0.0.0</version>
<description>Deep learning node for 3d object detection</description>
<maintainer email="ToDo">abbas</maintainer>
<license>Apache License 2.0</license>
<depend>ros2cli</depend>
<exec_depend>ament_index_python</exec_depend>
<exec_depend>python3-empy</exec_depend>
<exec_depend>python3-pkg-resources</exec_depend>
<exec_depend>rclpy</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>sensor_msgs_py</exec_depend>
<exec_depend>tensorboardX</exec_depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>