toppers / hakoniwa-unity-simasset-plugin

A plugin for Unity to easily integrate assets into hakoniwa simulation environment.
2 stars 1 forks source link

3DLiDARを追加して欲しい #22

Closed tmori closed 5 months ago

tmori commented 5 months ago

基本Spec

tmori commented 5 months ago

データ型

PointCloud2 を使う。

std_msgs/Header header

# 2D structure of the point cloud. If the cloud is unordered, height is
# 1 and width is the length of the point cloud.
uint32 height
uint32 width

# Describes the channels and their layout in the binary data blob.
PointField[] fields

bool    is_bigendian # Is this data bigendian?
uint32  point_step   # Length of a point in bytes
uint32  row_step     # Length of a row in bytes
uint8[] data         # Actual point data, size is (row_step*height)

bool is_dense        # True if there are no invalid points
tmori commented 5 months ago

filedsの内訳:

[
  {name: "x", offset: 0, datatype: FLOAT32, count: 1},
  {name: "y", offset: 4, datatype: FLOAT32, count: 1},
  {name: "z", offset: 8, datatype: FLOAT32, count: 1},
  {name: "intensity", offset: 12, datatype: FLOAT32, count: 1}
]
tmori commented 5 months ago

こんな感じでUnityのインスペクタビューでパラメータ定義できるようにしてやった。

スクリーンショット 2024-04-15 18 35 07

tmori commented 5 months ago

以下で対応。

https://github.com/toppers/hakoniwa-unity-simasset-plugin/commit/623b0f8d813a21d5a44cfc554bd80cd12a35be72

tmori commented 5 months ago

動作確認プログラム


def parse_lidarData(data):

    # reshape array of floats to array of [X,Y,Z]
    points = numpy.array(data.point_cloud, dtype=numpy.dtype('f4'))
    points = numpy.reshape(points, (int(points.shape[0]/3), 3))

    return points

def main():
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <config_path>")
        return 1

    # connect to the HakoSim simulator
    client = hakosim.MultirotorClient(sys.argv[1])
    client.confirmConnection()
    client.enableApiControl(True)
    client.armDisarm(True)
    client.takeoff(3)

    lidarData = client.getLidarData()
    if (len(lidarData.point_cloud) < 3):
        print("\tNo points received from Lidar data")
    else:
        print(f"len: {len(lidarData.point_cloud)}")
        points = parse_lidarData(lidarData)
        print("\tReading: time_stamp: %d number_of_points: %d" % (lidarData.time_stamp, len(points)))
        print("\t\tlidar position: %s" % (pprint.pformat(lidarData.pose.position)))
        print("\t\tlidar orientation: %s" % (pprint.pformat(lidarData.pose.orientation)))

        condition = numpy.logical_and(points <= 3, points > 0)
        filtered_points = points[numpy.any(condition, axis=1)]
        print(filtered_points)