-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IMU with Motion topic #11990
IMU with Motion topic #11990
Conversation
@@ -32,9 +32,9 @@ public enum StreamFormat { | |||
Z16H(28), | |||
FG(29), | |||
Y411(30), | |||
Y16I(31); | |||
COMBINED_MOTION(31); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there a Y16I format at some point?
If changing this file, I think that Z16H is unused anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there a Y16I format at some point?
There was (though I don't think it was released) -- and then was removed. The rs2_stream
enum no longer has it, so I made sure this reflected the current state of the enum.
We cannot go and remove the old enum values (which were released).
imu_data().orientation_covariance() = { -1., 0., 0., 0., 0., 0., 0., 0., 0. }; | ||
// "you can initiate the sensor covariance matrix by giving some small values on the diagonal" | ||
double const cov = 0.01; // TODO from context? | ||
imu_data().linear_acceleration_covariance() = { cov, 0., 0., 0., cov, 0., 0., 0., cov }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the first element be set to -1 (as in orientation?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do have linear acceleration (accel) and angular velocity (gyro).
This is a copy of the code from the ROS wrapper.
src/dds/rs-dds-sensor-proxy.cpp
Outdated
data.frame_number; // filled in only once metadata is known | ||
data.timestamp // in ms | ||
= static_cast< rs2_time_t >( realdds::time_to_double( imu.timestamp() ) * 1e3 ); | ||
data.timestamp_domain = RS2_TIMESTAMP_DOMAIN_GLOBAL_TIME; // leave default (hardware domain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment about HW domain does not match actual "global time" value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take out the "global time" setting and leave at default. I changed it when trying stuff.
Bottom line:
Camera-generated domains will always be HW times and, when global time is enable, converted.
Adapter-sent domains may already be global (from the adapter's side) but will be treated as HW meaning may get converted to the client's global time.
src/dds/rs-dds-device-proxy.cpp
Outdated
if( video_stream ) | ||
{ | ||
auto video_profile = std::static_pointer_cast< realdds::dds_video_stream_profile >( profile ); | ||
auto added_stream_profile = sensor.add_video_stream( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not call this raw_stream_profile
? And the comment can apply to both motion and video
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, changing
sid_index type_and_index( profile->get_stream_type(), profile->get_stream_index()); | ||
if( auto p = std::dynamic_pointer_cast< librealsense::video_stream_profile_interface >( profile ) ) | ||
{ | ||
LOG_DEBUG( " " << get_string( p->get_stream_type() ) << ' ' << p->get_stream_index() << ' ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that framerate should follow the resolution and format after.
E.g. 1280x720@30 RGB8 (instead of 1280x720 RGB8 @ 30)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK :)
} | ||
|
||
server->init_profiles( profiles, default_profile_index ); | ||
|
||
// Set stream intrinsics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this comment, it is now redundant and does not relate to metadata handling in this if
statement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
{ | ||
video_server->set_intrinsics( std::move( stream_name_to_video_intrinsics[stream_name] ) ); | ||
// Set stream metadata support (currently if the device supports metadata all streams does) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment correct to video streams only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but it's inside a block only for video streams... You want me to change?
stream_profiles.end(), | ||
[&]( const rs2::stream_profile & sp ) | ||
{ | ||
switch( sp.stream_type() ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why switch
and not if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were other cases, maybe? Changed to if.
if( auto video = std::dynamic_pointer_cast< realdds::dds_video_stream_server >( server ) ) | ||
{ | ||
// RS2_STREAM_DEPTH, RS2_STREAM_COLOR, RS2_STREAM_INFRARED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confidence?
I think that this comment is redundant. Same for the motion comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
} | ||
{ | ||
// RS2_STREAM_GYRO, RS2_STREAM_ACCEL | ||
static realdds::topics::imu_msg imu; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static variables here can be members.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but then you have to #include the imu message, etc.
I chose to split the start() call into two parts and pass the IMU "context" (message plus mutex) in.
auto const stream_type = stream_profile.stream_type(); | ||
dds_time const timestamp // in sec.nsec | ||
( static_cast< long double >( f.get_timestamp() ) / 1e3 ); | ||
|
||
if( auto video = std::dynamic_pointer_cast< realdds::dds_video_stream_server >( server ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this logic to a helper function.
Let's keep out lamdas small :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easier said than done. Right now I left it the same (though changed -- check it out).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like all you need to pass the helper function is a reference to sensor
{ | ||
if( sp.stream_type() != RS2_STREAM_ACCEL ) | ||
continue; | ||
if( sp.format() != rs2_profile.format() ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is format check necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not...
|
||
#### Metadata | ||
|
||
A single metadata message is expected for all messages from the same sensor (so one for depth, IR left, IR right). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we send a metadata message per active stream, not per active sensor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, yes, you're correct. And after talking to Evgeni, I think I'll take that statement back.
@@ -464,6 +456,28 @@ find_profile( std::shared_ptr< realdds::dds_stream_server > const & stream, | |||
} | |||
|
|||
|
|||
std::shared_ptr< realdds::dds_stream_server > | |||
lrs_device_controller::frame_to_streaming_server( rs2::frame const & f, rs2::stream_profile * p_profile ) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need p_profile
and all this code handling it? Just to avoid calling f.get_profile()
outside this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, yes -- it's actually two calls into librealsense and populations of data. Why do something twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much less readable, not relevant for all cases and I am not sure if it more efficient...
Had to read several times to understand all this handling with profile/p_profile/profile_.
Passing another parameter, creating a default initialized profile that is not always needed, if
statement... just to avoid an API call...
std::mutex mutex; | ||
}; | ||
sensor.start( | ||
[this, imu = std::make_shared< imu_context >()]( rs2::frame f ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When called from two different threads imu
will be the same object for both? Isn't another instance is created?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, there should be a new make_shared
each time a sensor is started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I.e., when the on_start_sensor
lambda is called.
auto xyz = reinterpret_cast< float const * >( f.get_data() ); | ||
if( RS2_STREAM_ACCEL == stream_profile.stream_type() ) | ||
{ | ||
std::unique_lock< std::mutex > lock( imu->mutex ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that std::lock_guard
is more efficient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm, yes, I don't know how it got there. But essentially the same, maybe slightly more overhead. I'll fix if other changes are needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
IMU DDS implementation is now combined into a single topic:
sensor_msgs::msg::Imu
format, including orientation, linear acceleration (Accel), and angular velocity (Gyro) in one messageunite_imu_method
value 1 (copy) - added LRS-834 for interpolationRS2_STREAM_MOTION
in formatRS2_FORMAT_COMBINED_MOTION
streamAlong the way:
Tracked on [LRS-796]