0
$\begingroup$

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>
$\endgroup$

1 Answer 1

0
$\begingroup$

I copied all files from pointpillars to the same folder of pc_subscriber.py.

Since it's a library it would be best not to copy the files in your module and instead install it on your system.

Following the instructions in the readme should get you most of the way there, but I would replace python setup.py develop with pip install --user . since you're not interested in modifying the library itself.

This should add the module to python's search path by installing it in your user package directory (typically ~/.local/lib/python3.10/site-packages, you can find it with python -m site --user-site). If ROS still can't find the package you may need to add its location manually to your PYTHONPATH environment variable.

$\endgroup$
8
  • $\begingroup$ Thank you for your suggestion. I have already used the procedure in readme to run pointpillars on an anaconda's environment. If I understood your comment correctly, I need to follow the procedure and install pointpillars with its dependencies in Ros2 environment using pip install --user. Am I right? My second question is, can I create a new anaconda environment in Ros2 and install all dependencies for pointpillars? In this case, should I use python setup.py develop or pip install --user? $\endgroup$
    – Abbas
    Commented Feb 27 at 16:53
  • $\begingroup$ I git cloned pointpillars and installed its dependencies. In Ros2 (bash source ros package), changed directory to pointpillars folder, then updated setuptools==60.7.0 and used python3 -m pip install --user -e . found in this link (github.com/open-mmlab/OpenPCDet/issues/782). But I got this error: note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for numpy Failed to build numpy ERROR: Could not build wheels for numpy, which is required to install pyproject.toml-based projects . Is this way correct? $\endgroup$
    – Abbas
    Commented Feb 27 at 20:55
  • $\begingroup$ @Abbas python setup.py develop and the -e argument to pip will build pointpillars in the current folder for developing and testing that package, whereas pip install --user will build it and install it in a place where it will be found even if you're not running from inside the pointpillars folder. Running pip from inside an anaconda environment should work fine. $\endgroup$
    – Xilef11
    Commented Feb 28 at 15:41
  • $\begingroup$ Thank you for your help. I bashed source Ros2 package, cd pointpillars folder, then pip install --user . , but I got this error: note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for numpy Failed to build ops numpy ERROR: Could not build wheels for numpy, which is required to install pyproject.toml-based projects I have installed numpy. Am I missing something? I am sorry for lots of questions since I am new using Ros2 and really stuck to solve this issue. $\endgroup$
    – Abbas
    Commented Feb 28 at 17:41
  • $\begingroup$ @Abbas This looks like a problem with your numpy version/installation. Based on the setup.py, ops requires 'numpy<=1.20'. Did you change your environment between testing pointpillars and trying to install it? Maybe also look at the documentation for setuptools $\endgroup$
    – Xilef11
    Commented Feb 29 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.