Skip to content

Commit

Permalink
PR IntelRealSense#13104 from Eran: rs-dds-config
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel authored Jul 7, 2024
2 parents 660d533 + 11cd58f commit 3d4398f
Show file tree
Hide file tree
Showing 22 changed files with 907 additions and 120 deletions.
2 changes: 1 addition & 1 deletion include/librealsense2/hpp/rs_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,8 @@ namespace rs2
rs2_error* e = nullptr;
auto buffer = rs2_build_debug_protocol_command(_dev.get(), opcode, param1, param2, param3, param4,
(void*)data.data(), (uint32_t)data.size(), &e);
std::shared_ptr<const rs2_raw_data_buffer> list(buffer, rs2_delete_raw_data);
error::handle(e);
std::shared_ptr< const rs2_raw_data_buffer > list( buffer, rs2_delete_raw_data );

auto size = rs2_get_raw_data_size(list.get(), &e);
error::handle(e);
Expand Down
2 changes: 1 addition & 1 deletion src/platform/uvc-option.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class uvc_xu_option : virtual public option
T t;
if( ! dev.get_xu( _xu, _id, reinterpret_cast< uint8_t * >( &t ), sizeof( T ) ) )
throw invalid_value_exception( rsutils::string::from()
<< "get_xu(id=" << std::to_string( _id ) << ") failed!"
<< "get_xu(id=" << _id << ") failed!"
<< " Last Error: " << strerror( errno ) );
if (_parsing_modifier)
return _parsing_modifier(t);
Expand Down
21 changes: 12 additions & 9 deletions third-party/realdds/doc/control.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,18 @@ A device can run the flow when in recovery mode or during normal operation:

Starts the DFU process.

The device will subscribe to a `dfu` topic under the topic root (accepting a `blob` message, reliable). Enough memory should be allocated to make sure we're ready to receive the image before a reply is sent.
The device will subscribe to a `dfu` topic under the topic root (accepting a `blob` message, reliable).

```JSON
{
"id": "dfu-start",
"size": 2097152,
"crc": 65358876
}
```

- A `size` will be communicated to ensure enough memory is allocated and we're ready to receive the image
- The `crc` is needed to verify the image is intact

A reply should indicate the image is ready to be received.

Expand All @@ -269,14 +280,6 @@ Errors can look like this:
```
If status is not `OK`, then the device is expected to go back to the pre-DFU state and the process needs to start over.

On success, the device may send back a `"crc": <crc32-value>` or `"size": <number-of-bytes>`, to help debug, or any other relevant content:
```JSON
{
"id": "dfu-ready",
"crc": <value>
}
```

The `dfu` subscription can be removed at this time.

#### `dfu-apply`
Expand Down
4 changes: 2 additions & 2 deletions third-party/realdds/include/realdds/dds-option.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#pragma once

#include <rsutils/json.h>
#include <rsutils/string/ip-address.h>
#include <rsutils/type/ip-address.h>

#include <string>
#include <vector>
Expand Down Expand Up @@ -194,7 +194,7 @@ class dds_ip_option : public dds_string_option
using super = dds_string_option;

public:
using ip_address = rsutils::string::ip_address;
using ip_address = rsutils::type::ip_address;

char const * value_type() const override { return "ip-address"; }

Expand Down
24 changes: 23 additions & 1 deletion third-party/realdds/include/realdds/dds-time.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,29 @@ inline long double time_to_double( eprosima::fastrtps::rtps::Time_t const & t )
}


std::string time_to_string( dds_time const & t );
struct time_to_string
{
int32_t _seconds;
uint32_t _nanosec;

time_to_string( dds_time const & t )
: _seconds( t.seconds )
, _nanosec( t.nanosec )
{}

time_to_string( eprosima::fastrtps::rtps::Time_t const & t )
: _seconds( t.seconds() )
, _nanosec( t.nanosec() )
{}

time_to_string( int32_t seconds, uint32_t nanoseconds )
: _seconds( seconds )
, _nanosec( nanoseconds )
{}
};


std::ostream & operator<<( std::ostream &, time_to_string const & );


// Easy way to format DDS time to a legible string, in milliseconds
Expand Down
14 changes: 12 additions & 2 deletions third-party/realdds/py/pyrealdds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ PYBIND11_MODULE(NAME, m) {
.def_static( "from_ns", []( dds_nsec ns ) { return realdds::time_from( ns ); } )
.def_static( "from_double", []( long double d ) { return realdds::dds_time( d ); } )
.def( "to_double", py::overload_cast< dds_time const & >( &realdds::time_to_double ) )
.def( "__repr__", &realdds::time_to_string )
.def( "__repr__", []( dds_time const & self ) -> std::string { return rsutils::string::from( realdds::time_to_string( self ) ); } )
.def( pybind11::self == pybind11::self )
.def( pybind11::self != pybind11::self );

Expand Down Expand Up @@ -503,7 +503,17 @@ PYBIND11_MODULE(NAME, m) {
.def( py::init<>() )
.def( "identity", []( dds_sample const & self ) { return self.sample_identity; } )
.def( "source_timestamp", []( dds_sample const & self ) { return self.source_timestamp.to_ns(); } )
.def( "reception_timestamp", []( dds_sample const & self ) { return self.reception_timestamp.to_ns(); } );
.def( "reception_timestamp", []( dds_sample const & self ) { return self.reception_timestamp.to_ns(); } )
.def( "__repr__",
[]( dds_sample const & self )
{
std::ostringstream os;
os << "<sample #" << self.sample_identity.sequence_number();
os << " @ " << realdds::time_to_string( self.reception_timestamp );
os << " from " << realdds::print_guid( self.sample_identity.writer_guid() );
os << ">";
return os.str();
} );


py::class_< flexible_msg >( message, "flexible" )
Expand Down
18 changes: 15 additions & 3 deletions third-party/realdds/scripts/topic-sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def time_arg(x):
args.add_argument( '--wait', metavar='<seconds>', type=time_arg, default=5., help='seconds to wait for writers (default 5; 0=disable)' )
args.add_argument( '--time', metavar='<seconds>', type=time_arg, help='runtime before stopping, in seconds (default 0=forever)' )
args.add_argument( '--not-ready', action='store_true', help='start output immediately, without waiting for all topics' )
args.add_argument( '--field', metavar='<name>', help='name to extract from the flexible JSON (or whole JSON is printed, indented)' )
args = args.parse_args()

if args.quiet:
Expand All @@ -43,6 +44,10 @@ def e( *a, **kw ):

import pyrealdds as dds
import time
from datetime import datetime

def timestamp():
return datetime.now().time()

dds.debug( args.debug )

Expand All @@ -66,7 +71,7 @@ def on_blob_available( reader ):
if not got_something:
raise RuntimeError( "expected message not received!" )
break
i( f'{msg}', )
i( f'{timestamp()} {msg}', )
got_something = True
for topic_path in args.blob or []:
reader = dds.topic_reader( dds.message.blob.create_topic( participant, topic_path ))
Expand All @@ -90,7 +95,7 @@ def on_image_available( reader ):
if not got_something:
raise RuntimeError( "expected message not received!" )
break
i( f'{msg}', )
i( f'{timestamp()} {msg}', )
got_something = True
for topic_path in args.image or []:
reader = dds.topic_reader( dds.message.image.create_topic( participant, topic_path ))
Expand All @@ -114,7 +119,14 @@ def on_flexible_available( reader ):
if not got_something:
raise RuntimeError( "expected message not received!" )
break
i( f'{json.dumps( msg.json_data(), indent=4 )}', )
j = msg.json_data()
if args.field:
s = j.get( args.field )
if not s:
s = json.dumps( j ) # without indent
else:
s = json.dumps( j, indent=4 )
i( f'{timestamp()} {sample} {s}', )
got_something = True
for topic_path in args.flexible_be or []:
reader = dds.topic_reader( dds.message.flexible.create_topic( participant, topic_path ))
Expand Down
2 changes: 1 addition & 1 deletion third-party/realdds/src/dds-option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ json dds_enum_option::to_json() const
}


/*static*/ rsutils::string::ip_address dds_ip_option::check_ip( json const & value )
/*static*/ dds_ip_option::ip_address dds_ip_option::check_ip( json const & value )
{
ip_address ip( value.string_ref() );
if( ip.is_valid() )
Expand Down
28 changes: 16 additions & 12 deletions third-party/realdds/src/dds-time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@
namespace realdds {


std::string time_to_string( dds_time const & t )
std::ostream & operator<<( std::ostream & os, time_to_string const & t )
{
if( t == eprosima::fastrtps::c_TimeInvalid )
return std::string( "INVALID", 7 );
std::string nsec = std::to_string( t.nanosec );
if( t.nanosec )
{
// DDS spec 2.3.2: "the nanosec field must verify 0 <= nanosec < 1000000000"
nsec.insert( 0, 9 - nsec.length(), '0' ); // will throw if more than 9 digits!
while( nsec.length() > 1 && nsec.back() == '0' )
nsec.pop_back();
}
return std::to_string( t.seconds ) + '.' + nsec;
if( t._seconds == eprosima::fastrtps::c_TimeInvalid.seconds
&& t._nanosec == eprosima::fastrtps::c_TimeInvalid.nanosec )
return os << "INVALID";

os << t._seconds << '.';

if( ! t._nanosec )
return os << '0';

std::string nsec = std::to_string( t._nanosec );
// DDS spec 2.3.2: "the nanosec field must verify 0 <= nanosec < 1000000000"
nsec.insert( 0, 9 - nsec.length(), '0' ); // will throw if more than 9 digits!
while( nsec.length() > 1 && nsec.back() == '0' )
nsec.pop_back();
return os << nsec;
}


Expand Down
15 changes: 15 additions & 0 deletions third-party/rsutils/include/rsutils/exceptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once


namespace rsutils {


// Enum that can be used to make code more verbose:
// ip_address( "blah", throw_if_not_valid );
//
enum _throw_if_not_valid { throw_if_not_valid };


}
59 changes: 0 additions & 59 deletions third-party/rsutils/include/rsutils/string/ip-address.h

This file was deleted.

77 changes: 77 additions & 0 deletions third-party/rsutils/include/rsutils/type/ip-address.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once

#include <rsutils/json-fwd.h>
#include <rsutils/exceptions.h>

#include <string>
#include <iosfwd>


namespace rsutils {
namespace type {


// An IP address, version 4.
//
// 4 decimals separated by a period:
// W.X.Y.Z
//
class ip_address
{
uint8_t _b[4];

public:
ip_address() : _b{ 0 } {}
ip_address( uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4 ) : _b{ b1, b2, b3, b4 } {}
ip_address( uint8_t const b[4] ) : _b{ b[0], b[1], b[2], b[3] } {}
ip_address( ip_address const & ) = default;

explicit ip_address( std::string const & ) noexcept;
explicit ip_address( std::string const &, _throw_if_not_valid );

ip_address & operator=( ip_address const & ) = default;

bool is_valid() const { return _b[0] || _b[1] || _b[2] || _b[3]; }

bool empty() const { return ! _b[0] && ! _b[1] && ! _b[2] && ! _b[3]; }
void clear() { _b[0] = _b[1] = _b[2] = _b[3] = 0; }

std::string to_string() const;

bool operator==( ip_address const & other ) const
{
return _b[0] == other._b[0] && _b[1] == other._b[1] && _b[2] == other._b[2] && _b[3] == other._b[3];
}
bool operator!=( ip_address const & other ) const
{
return _b[0] != other._b[0] || _b[1] != other._b[1] || _b[2] != other._b[2] || _b[3] != other._b[3];
}

void get_components( uint8_t & b0, uint8_t & b1, uint8_t & b2, uint8_t & b3 ) const
{
b0 = _b[0];
b1 = _b[1];
b2 = _b[2];
b3 = _b[3];
}
void get_components( uint8_t b[4] ) const { get_components( b[0], b[1], b[2], b[3] ); }

private:
friend std::ostream & operator<<( std::ostream &, ip_address const & );
};


std::ostream & operator<<( std::ostream &, ip_address const & );


// Allow j["key"] = ip_address( "1.2.3.4" );
void to_json( rsutils::json &, const ip_address & );
// Allow j.get< ip_address >();
void from_json( rsutils::json const &, ip_address & );
// See https://github.com/nlohmann/json#arbitrary-types-conversions


} // namespace type
} // namespace rsutils
Loading

0 comments on commit 3d4398f

Please sign in to comment.