@@ -144,6 +144,237 @@ public LaserScanMessage(HeaderMessage header, float angle_min, float angle_max,
144144 }
145145 }
146146
147+
148+ /// <summary>
149+ /// This message holds the description of one point entry in the
150+ /// PointCloud2 message format.
151+ /// uint8 INT8 = 1
152+ /// uint8 UINT8 = 2
153+ /// uint8 INT16 = 3
154+ /// uint8 UINT16 = 4
155+ /// uint8 INT32 = 5
156+ /// uint8 UINT32 = 6
157+ /// uint8 FLOAT32 = 7
158+ /// uint8 FLOAT64 = 8
159+ /// </summary>
160+ public class PointFieldMessage : ZOROSMessageInterface {
161+
162+ [ Newtonsoft . Json . JsonIgnore ]
163+ public string MessageType { get { return PointFieldMessage . Type ; } }
164+
165+ [ Newtonsoft . Json . JsonIgnore ]
166+ public static string Type = "sensor_msgs/PointField" ;
167+
168+
169+ /// <summary>
170+ /// name of field.
171+ /// </summary>
172+ /// <value></value>
173+ public string name { get ; set ; }
174+
175+ /// <summary>
176+ /// Offset from start of point struct
177+ /// </summary>
178+ /// <value></value>
179+ public uint offset { get ; set ; }
180+
181+ /// <summary>
182+ /// Datatype enumeration.
183+ /// uint8 INT8 = 1
184+ /// uint8 UINT8 = 2
185+ /// uint8 INT16 = 3
186+ /// uint8 UINT16 = 4
187+ /// uint8 INT32 = 5
188+ /// uint8 UINT32 = 6
189+ /// uint8 FLOAT32 = 7
190+ /// uint8 FLOAT64 = 8
191+ /// </summary>
192+ /// <value></value>
193+ public byte datatype { get ; set ; }
194+
195+ /// <summary>
196+ /// How many elements in the field
197+ /// </summary>
198+ /// <value></value>
199+ public uint count { get ; set ; }
200+
201+ public PointFieldMessage ( ) {
202+ this . name = "" ;
203+ this . offset = 0 ;
204+ this . datatype = 1 ;
205+ this . count = 0 ;
206+ }
207+
208+ public PointFieldMessage ( string name , uint offset , byte datatype , uint count ) {
209+ this . name = name ;
210+ this . offset = offset ;
211+ this . datatype = datatype ;
212+ this . count = count ;
213+ }
214+
215+ public static PointFieldMessage [ ] CreateXYZPointFieldArray ( uint count ) {
216+ PointFieldMessage [ ] pointFieldMessages = new PointFieldMessage [ 3 ] ;
217+
218+ // x
219+ pointFieldMessages [ 0 ] = new PointFieldMessage ( ) ;
220+ pointFieldMessages [ 0 ] . name = "x" ;
221+ pointFieldMessages [ 0 ] . offset = 0 ;
222+ pointFieldMessages [ 0 ] . datatype = 7 ; // float32
223+ pointFieldMessages [ 0 ] . count = count ;
224+
225+ // y
226+ pointFieldMessages [ 1 ] = new PointFieldMessage ( ) ;
227+ pointFieldMessages [ 1 ] . name = "y" ;
228+ pointFieldMessages [ 1 ] . offset = 4 ;
229+ pointFieldMessages [ 1 ] . datatype = 7 ; // float32
230+ pointFieldMessages [ 1 ] . count = count ;
231+
232+ // z
233+ pointFieldMessages [ 2 ] = new PointFieldMessage ( ) ;
234+ pointFieldMessages [ 2 ] . name = "z" ;
235+ pointFieldMessages [ 2 ] . offset = 8 ;
236+ pointFieldMessages [ 2 ] . datatype = 7 ; // float32
237+ pointFieldMessages [ 2 ] . count = count ;
238+
239+ return pointFieldMessages ;
240+
241+ }
242+
243+ }
244+
245+ /// <summary>
246+ /// This message holds a collection of N-dimensional points, which may
247+ /// contain additional information such as normals, intensity, etc. The
248+ /// point data is stored as a binary blob, its layout described by the
249+ /// contents of the "fields" array.
250+ ///
251+ /// The point cloud data may be organized 2d (image-like) or 1d
252+ /// (unordered). Point clouds organized as 2d images may be produced by
253+ /// camera depth sensors such as stereo or time-of-flight.
254+ /// </summary>
255+ public class PointCloud2Message : ZOROSMessageInterface {
256+
257+ [ Newtonsoft . Json . JsonIgnore ]
258+ public string MessageType { get { return PointCloud2Message . Type ; } }
259+
260+ [ Newtonsoft . Json . JsonIgnore ]
261+ public static string Type = "sensor_msgs/PointCloud2" ;
262+
263+
264+ /// <summary>
265+ /// Time of sensor data acquisition, and the coordinate frame ID (for 3d points).
266+ /// </summary>
267+ /// <value></value>
268+ public HeaderMessage header { get ; set ; }
269+
270+
271+ /// <summary>
272+ /// 2D structure of the point cloud. If the cloud is unordered, height is
273+ /// 1 and width is the length of the point cloud.
274+ /// </summary>
275+ /// <value></value>
276+ public uint height { get ; set ; }
277+ public uint width { get ; set ; }
278+
279+ /// <summary>
280+ /// Describes the channels and their layout in the binary data blob.
281+ /// </summary>
282+ /// <value></value>
283+ public PointFieldMessage [ ] fields { get ; set ; }
284+
285+ /// <summary>
286+ /// Is this data bigendian?
287+ /// </summary>
288+ /// <value></value>
289+ public bool is_bigendian { get ; set ; }
290+
291+ /// <summary>
292+ /// Length of a point in bytes
293+ /// </summary>
294+ /// <value></value>
295+ public uint point_step { get ; set ; }
296+
297+ /// <summary>
298+ /// Length of a row in bytes
299+ /// </summary>
300+ /// <value></value>
301+ public uint row_step { get ; set ; }
302+
303+ /// <summary>
304+ /// Actual point data, size is (row_step*height)
305+ /// </summary>
306+ /// <value></value>
307+ public byte [ ] data { get ; set ; }
308+
309+ /// <summary>
310+ /// True if there are no invalid points
311+ /// </summary>
312+ /// <value></value>
313+ public bool is_dense { get ; set ; }
314+
315+ public PointCloud2Message ( ) {
316+ this . header = new HeaderMessage ( ) ;
317+ this . height = 0 ;
318+ this . width = 0 ;
319+ this . fields = new PointFieldMessage [ 0 ] ;
320+ this . is_bigendian = false ;
321+ this . point_step = 0 ;
322+ this . row_step = 0 ;
323+ this . data = new byte [ 0 ] ;
324+ this . is_dense = true ;
325+
326+ }
327+
328+ public PointCloud2Message ( HeaderMessage header , uint height , uint width , PointFieldMessage [ ] pointFieldMessages , bool is_bigendian , uint point_step , uint row_step , byte [ ] data , bool is_dense ) {
329+ this . header = header ;
330+ this . height = height ;
331+ this . width = width ;
332+ this . fields = pointFieldMessages ;
333+ this . is_bigendian = is_bigendian ;
334+ this . point_step = point_step ;
335+ this . row_step = row_step ;
336+ this . data = data ;
337+ this . is_dense = is_dense ;
338+
339+ }
340+
341+ public void Update ( ) {
342+ this . header . Update ( ) ;
343+ }
344+
345+ public static PointCloud2Message CreateXYZPointCloud ( UnityEngine . Vector3 [ ] pointsInUnityCoordinates ) {
346+ byte [ ] byteData = new byte [ sizeof ( float ) * 3 * pointsInUnityCoordinates . Length ] ;
347+
348+ // public void FromUnityVector3(UnityEngine.Vector3 v) {
349+ // this.x = (double)v.z;
350+ // this.y = -(double)v.x;
351+ // this.z = (double)v.y;
352+ // }
353+
354+ int byteDataOffset = 0 ;
355+ foreach ( UnityEngine . Vector3 v in pointsInUnityCoordinates ) {
356+ Buffer . BlockCopy ( BitConverter . GetBytes ( v . z ) , 0 , byteData , byteDataOffset + ( 0 * sizeof ( float ) ) , sizeof ( float ) ) ;
357+ Buffer . BlockCopy ( BitConverter . GetBytes ( - v . x ) , 0 , byteData , byteDataOffset + ( 1 * sizeof ( float ) ) , sizeof ( float ) ) ;
358+ Buffer . BlockCopy ( BitConverter . GetBytes ( v . y ) , 0 , byteData , byteDataOffset + ( 2 * sizeof ( float ) ) , sizeof ( float ) ) ;
359+ byteDataOffset += ( 3 * sizeof ( float ) ) ;
360+ }
361+
362+ PointCloud2Message pointCloud2Message = new PointCloud2Message ( new HeaderMessage ( ) ,
363+ height : 1 ,
364+ width : ( uint ) pointsInUnityCoordinates . Length ,
365+ pointFieldMessages : PointFieldMessage . CreateXYZPointFieldArray ( ( uint ) pointsInUnityCoordinates . Length ) ,
366+ is_bigendian : false ,
367+ point_step : sizeof ( float ) * 3 ,
368+ row_step : sizeof ( float ) * 12 * ( uint ) pointsInUnityCoordinates . Length ,
369+ byteData ,
370+ false ) ;
371+
372+ return pointCloud2Message ;
373+ }
374+
375+
376+ }
377+
147378 /// <summary>
148379 /// This is a message that holds data to describe the state of a set of torque controlled joints.
149380 ///
0 commit comments