Comments (10)
Hi, I am testing the plugin on UE 4.23 to compare it with the solution my team has been using for the last year or so - and it seems like this plugin might be a good replacemente for that!
Anyway, I just tried doing what you are asking for, so, even if I am not among the plugin developers, I might be able to help - I hope it's not too late :)
I will just copy-paste the parts to be modified - they can easily be found in the .h and .cpp file.
Header
In Topic.h
you can modify the enum defining the available topics in your Blueprint by adding the datatype you need, as follows:
UENUM(BlueprintType, Category = "ROS")
enum class EMessageType : uint8
{
String = 0,
Float32 = 1,
// added the following type:
PoseStamped = 2
};
Then, you can scroll down in the same file, and add the UFUNCTION
to be implemented in Blueprint after the existing ones (OnStringMessage
, OnFloat32Message
), like so:
UFUNCTION(BlueprintImplementableEvent, Category = ROS)
void OnPoseStampedMessage(const FVector& Position, const FRotator& Rotation);
Source
Then you can move to the Topic.cpp file.
You can add the new message type to the supported ones within the constructor:
if (SupportedMessageTypes.Num() == 0)
{
SupportedMessageTypes.Add(EMessageType::String, TEXT("std_msgs/String"));
SupportedMessageTypes.Add(EMessageType::Float32, TEXT("std_msgs/Float32"));
// this is the line to be added
SupportedMessageTypes.Add(EMessageType::PoseStamped, TEXT("geometry_msgs/PoseStamped"));
}
Finally, move to the UTopic::Subscribe()
function and add a case to the switch:
case EMessageType::PoseStamped:
{
auto ConcretePoseStampedMessage = StaticCastSharedPtr<ROSMessages::geometry_msgs::PoseStamped>(msg);
if (ConcretePoseStampedMessage.IsValid())
{
const FVector Pos = FVector(ConcretePoseStampedMessage->pose.position.x,
ConcretePoseStampedMessage->pose.position.y,
ConcretePoseStampedMessage->pose.position.z);
const FQuat Rot = FQuat(ConcretePoseStampedMessage->pose.orientation.x,
ConcretePoseStampedMessage->pose.orientation.y,
ConcretePoseStampedMessage->pose.orientation.z,
ConcretePoseStampedMessage->pose.orientation.w);
TWeakPtr<UTopic, ESPMode::ThreadSafe> SelfPtr(_SelfPtr);
AsyncTask(ENamedThreads::GameThread, [this, Pos, Rot, SelfPtr]()
{
if (!SelfPtr.IsValid()) return;
OnPoseStampedMessage(Pos, Rot.Rotator());
});
}
break;
}
Important things to notice
I am just trying the plugin, so I don't know if internally it is already dealing with the change of basis required to properly exchange geometry data between UE4 and ROS.
So, the way the code above is filling the position and rotation variables fed to the blueprint could definitely be wrong!
Also, I didn't test the blueprint/code, but it seems to be receiving a test PoseStamped message fine!
This might be a good starting point for your own implementation :)
from rosintegration.
Hi, how do I know what to put in the UFUNCTION for Twist for example?
I don't have a project setup with this code at the moment, but based on the Twist message structure (link) the UFUNCTION should be something like:
UFUNCTION(BlueprintImplementableEvent, Category = ROS)
void OnTwistMessage(const FVector& Linear, const FVector& Angular);
The way this UFUNCTION is defined is up to you, in the end: this is an Event you can implement in your blueprint, and based on your needs you could specify less or more arguments. More on that once we get to the following part.
And I also have no idea how to get this right..
Supposing Twist has been added to the EMessageType
enum as Twist
, you need to add a case for it in your code. That case should be similar to the following:
case EMessageType::Twist:
{
auto ConcreteTwistMessage = StaticCastSharedPtr<ROSMessages::geometry_msgs::Twist>(msg);
if (ConcreteTwistMessage.IsValid())
{
const FVector Linear = FVector(ConcreteTwistMessage->linear.x,
ConcreteTwistMessage->linear.y,
ConcreteTwistMessage->linear.z);
const FVector Angular = FVector(ConcreteTwistMessage->angular.x,
ConcreteTwistMessage->angular.y,
ConcreteTwistMessage->angular.z);
TWeakPtr<UTopic, ESPMode::ThreadSafe> SelfPtr(_SelfPtr);
AsyncTask(ENamedThreads::GameThread, [this, Linear, Angular, SelfPtr]()
{
if (!SelfPtr.IsValid()) return;
OnTwistMessage(Linear, Angular);
});
}
break;
}
As you can see, the modified parts are the ones regarding the fields of your message. In this case, geometry_msgs::Twist
(that's a link to the sourcecode) is made of Angular
and Linear
, which are geometry_msgs::Vector3
types. All these are ROS messages, which are also defined by this Unreal plugin. Looking at both the ROS documentation and the plugin code, it is possible to understand how these messages are structured.
Going back to the UFUNCTION, you see how it is called by this code, specifically this part:
AsyncTask(ENamedThreads::GameThread, [this, Linear, Angular, SelfPtr]()
{
if (!SelfPtr.IsValid()) return;
OnTwistMessage(Linear, Angular);
});
Now, let's imagine you only need Linear, and you don't care about Angular for your application: in that case, you could define your UFUNCTION to have only the const FVector& Linear
argument, and call it as OnTwistMessage(Linear);
.
On the other hand, if you need to pass additional information to your blueprint, you can also do that: you just need to define the UFUNCTION the way you need it, e.g. adding a string parameter, a bool, etc.
Anyway, I hope this code works, since I cannot test it at the moment :P
A not so well written note about the AsyncTask
Also, the AsyncTask
portion is an interesting one. This is because Events defined in Blueprints cannot run in any thread, you want them in the GameThread (I don't know about other threads actually).
The AsyncTask
allows you to schedule the code you specify for execution in the thread you need. In this case that thread is the GameThread. This is important: the above c++ code is running in its own thread, if I remember correctly. So, if you were to just call OnTwistMessage
right after retrieving the message, you might have some issues (crashes, errors, etc).
By using AsyncTask
you are ensuring that the Event declared as UFUNCTION will be execute in the GameThread. As you see, the AsyncTask
arguments include the thread you want the specified code to run into, the passed arguments, and finally the code.
from rosintegration.
@DarioMazzanti Thank you very much! I understand how it works now. After editing Topic.h & Topic.cpp the option still doesn't show up in UE4. Is there anything I have to do after editing the files? Like compiling the Topic.cpp file?
That's right, whenever you change your code in cpp you need to compile it, otherwise the binaries you will be running will be outdated. That can be a good reason for your new enum option not to show up in UE4.
In UE4, if you are changing code inside a plugin you need to compile your project from your IDE, and not from the editor. This is because plugins are compiled as libraries, and are loaded by UE4 when you launch it. So, you have to close the editor, compile your project (which will include the plugins you are working on) and then launch UE4. This should load the latest version of your code!
There are certain languages which don't need to be compiled (interpreted languages, e.g. python, and most of js/web stuff), but that's not the case for cpp. This is actually a huge topic, and I am definitely no expert about it!
I think Epic presented some sort of "live code" feature, but I never tried it and at the time it didn't work for plugins.
from rosintegration.
Hi!
I'm rarely working with Blueprints, so i can't really comment on that. Maybe the others can help here.
from rosintegration.
This works. Good job. Thank you so much for the help. This should be a part of the ReadMe of this plugin. That and be integrated into the code base. I managed to setup a publishing node in blueprints using that as a starting point and knowledge gained from working with a new subscribing topic. Ideally, with more time, I would like to expand this to blueprint all the existing message types for subscribing and publishing along with including examples on setting up blueprints for passing this information around.
from rosintegration.
Realy cool, thank you. Is it also possible to use bson with blueprints? For my project it is necessary to create a Videostream from UE to ROS and my C++ knowledge is not the best.
from rosintegration.
Realy cool, thank you. Is it also possible to use bson with blueprints? For my project it is necessary to create a Videostream from UE to ROS and my C++ knowledge is not the best.
I believe the code-iai vision plugin handles videostreaming from UE4 to ROS. I got it to work once but it was fairly resource hungry as I roughly recall.
https://github.com/code-iai/ROSIntegrationVision
from rosintegration.
Hi, how do I know what to put in the UFUNCTION for Twist for example?
Then, you can scroll down in the same file, and add the
UFUNCTION
to be implemented in Blueprint after the existing ones (OnStringMessage
,OnFloat32Message
), like so:UFUNCTION(BlueprintImplementableEvent, Category = ROS) void OnPoseStampedMessage(const FVector& Position, const FRotator& Rotation);
And I also have no idea how to get this right..
Finally, move to the
UTopic::Subscribe()
function and add a case to the switch:case EMessageType::PoseStamped: { auto ConcretePoseStampedMessage = StaticCastSharedPtr<ROSMessages::geometry_msgs::PoseStamped>(msg); if (ConcretePoseStampedMessage.IsValid()) { const FVector Pos = FVector(ConcretePoseStampedMessage->pose.position.x, ConcretePoseStampedMessage->pose.position.y, ConcretePoseStampedMessage->pose.position.z); const FQuat Rot = FQuat(ConcretePoseStampedMessage->pose.orientation.x, ConcretePoseStampedMessage->pose.orientation.y, ConcretePoseStampedMessage->pose.orientation.z, ConcretePoseStampedMessage->pose.orientation.w); TWeakPtr<UTopic, ESPMode::ThreadSafe> SelfPtr(_SelfPtr); AsyncTask(ENamedThreads::GameThread, [this, Pos, Rot, SelfPtr]() { if (!SelfPtr.IsValid()) return; OnPoseStampedMessage(Pos, Rot.Rotator()); }); } break; }
Maybe the answer is really simple but I'm new to ROS :)
from rosintegration.
@DarioMazzanti Thank you very much! I understand how it works now. After editing Topic.h & Topic.cpp the option still doesn't show up in UE4. Is there anything I have to do after editing the files? Like compiling the Topic.cpp file?
from rosintegration.
@DarioMazzanti Thank you! Didn't know. It works! 😃
from rosintegration.
Related Issues (20)
- No Topics in Rosbridge with docker HOT 2
- Plugin can not be compiled HOT 1
- Failed to built on UE 4.25 HOT 2
- Why msg/Int16.msg in ros not supported in ROSIntegration? How to custom it with BSON? HOT 1
- BSON lib doesn't support Int16 which is supported in ROS. HOT 1
- Why UE4 becomes stuttered after play if the rosbridge_server in another machine doesn't open? HOT 2
- Fork with visualizations, websockets, latest rosbridge_suite, etc. HOT 5
- Subsystem Game Instance HOT 3
- PR #180 Gives Compile Error in UE4 HOT 4
- Use of undeclared Identifier GetGameInstance HOT 1
- How can I solve the problem of `sensor_msgs/CameraInfo does not have a field d` HOT 2
- ROS bridge for UE 5 HOT 4
- (UE5 / Humble) De-/serialization problem when trying to publish sensor_msgs/Image or CompressedImage HOT 3
- ROS Message Types as UObjects? HOT 1
- Crashing and lag spikes. HOT 1
- Accessing the variable that was updated from a subscribed topic
- HoloLens2 packaging fails HOT 2
- (UE5/Melodic) Subscribing to color compressedImage and depth Image at the same time HOT 1
- /Clock publish rate too low. HOT 2
- sensor_msgs/Image Issue HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rosintegration.