private void SendPointCloud()
    {
        if (Bridge == null || Bridge.Status != Comm.BridgeStatus.Connected)
        {
            range_array.Clear();
            intensity_array.Clear();
            return;
        }
        int FOV_take_1 = (int)(Mathf.Abs(FOVLeftLimit - FOVRightLimit) / Mathf.Abs(rotationAnglePerStep));
        int FOV_skip   = (int)(Mathf.Abs(-270 - FOVLeftLimit) / Mathf.Abs(rotationAnglePerStep));
        int FOV_take_2 = 0;

        if (FOV_take_1 + FOV_skip != (int)(360 / rotationAnglePerStep))
        {
            FOV_take_2 = (int)(360 / rotationAnglePerStep) - FOV_skip - FOV_take_1;
        }


        var msg = new Ros.LaserScan()
        {
            header = new Ros.Header()
            {
                stamp    = Ros.Time.Now(),
                seq      = seqId++,
                frame_id = frame_id,
            },
            angle_min       = FOVLeftLimit * Mathf.PI / 180.0f,
            angle_max       = FOVRightLimit * Mathf.PI / 180.0f,
            angle_increment = rotationAnglePerStep * Mathf.PI / 180.0f,
            time_increment  = 1.0f * 360.0f / (rotationSpeedHz * rotationAnglePerStep),
            scan_time       = 1.0f / rotationSpeedHz,
            range_min       = minRange,
            range_max       = maxRange,
            ranges          = (range_array.Take(FOV_take_2).Concat(range_array.Skip(FOV_skip).Take(FOV_take_1))).ToArray(),
            intensities     = (intensity_array.Take(FOV_take_2).Concat(intensity_array.Skip(FOV_skip).Take(FOV_take_1))).ToArray(),
        };

        if (targetEnv == ROSTargetEnvironment.AUTOWARE || targetEnv == ROSTargetEnvironment.DUCKIETOWN_ROS1)
        {
            AutowareWriterLaserScan.Publish(msg);
        }

        range_array.Clear();
        intensity_array.Clear();
    }
Example #2
0
    void SendMessage(int currentEndIndex, float currentEndAngle)
    {
        if (Bridge == null || Bridge.Status != Comm.BridgeStatus.Connected)
        {
            return;
        }

#if UNITY_EDITOR
        UnityEngine.Profiling.Profiler.BeginSample("SendMessage");
#endif

        // Lidar x is forward, y is left, z is up
        var worldToLocal = new Matrix4x4(new Vector4(0, -1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(1, 0, 0, 0), Vector4.zero);

        if (Compensated)
        {
            worldToLocal = worldToLocal * transform.worldToLocalMatrix;
        }

        if (CurrentRayCount != 1)
        {
            System.DateTime Unixepoch        = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
            double          measurement_time = (double)(System.DateTime.UtcNow - Unixepoch).TotalSeconds;

            if (TargetEnvironment == ROSTargetEnvironment.APOLLO35)
            {
                var msg = new Apollo.Drivers.PointCloud()
                {
                    Header = new Apollo.Common.Header()
                    {
                        // TimestampSec = measurement_time,
                        SequenceNum = Sequence++,
                        FrameId     = FrameName,
                    },
                    FrameId         = "lidar128",
                    IsDense         = false,
                    MeasurementTime = measurement_time,
                    Height          = 1,
                    Width           = (uint)PointCloud.Length, // TODO is this right?
                };

                for (int i = 0; i < PointCloud.Length; i++)
                {
                    var point = PointCloud[i];
                    if (point == Vector4.zero)
                    {
                        continue;
                    }

                    var   pos       = new Vector3(point.x, point.y, point.z);
                    float intensity = point.w;

                    pos = worldToLocal.MultiplyPoint3x4(pos);

                    msg.Point.Add(new Apollo.Drivers.PointXYZIT()
                    {
                        X         = pos.x,
                        Y         = pos.y,
                        Z         = pos.z,
                        Intensity = (byte)(intensity * 255),
                        Timestamp = (ulong)measurement_time
                    });
                }
                ;

                Apollo35WriterPointCloud2.Publish(msg);
            }

            else
            {
                int count = 0;
                unsafe
                {
                    fixed(byte *ptr = RosPointCloud)
                    {
                        int offset = 0;

                        for (int i = 0; i < PointCloud.Length; i++)
                        {
                            var point = PointCloud[i];
                            if (point == Vector4.zero)
                            {
                                continue;
                            }

                            var   pos       = new Vector3(point.x, point.y, point.z);
                            float intensity = point.w;

                            *(Vector3 *)(ptr + offset) = worldToLocal.MultiplyPoint3x4(pos);
                            *(ptr + offset + 16)       = (byte)(intensity * 255);

                            offset += 32;
                            count++;
                        }
                    }
                }

                var msg = new Ros.PointCloud2()
                {
                    header = new Ros.Header()
                    {
                        stamp    = Ros.Time.Now(),
                        seq      = Sequence++,
                        frame_id = FrameName,
                    },
                    height = 1,
                    width  = (uint)count,
                    fields = new Ros.PointField[] {
                        new Ros.PointField()
                        {
                            name     = "x",
                            offset   = 0,
                            datatype = 7,
                            count    = 1,
                        },
                        new Ros.PointField()
                        {
                            name     = "y",
                            offset   = 4,
                            datatype = 7,
                            count    = 1,
                        },
                        new Ros.PointField()
                        {
                            name     = "z",
                            offset   = 8,
                            datatype = 7,
                            count    = 1,
                        },
                        new Ros.PointField()
                        {
                            name     = "intensity",
                            offset   = 16,
                            datatype = 2,
                            count    = 1,
                        },
                        new Ros.PointField()
                        {
                            name     = "timestamp",
                            offset   = 24,
                            datatype = 8,
                            count    = 1,
                        },
                    },
                    is_bigendian = false,
                    point_step   = 32,
                    row_step     = (uint)count * 32,
                    data         = new Ros.PartialByteArray()
                    {
                        Base64 = System.Convert.ToBase64String(RosPointCloud, 0, count * 32),
                    },
                    is_dense = true,
                };

                if (TargetEnvironment == ROSTargetEnvironment.APOLLO)
                {
                    ApolloWriterPointCloud2.Publish(msg);
                }

                else if (TargetEnvironment == ROSTargetEnvironment.AUTOWARE)
                {
                    AutowareWriterPointCloud2.Publish(msg);
                }

                else
                {
                    WriterPointCloud2.Publish(msg);
                }
            }
        }
        else // for planar lidar only (single ray lidar) publish LaserScan instead of PoinCloud2
        {
            float fixup = currentEndAngle;
            FixupAngle = currentEndAngle;

            float LaserScanMinAngle = -Mathf.PI;
            float LaserScanMaxAngle = Mathf.PI;
            float LaserScanMinRange = 0.0f;
            float LaserScanMaxRange = 40.0f;

            float[] range_array     = new float[CurrentMeasurementsPerRotation];
            float[] intensity_array = new float[CurrentMeasurementsPerRotation];

            int offset = (int)(currentEndIndex - currentEndAngle / 360.0f * CurrentMeasurementsPerRotation);

            for (int i = 0; i < PointCloud.Length; i++)
            {
                var point = PointCloud[i];
                if (point == Vector4.zero)
                {
                    continue;
                }
                range_array[(i + offset + CurrentMeasurementsPerRotation) % CurrentMeasurementsPerRotation]     = Vector3.Distance(new Vector3(point.x, point.y, point.z), transform.position);
                intensity_array[(i + offset + CurrentMeasurementsPerRotation) % CurrentMeasurementsPerRotation] = point.w;
            }
            // Populate LaserScan message
            var msg = new Ros.LaserScan()
            {
                header = new Ros.Header()
                {
                    stamp    = Ros.Time.Now(),
                    seq      = Sequence++,
                    frame_id = FrameName,
                },
                angle_min       = LaserScanMinAngle,
                angle_max       = LaserScanMaxAngle,
                angle_increment = Mathf.Abs(LaserScanMaxAngle - LaserScanMinAngle) / CurrentMeasurementsPerRotation,
                time_increment  = 1.0f / (CurrentMeasurementsPerRotation * RotationFrequency),
                scan_time       = 1.0f / RotationFrequency,
                range_min       = LaserScanMinRange,
                range_max       = LaserScanMaxRange,
                ranges          = range_array, // TODO: Should make sure only sending range between min and max
                intensities     = intensity_array,
            };
            WriterLaserScan.Publish(msg);
        }

#if UNITY_EDITOR
        UnityEngine.Profiling.Profiler.EndSample();
#endif
    }
Example #3
0
    void SendMessage(int currentEndIndex, float currentEndAngle)
    {
        if (Bridge == null || Bridge.Status != Ros.Status.Connected)
        {
            return;
        }

#if UNITY_EDITOR
        UnityEngine.Profiling.Profiler.BeginSample("SendMessage");
#endif

        Matrix4x4 worldToLocal;

        if (TargetEnvironment == ROSTargetEnvironment.APOLLO)
        {
            // local.Set(local.x, local.z, local.y);
            worldToLocal = new Matrix4x4(new Vector4(1, 0, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 1, 0, 0), Vector4.zero);
        }
        else if (TargetEnvironment == ROSTargetEnvironment.AUTOWARE)
        {
            // local.Set(local.z, -local.x, local.y);
            worldToLocal = new Matrix4x4(new Vector4(0, -1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(1, 0, 0, 0), Vector4.zero);
        }
        else
        {
            worldToLocal = Matrix4x4.identity;
        }

        if (Compensated)
        {
            worldToLocal = worldToLocal * transform.worldToLocalMatrix;
        }

        if (CurrentRayCount != 1)
        {
            int count = 0;
            unsafe
            {
                fixed(byte *ptr = RosPointCloud)
                {
                    int offset = 0;

                    for (int i = 0; i < PointCloud.Length; i++)
                    {
                        var point = PointCloud[i];
                        if (point == Vector4.zero)
                        {
                            continue;
                        }

                        var   pos       = new Vector3(point.x, point.y, point.z);
                        float intensity = point.w;

                        *(Vector3 *)(ptr + offset) = worldToLocal.MultiplyPoint3x4(pos);
                        *(ptr + offset + 16)       = (byte)(intensity * 255);

                        offset += 32;
                        count++;
                    }
                }
            }

            var msg = new Ros.PointCloud2()
            {
                header = new Ros.Header()
                {
                    stamp    = Ros.Time.Now(),
                    seq      = Sequence++,
                    frame_id = FrameName,
                },
                height = 1,
                width  = (uint)count,
                fields = new Ros.PointField[] {
                    new Ros.PointField()
                    {
                        name     = "x",
                        offset   = 0,
                        datatype = 7,
                        count    = 1,
                    },
                    new Ros.PointField()
                    {
                        name     = "y",
                        offset   = 4,
                        datatype = 7,
                        count    = 1,
                    },
                    new Ros.PointField()
                    {
                        name     = "z",
                        offset   = 8,
                        datatype = 7,
                        count    = 1,
                    },
                    new Ros.PointField()
                    {
                        name     = "intensity",
                        offset   = 16,
                        datatype = 2,
                        count    = 1,
                    },
                    new Ros.PointField()
                    {
                        name     = "timestamp",
                        offset   = 24,
                        datatype = 8,
                        count    = 1,
                    },
                },
                is_bigendian = false,
                point_step   = 32,
                row_step     = (uint)count * 32,
                data         = new Ros.PartialByteArray()
                {
                    Base64 = System.Convert.ToBase64String(RosPointCloud, 0, count * 32),
                },
                is_dense = true,
            };

#if UNITY_EDITOR
            UnityEngine.Profiling.Profiler.BeginSample("Publish");
#endif

            if (TargetEnvironment == ROSTargetEnvironment.APOLLO)
            {
                Bridge.Publish(ApolloTopicName, msg);
            }
            else if (TargetEnvironment == ROSTargetEnvironment.AUTOWARE)
            {
                Bridge.Publish(AutowareTopicName, msg);
            }
            else
            {
                Bridge.Publish(TopicName, msg);
            }
#if UNITY_EDITOR
            UnityEngine.Profiling.Profiler.EndSample();
#endif
        }
        else // for planar lidar only (single ray lidar) publish LaserScan instead of PoinCloud2
        {
            float fixup = currentEndAngle;
            FixupAngle = currentEndAngle;

            float LaserScanMinAngle = -Mathf.PI;
            float LaserScanMaxAngle = Mathf.PI;
            float LaserScanMinRange = 0.0f;
            float LaserScanMaxRange = 40.0f;

            float[] range_array     = new float[CurrentMeasurementsPerRotation];
            float[] intensity_array = new float[CurrentMeasurementsPerRotation];

            int offset = (int)(currentEndIndex - currentEndAngle / 360.0f * CurrentMeasurementsPerRotation);

            for (int i = 0; i < PointCloud.Length; i++)
            {
                var point = PointCloud[i];
                if (point == Vector4.zero)
                {
                    continue;
                }
                range_array[(i + offset + CurrentMeasurementsPerRotation) % CurrentMeasurementsPerRotation]     = Vector3.Distance(new Vector3(point.x, point.y, point.z), transform.position);
                intensity_array[(i + offset + CurrentMeasurementsPerRotation) % CurrentMeasurementsPerRotation] = point.w;
            }
            // Populate LaserScan message
            var msg = new Ros.LaserScan()
            {
                header = new Ros.Header()
                {
                    stamp    = Ros.Time.Now(),
                    seq      = Sequence++,
                    frame_id = FrameName,
                },
                angle_min       = LaserScanMinAngle,
                angle_max       = LaserScanMaxAngle,
                angle_increment = Mathf.Abs(LaserScanMaxAngle - LaserScanMinAngle) / CurrentMeasurementsPerRotation,
                time_increment  = 1.0f / (CurrentMeasurementsPerRotation * RotationFrequency),
                scan_time       = 1.0f / RotationFrequency,
                range_min       = LaserScanMinRange,
                range_max       = LaserScanMaxRange,
                ranges          = range_array, // TODO: Should make sure only sending range between min and max
                intensities     = intensity_array,
            };
            Bridge.Publish(TopicName, msg);
        }


#if UNITY_EDITOR
        UnityEngine.Profiling.Profiler.EndSample();
#endif
    }