Skip to content

Commit

Permalink
support compressed image
Browse files Browse the repository at this point in the history
  • Loading branch information
TakanoTaiga authored May 25, 2024
1 parent b03d69f commit 6dca3fe
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
91 changes: 79 additions & 12 deletions Assets/AWSIM/Scripts/Sensors/Camera/CameraRos2Publisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
using System.Collections.Generic;
using UnityEngine;
using ROS2;
using System.Drawing;
using System.IO;
using UnityEngine;


namespace AWSIM
{
public enum raw_or_compress
{
RAW, Compressed
}

/// <summary>
/// Convert the data output from CameraSensor to ROS2 msg and Publish.
/// </summary>
Expand All @@ -16,7 +25,7 @@ public class CameraRos2Publisher : MonoBehaviour
/// <summary>
/// Topic name for Image msg.
/// </summary>
public string imageTopic = "/sensing/camera/traffic_light/image_raw";
public string imageTopic = "/sensing/camera/traffic_light/image";

/// <summary>
/// Topic name for CameraInfo msg.
Expand All @@ -28,6 +37,11 @@ public class CameraRos2Publisher : MonoBehaviour
/// </summary>
public string frameId = "traffic_light_left_camera/camera_link";

/// <summary>
/// Publish type. Raw or Compressed.
/// </summary>
public raw_or_compress publish_type;

/// <summary>
/// QoS settings.
/// </summary>
Expand All @@ -41,9 +55,11 @@ public class CameraRos2Publisher : MonoBehaviour

// Publishers
IPublisher<sensor_msgs.msg.Image> imagePublisher;
IPublisher<sensor_msgs.msg.CompressedImage> compressedImagePublisher;
IPublisher<sensor_msgs.msg.CameraInfo> cameraInfoPublisher;
sensor_msgs.msg.Image imageMsg;
sensor_msgs.msg.CameraInfo cameraInfoMsg;
sensor_msgs.msg.CompressedImage compressedImageMsg;

CameraSensor sensor;

Expand All @@ -54,17 +70,38 @@ void Start()
{
throw new MissingComponentException("No active CameraSensor component found.");
}
if (publish_type == raw_or_compress.Compressed)
{
sensor.flip_image = true;
}else
{
sensor.flip_image = false;
}

// Set callback
sensor.OnOutputData += UpdateMessagesAndPublish;

// Initialize msgs
imageMsg = InitializeEmptyImageMsg();
if(publish_type == raw_or_compress.RAW)
{
imageMsg = InitializeEmptyImageMsg();
}
else
{
compressedImageMsg = InitializeEmptyCompressedImageMsg();
}
cameraInfoMsg = InitializeEmptyCameraInfoMsg();

// Create publishers
var qos = qosSettings.GetQoSProfile();
imagePublisher = SimulatorROS2Node.CreatePublisher<sensor_msgs.msg.Image>(imageTopic, qos);
if (publish_type == raw_or_compress.RAW)
{
imagePublisher = SimulatorROS2Node.CreatePublisher<sensor_msgs.msg.Image>(imageTopic, qos);
}
else
{
compressedImagePublisher = SimulatorROS2Node.CreatePublisher<sensor_msgs.msg.CompressedImage>(imageTopic, qos);
}
cameraInfoPublisher = SimulatorROS2Node.CreatePublisher<sensor_msgs.msg.CameraInfo>(cameraInfoTopic, qos);
}

Expand All @@ -81,26 +118,45 @@ void UpdateMessagesAndPublish(CameraSensor.OutputData outputData)

// Update msgs timestamp, timestamps should be synchronized in order to connect image and camera_info msgs
var timeMsg = SimulatorROS2Node.GetCurrentRosTime();
imageMsg.Header.Stamp = timeMsg;
cameraInfoMsg.Header.Stamp = timeMsg;

// Publish to ROS2
imagePublisher.Publish(imageMsg);
if (publish_type == raw_or_compress.RAW)
{
imageMsg.Header.Stamp = timeMsg;
imagePublisher.Publish(imageMsg);
}
else
{
compressedImageMsg.Header.Stamp = timeMsg;
compressedImagePublisher.Publish(compressedImageMsg);
}
cameraInfoMsg.Header.Stamp = timeMsg;
cameraInfoPublisher.Publish(cameraInfoMsg);
}

private void UpdateImageMsg(CameraSensor.OutputData data)
{
if (imageMsg.Width != data.cameraParameters.width || imageMsg.Height != data.cameraParameters.height)
if (publish_type == raw_or_compress.RAW)
{
imageMsg.Width = (uint)data.cameraParameters.width;
imageMsg.Height = (uint)data.cameraParameters.height;
imageMsg.Step = (uint)(data.cameraParameters.width * 3);
if (imageMsg.Width != data.cameraParameters.width || imageMsg.Height != data.cameraParameters.height)
{
imageMsg.Width = (uint)data.cameraParameters.width;
imageMsg.Height = (uint)data.cameraParameters.height;
imageMsg.Step = (uint)(data.cameraParameters.width * 3);

imageMsg.Data = new byte[data.cameraParameters.height * data.cameraParameters.width * 3];
}

imageMsg.Data = new byte[data.cameraParameters.height * data.cameraParameters.width * 3];
imageMsg.Data = data.imageDataBuffer;
}
else
{
Texture2D texture = new Texture2D(data.cameraParameters.width, data.cameraParameters.height, TextureFormat.RGB24, false);
texture.LoadRawTextureData(data.imageDataBuffer);
texture.Apply();

imageMsg.Data = data.imageDataBuffer;
compressedImageMsg.Data = texture.EncodeToJPG();
}
}

private void UpdateCameraInfoMsg(CameraSensor.CameraParameters cameraParameters)
Expand Down Expand Up @@ -147,6 +203,17 @@ private sensor_msgs.msg.Image InitializeEmptyImageMsg()
Is_bigendian = 0,
};
}
private sensor_msgs.msg.CompressedImage InitializeEmptyCompressedImageMsg()
{
return new sensor_msgs.msg.CompressedImage()
{
Header = new std_msgs.msg.Header()
{
Frame_id = frameId
},
Format = "jpeg"
};
}

private sensor_msgs.msg.CameraInfo InitializeEmptyCameraInfoMsg()
{
Expand Down
6 changes: 5 additions & 1 deletion Assets/AWSIM/Scripts/Sensors/Camera/CameraSensor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ private enum FocalLengthName

private int bytesPerPixel = 3;

[HideInInspector]
public bool flip_image = false;

void Start()
{
if (cameraObject == null)
Expand Down Expand Up @@ -223,6 +226,7 @@ public void DoRender()
rosImageShader.SetTexture(rosShaderKernelIdx, "_InputTexture", distortedRenderTexture);
rosImageShader.SetBuffer(rosShaderKernelIdx, "_RosImageBuffer", computeBuffer);
rosImageShader.Dispatch(rosShaderKernelIdx, rosImageShaderGroupSizeX, 1, 1);
rosImageShader.SetBool("_flip_image", flip_image);

// Get data from shader
AsyncGPUReadback.Request(computeBuffer, OnGPUReadbackRequest);
Expand Down Expand Up @@ -341,4 +345,4 @@ private void UpdateCameraParameters()
cameraParameters.cy = ((cameraParameters.height + 1) / 2.0f);
}
}
}
}
2 changes: 1 addition & 1 deletion Assets/AWSIM/Scripts/Sensors/Camera/CameraSensorHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class CameraSensorHolder : MonoBehaviour
/// Data output hz.
/// Sensor processing and callbacks are called in this hz.
/// </summary>
[Range(0, 30)][SerializeField] private uint publishHz = 10;
[Range(0, 60)][SerializeField] private uint publishHz = 10;

/// <summary>
/// Rendering sequence type.
Expand Down
13 changes: 12 additions & 1 deletion Assets/AWSIM/Scripts/Sensors/Camera/RosImageShader.compute
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ RWStructuredBuffer<uint> _RosImageBuffer;
uint _width;
uint _height;

bool _flip_image;

#define BYTES_PER_PIXEL 3
#define SIZE_OF_UINT 4

Expand All @@ -28,7 +30,16 @@ void RosImageShaderKernel (uint3 id : SV_DispatchThreadID)
// Convert coordinates for use in ROS (bgr8).
// write down for distortion texture
// write to B,G,R
uint rosImageY = _height - 1 - textureY;

uint rosImageY = 0;
if (_flip_image)
{
rosImageY = textureY;
}
else
{
rosImageY = _height - 1 - textureY;
}
float3 color1 = _InputTexture[float2(textureX, rosImageY)].rgb;

// check boundary conditions
Expand Down

0 comments on commit 6dca3fe

Please sign in to comment.