From d3d266264c3cd177d822bebe0c496d074400b750 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 15:36:26 +0300 Subject: [PATCH 01/50] NodeStatus extended with a 32-bit vendor-specific status code --- dsdl/uavcan/protocol/550.NodeStatus.uavcan | 9 ++++++--- libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp | 1 + libuavcan/test/protocol/node_status_monitor.cpp | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dsdl/uavcan/protocol/550.NodeStatus.uavcan b/dsdl/uavcan/protocol/550.NodeStatus.uavcan index 0d777fc759..934e741c12 100644 --- a/dsdl/uavcan/protocol/550.NodeStatus.uavcan +++ b/dsdl/uavcan/protocol/550.NodeStatus.uavcan @@ -1,6 +1,9 @@ # # Abstract node status information. # Any UAVCAN node is required to publish this message periodically. +# It is NOT recommended to change its publication rate at run time. +# +# See http://uavcan.org/Standard_data_types_and_application_level_functions # uint16 MAX_PUBLICATION_PERIOD_MS = 1000 @@ -13,9 +16,6 @@ uint16 OFFLINE_TIMEOUT_MS = 3000 uint28 uptime_sec # Status code should be used to reflect the node status in the most abstract way. -# Use cases: top-level onboard computer should not allow the UAV to begin normal operation -# unless all nodes report OK. If a mission critical node reports CRITICAL status, current -# mission should be immediately yet safely aborted (e.g. RTL). # OFFLINE status can be actually reported by the node to explicitly inform other network # participants that the sending node is about to shutdown. In this case other nodes will not # have to wait OFFLINE_TIMEOUT_MS before they detect that the node is no longer available. @@ -25,3 +25,6 @@ uint4 STATUS_WARNING = 2 uint4 STATUS_CRITICAL = 3 uint4 STATUS_OFFLINE = 15 uint4 status_code + +# Optional, vendor-specific node status code, e.g. a fault code or a status bitmask. +uint32 vendor_specific_status_code diff --git a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp index d1671c4ef5..852f79a208 100644 --- a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp +++ b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp @@ -60,6 +60,7 @@ TEST(Dsdl, Streaming) "status: \n" " uptime_sec: 0\n" " status_code: 0\n" + " vendor_specific_status_code: 0\n" "software_version: \n" " major: 0\n" " minor: 0\n" diff --git a/libuavcan/test/protocol/node_status_monitor.cpp b/libuavcan/test/protocol/node_status_monitor.cpp index 3a2db1394b..bfb97b0053 100644 --- a/libuavcan/test/protocol/node_status_monitor.cpp +++ b/libuavcan/test/protocol/node_status_monitor.cpp @@ -20,7 +20,7 @@ static void publishNodeStatus(CanDriverMock& can, uavcan::NodeID node_id, uavcan // Manual message publication ASSERT_LT(0, uavcan::protocol::NodeStatus::encode(msg, codec)); - ASSERT_GE(7, buffer.getMaxWritePos()); + ASSERT_GE(8, buffer.getMaxWritePos()); // DataTypeID data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame From 4239c2edddb9cb922f80873e25129368dd9bf4e2 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 15:55:53 +0300 Subject: [PATCH 02/50] Optimized NodeStatusMonitor --- libuavcan/include/uavcan/protocol/node_status_monitor.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp index 1c499014ee..962e6f93ff 100644 --- a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp +++ b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp @@ -45,7 +45,12 @@ private: void (NodeStatusMonitor::*)(const ReceivedDataStructure&)> NodeStatusCallback; - Subscriber sub_; + /* + * We'll be able to handle this many nodes in the network without any dynamic memory. + */ + enum { NumStaticReceivers = 64 }; + + Subscriber sub_; struct Entry { From f5526a4d6d84a40b3c1b5087d14eab5d02401878 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 16:11:22 +0300 Subject: [PATCH 03/50] GNSS messages updated --- dsdl/uavcan/equipment/gnss/300.Fix.uavcan | 22 ++++++++++++++++++- .../equipment/gnss/302.Auxiliary.uavcan | 2 -- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/dsdl/uavcan/equipment/gnss/300.Fix.uavcan b/dsdl/uavcan/equipment/gnss/300.Fix.uavcan index 8e3997307e..2613365065 100644 --- a/dsdl/uavcan/equipment/gnss/300.Fix.uavcan +++ b/dsdl/uavcan/equipment/gnss/300.Fix.uavcan @@ -4,8 +4,22 @@ uavcan.Timestamp timestamp # Global network-synchronized time, if available, otherwise zero -uavcan.Timestamp gnss_timestamp # GNSS timestamp (UTC is preferred), if available, otherwise zero +# +# Time solution +# +# The following rules apply: +# - if num_leap_seconds is zero, it is assumed that its value is unknown, and that gnss_timestamp contains GPS time. +# - if num_leap_seconds is nonzero, it is assumed that its value is known, and that gnss_timestamp contains UTC time. +# +# At the time of February 2015, the number of leap seconds is 26. +# +uavcan.Timestamp gnss_timestamp # GNSS timestamp, if available, otherwise zero +uint8 num_leap_seconds + +# +# Position and velocity solution +# int37 longitude_deg_1e8 # Longitude degrees multiplied by 1e8 (approx. 1 mm per LSB) int37 latitude_deg_1e8 # Latitude degrees multiplied by 1e8 (approx. 1 mm per LSB on equator) int27 height_ellipsoid_mm # Height above ellipsoid in millimeters @@ -13,6 +27,9 @@ int27 height_msl_mm # Height above mean sea level in millimeters float16[3] ned_velocity # NED frame (north-east-down) in meters per second +# +# Fix status +# uint6 sats_used uint2 STATUS_NO_FIX = 0 @@ -21,6 +38,9 @@ uint2 STATUS_2D_FIX = 2 uint2 STATUS_3D_FIX = 3 uint2 status +# +# Precision +# float16 pdop float16[<=9] position_covariance # m^2 diff --git a/dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan b/dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan index 6321bca887..43bb3c56be 100644 --- a/dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan +++ b/dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan @@ -13,5 +13,3 @@ float16 edop uint7 sats_visible # All visible sats of all available GNSS (e.g. GPS, GLONASS, etc) uint6 sats_used # All used sats of all available GNSS - -bool differential_corrections_applied From ec10722d59b982c1ad597c76245d85119db0d8b0 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 18:56:37 +0300 Subject: [PATCH 04/50] GNSS Fix clarifications --- dsdl/uavcan/equipment/gnss/300.Fix.uavcan | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dsdl/uavcan/equipment/gnss/300.Fix.uavcan b/dsdl/uavcan/equipment/gnss/300.Fix.uavcan index 2613365065..273daaa799 100644 --- a/dsdl/uavcan/equipment/gnss/300.Fix.uavcan +++ b/dsdl/uavcan/equipment/gnss/300.Fix.uavcan @@ -8,13 +8,18 @@ uavcan.Timestamp timestamp # Global network-synchronized time, if availa # Time solution # # The following rules apply: -# - if num_leap_seconds is zero, it is assumed that its value is unknown, and that gnss_timestamp contains GPS time. -# - if num_leap_seconds is nonzero, it is assumed that its value is known, and that gnss_timestamp contains UTC time. +# - if num_leap_seconds = 0, it is assumed that its value is unknown, and that gnss_timestamp contains UTC time. +# - if num_leap_seconds = 1, it is assumed that its value is unknown, and that gnss_timestamp contains GPS time. +# - if num_leap_seconds = 2, it is assumed that its value is unknown, and that gnss_timestamp contains TAI time. +# - if num_leap_seconds > 2, it is assumed that its value is KNOWN, and that gnss_timestamp contains UTC time. # # At the time of February 2015, the number of leap seconds is 26. # uavcan.Timestamp gnss_timestamp # GNSS timestamp, if available, otherwise zero +uint8 NUM_LEAP_SECONDS_UNKNOWN_GNSS_TIME_UTC = 0 # num_leap_seconds is unknown, gnss_timestamp contains UTC time +uint8 NUM_LEAP_SECONDS_UNKNOWN_GNSS_TIME_GPS = 1 # num_leap_seconds is unknown, gnss_timestamp contains GPS time +uint8 NUM_LEAP_SECONDS_UNKNOWN_GNSS_TIME_TAI = 2 # num_leap_seconds is unknown, gnss_timestamp contains TAI time uint8 num_leap_seconds # From d40a1397e7a6214a9896b95c4823c9e29a70aa5a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 23:22:48 +0300 Subject: [PATCH 05/50] Elaborated SaveErase --- dsdl/uavcan/protocol/param/598.SaveErase.uavcan | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dsdl/uavcan/protocol/param/598.SaveErase.uavcan b/dsdl/uavcan/protocol/param/598.SaveErase.uavcan index 4d4d933fd4..2f268283d1 100644 --- a/dsdl/uavcan/protocol/param/598.SaveErase.uavcan +++ b/dsdl/uavcan/protocol/param/598.SaveErase.uavcan @@ -1,10 +1,16 @@ # # Service to control non-volatile parameter storage. # +# SAVE operation instructs the remote node to save the current configuration parameters to the non-volatile +# storage. The device may require a restart in order for some changes to take effect. +# +# ERASE operation instructs the remote node to clear its configuration storage and reinitialize the parameters +# with their default values. The device may require a restart in order for some changes to take effect. +# -uint2 OPCODE_SAVE = 0 # Save all parameters to non-volatile storage -uint2 OPCODE_ERASE = 1 # Clear the non-volatile storage; actual parameter values may or may not be affected -uint2 opcode +uint8 OPCODE_SAVE = 0 # Save all parameters to non-volatile storage. +uint8 OPCODE_ERASE = 1 # Clear the non-volatile storage; some changes may take effect only after reboot. +uint8 opcode --- From 54696997afb507cff791093cf431011c55567596 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 23:24:06 +0300 Subject: [PATCH 06/50] debug KeyValue refers to param.Value --- dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan index be9668cfaf..6e0c29ccf7 100644 --- a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan +++ b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan @@ -2,14 +2,6 @@ # Generic named parameter (key/value pair). # -uint3 TYPE_UNDEF = 0 -uint3 TYPE_INTEGER = 1 -uint3 TYPE_FLOAT = 2 -uint3 TYPE_STRING = 3 -uint3 TYPE_BYTES = 4 -uint3 type - uint8[<64] key -float64[<=1] numeric_value # For type = INTEGER, FLOAT -uint8[<256] binary_value # For type = STRING, BYTES +uavcan.protocol.param.Value value From a50399266a232ab6d0a28d4aa90b20a068bde68d Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 3 Feb 2015 23:41:34 +0300 Subject: [PATCH 07/50] param.GetSet - string parameters support --- dsdl/uavcan/protocol/param/599.GetSet.uavcan | 18 +++++++++++------- dsdl/uavcan/protocol/param/Value.uavcan | 10 ++++++---- dsdl/uavcan/protocol/param/ValueString.uavcan | 5 +++++ 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 dsdl/uavcan/protocol/param/ValueString.uavcan diff --git a/dsdl/uavcan/protocol/param/599.GetSet.uavcan b/dsdl/uavcan/protocol/param/599.GetSet.uavcan index 73f5d74dab..a5da59837e 100644 --- a/dsdl/uavcan/protocol/param/599.GetSet.uavcan +++ b/dsdl/uavcan/protocol/param/599.GetSet.uavcan @@ -2,19 +2,23 @@ # Get or set a parameter by name or by index. # -# If set - parameter will be assigned this value, then the new value will be returned -# If not set - current parameter value will be returned +# If set - parameter will be assigned this value, then the new value will be returned. +# If not set - current parameter value will be returned. +# Refer to the definition of Value for details. Value value -# Index of the parameter starting from 0; ignored if name is nonempty +# Index of the parameter starting from 0; ignored if name is nonempty. uint8 index -# Name of the parameter; always preferred over index if nonempty -uint8[<=40] name +# Name of the parameter; always preferred over index if nonempty. +uint8[<64] name --- -# Actual parameter value. For write requests it must contain the newly assigned parameter value. +# Actual parameter value. +# For set requests, it should contain the actual parameter value after the set request was +# executed. The objective is to let the client know if the value could not be updated, e.g. +# due to its range violation, etc. # Empty value indicates that there is no such parameter. Value value @@ -23,4 +27,4 @@ Value max_value # Optional Value min_value # Optional # Empty name in response indicates that there is no such parameter -uint8[<=40] name +uint8[<64] name diff --git a/dsdl/uavcan/protocol/param/Value.uavcan b/dsdl/uavcan/protocol/param/Value.uavcan index 083db54bdf..44bf6f98e2 100644 --- a/dsdl/uavcan/protocol/param/Value.uavcan +++ b/dsdl/uavcan/protocol/param/Value.uavcan @@ -1,8 +1,10 @@ # # Single parameter value. -# The actual type should be detected from the available values, as described below. +# The actual type should be inferred from the available values, as described below. +# If none of the values below are present, the value is considered empty. # -bool[<=1] value_bool # Preferred over int and float if ambiguous -int64[<=1] value_int # Preferred over float if ambiguous -float32[<=1] value_float +bool[<=1] value_bool # Preferred over int, float and string if ambiguous +int64[<=1] value_int # Preferred over float and string if ambiguous +float32[<=1] value_float # Preferred over string if ambiguous +ValueString[<=1] value_string # This one will be used only if all above are empty diff --git a/dsdl/uavcan/protocol/param/ValueString.uavcan b/dsdl/uavcan/protocol/param/ValueString.uavcan new file mode 100644 index 0000000000..2e44a557a3 --- /dev/null +++ b/dsdl/uavcan/protocol/param/ValueString.uavcan @@ -0,0 +1,5 @@ +# +# This type is nested in Value. +# + +uint8[<=80] value From db0f544af8b3eb65351cb8fcf300a6280e7d8458 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 4 Feb 2015 19:34:22 +0300 Subject: [PATCH 08/50] GNSS Aux moved 302 --> 301 --- .../equipment/gnss/{302.Auxiliary.uavcan => 301.Auxiliary.uavcan} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dsdl/uavcan/equipment/gnss/{302.Auxiliary.uavcan => 301.Auxiliary.uavcan} (100%) diff --git a/dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan b/dsdl/uavcan/equipment/gnss/301.Auxiliary.uavcan similarity index 100% rename from dsdl/uavcan/equipment/gnss/302.Auxiliary.uavcan rename to dsdl/uavcan/equipment/gnss/301.Auxiliary.uavcan From 812f7f45978a8036e22284d58f5ec7c84d1a2967 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 4 Feb 2015 22:02:26 +0300 Subject: [PATCH 09/50] Update 600.Status.uavcan Units removed, since the specification explicitly calls for SI. In this case it means that the units will be dependent on the type of the actuator, e.g. Newtons for linear actuators, and Newton meters for rotational type. Thanks Robert Lefebvre for pointing this out. --- dsdl/uavcan/equipment/actuator/600.Status.uavcan | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsdl/uavcan/equipment/actuator/600.Status.uavcan b/dsdl/uavcan/equipment/actuator/600.Status.uavcan index 16a4125447..600abac1df 100644 --- a/dsdl/uavcan/equipment/actuator/600.Status.uavcan +++ b/dsdl/uavcan/equipment/actuator/600.Status.uavcan @@ -6,8 +6,8 @@ uint8 actuator_id float16 position # Position feedback; same units as command -float16 power # Watt -float16 force # Newton (sign depends on the direction of the force) +float16 power +float16 force # Sign depends on the direction of the force uint7 POWER_RATING_PCT_UNKNOWN = 127 uint7 power_rating_pct # 0 - unloaded, 100 - full load/overload From 444937b8e09ebe5557a7c94d26c80e094ee3c6a0 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 6 Feb 2015 21:52:53 +0300 Subject: [PATCH 10/50] Actuator messages update. Fixes #11 --- .../uavcan/equipment/actuator/600.Status.uavcan | 11 +++++++---- dsdl/uavcan/equipment/actuator/Command.uavcan | 17 +++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/dsdl/uavcan/equipment/actuator/600.Status.uavcan b/dsdl/uavcan/equipment/actuator/600.Status.uavcan index 600abac1df..ef15e5e395 100644 --- a/dsdl/uavcan/equipment/actuator/600.Status.uavcan +++ b/dsdl/uavcan/equipment/actuator/600.Status.uavcan @@ -5,9 +5,12 @@ uint8 actuator_id -float16 position # Position feedback; same units as command -float16 power -float16 force # Sign depends on the direction of the force +# +# Whether the units are linear or angular depends on the actuator type (refer to the Command data type). +# +float16 position # meter or radian +float16 force # Newton or Newton metre +float16 speed # meter per second or radian per second uint7 POWER_RATING_PCT_UNKNOWN = 127 -uint7 power_rating_pct # 0 - unloaded, 100 - full load/overload +uint7 power_rating_pct # 0 - unloaded, 100 - full load diff --git a/dsdl/uavcan/equipment/actuator/Command.uavcan b/dsdl/uavcan/equipment/actuator/Command.uavcan index 2728d682c3..e4d3d74084 100644 --- a/dsdl/uavcan/equipment/actuator/Command.uavcan +++ b/dsdl/uavcan/equipment/actuator/Command.uavcan @@ -6,10 +6,15 @@ uint8 actuator_id # -# Recommended units are, either: -# - Unitless [-1; 1] -# - Angular position in radians -# - Linear position in meters -# Status report should normally use the same units. +# Whether the units are linear or angular depends on the actuator type. # -float16 command +uint4 COMMAND_TYPE_UNITLESS = 0 # [-1, 1] +uint4 COMMAND_TYPE_POSITION = 1 # meter or radian +uint4 COMMAND_TYPE_FORCE = 2 # Newton or Newton metre +uint4 COMMAND_TYPE_SPEED = 3 # meter per second or radian per second +uint4 command_type + +# +# Value of the above type +# +float16 command_value From 211b90fbaf3ef2303a9ae711fba2dc18399ce33a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 6 Feb 2015 21:55:41 +0300 Subject: [PATCH 11/50] Airspeed message update. Thanks Holger Steinhaus and Jonathan Challinger. --- dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan b/dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan index ee366fcb55..46306b28ff 100644 --- a/dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan +++ b/dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan @@ -1,6 +1,10 @@ # -# True airspeed in meters per second. +# IAS and TAS in meters per second. +# Unknown values should be assigned NAN. # +float16 indicated_airspeed +float16 indicated_airspeed_variance + float16 true_airspeed float16 true_airspeed_variance From 84e22f1fb794946fd5efb34a0310c50225baa2e4 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 8 Feb 2015 01:34:03 +0300 Subject: [PATCH 12/50] param: Max parameter name length increased to 80 characters --- dsdl/uavcan/protocol/param/599.GetSet.uavcan | 4 ++-- dsdl/uavcan/protocol/param/ValueString.uavcan | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dsdl/uavcan/protocol/param/599.GetSet.uavcan b/dsdl/uavcan/protocol/param/599.GetSet.uavcan index a5da59837e..5a3746f002 100644 --- a/dsdl/uavcan/protocol/param/599.GetSet.uavcan +++ b/dsdl/uavcan/protocol/param/599.GetSet.uavcan @@ -11,7 +11,7 @@ Value value uint8 index # Name of the parameter; always preferred over index if nonempty. -uint8[<64] name +uint8[<=80] name --- @@ -27,4 +27,4 @@ Value max_value # Optional Value min_value # Optional # Empty name in response indicates that there is no such parameter -uint8[<64] name +uint8[<=80] name diff --git a/dsdl/uavcan/protocol/param/ValueString.uavcan b/dsdl/uavcan/protocol/param/ValueString.uavcan index 2e44a557a3..1607f0935f 100644 --- a/dsdl/uavcan/protocol/param/ValueString.uavcan +++ b/dsdl/uavcan/protocol/param/ValueString.uavcan @@ -2,4 +2,4 @@ # This type is nested in Value. # -uint8[<=80] value +uint8[<64] value From 70190658124dcf6ded118125a1ff3a45ba7522de Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 8 Feb 2015 01:34:52 +0300 Subject: [PATCH 13/50] debug: Max key length increased to 80 characters --- dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan index 6e0c29ccf7..b63eeffcb1 100644 --- a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan +++ b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan @@ -2,6 +2,6 @@ # Generic named parameter (key/value pair). # -uint8[<64] key +uint8[<=80] key uavcan.protocol.param.Value value From a8837943a331c284e04f9b8a7fd8d8eb10e51449 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 8 Feb 2015 01:37:47 +0300 Subject: [PATCH 14/50] DSDL clarifications --- dsdl/uavcan/protocol/560.RestartNode.uavcan | 1 + dsdl/uavcan/protocol/debug/1022.StartHILSimulation.uavcan | 1 + dsdl/uavcan/protocol/file/Path.uavcan | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dsdl/uavcan/protocol/560.RestartNode.uavcan b/dsdl/uavcan/protocol/560.RestartNode.uavcan index b4f4672da0..fea950ab23 100644 --- a/dsdl/uavcan/protocol/560.RestartNode.uavcan +++ b/dsdl/uavcan/protocol/560.RestartNode.uavcan @@ -1,6 +1,7 @@ # # Restart the node. # Some nodes may require restart before the new configuration will be applied. +# The request should be rejected if magic_number does not equal MAGIC_NUMBER. # uint40 MAGIC_NUMBER = 0xACCE551B1E diff --git a/dsdl/uavcan/protocol/debug/1022.StartHILSimulation.uavcan b/dsdl/uavcan/protocol/debug/1022.StartHILSimulation.uavcan index c132bcab29..c76ac61593 100644 --- a/dsdl/uavcan/protocol/debug/1022.StartHILSimulation.uavcan +++ b/dsdl/uavcan/protocol/debug/1022.StartHILSimulation.uavcan @@ -1,5 +1,6 @@ # # Start HIL simulation for the specified components. +# The request should be rejected if magic_number does not equal MAGIC_NUMBER. # uint40 MAGIC_NUMBER = 0xACCE551B1E diff --git a/dsdl/uavcan/protocol/file/Path.uavcan b/dsdl/uavcan/protocol/file/Path.uavcan index 8a30feb0be..c89b77b1e5 100644 --- a/dsdl/uavcan/protocol/file/Path.uavcan +++ b/dsdl/uavcan/protocol/file/Path.uavcan @@ -1,7 +1,7 @@ # # Nested type. -# File system path in ASCII or UTF8. -# The only valid separator is forward flash. +# File system path in UTF8. +# The only valid separator is forward slash. # uint8 SEPARATOR = '/' From eb72ee1655fc50fdb1b740aeb0ad8a7fc396db0d Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 8 Feb 2015 01:41:33 +0300 Subject: [PATCH 15/50] Max node name length increased to 80 characters --- dsdl/uavcan/protocol/551.GetNodeInfo.uavcan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsdl/uavcan/protocol/551.GetNodeInfo.uavcan b/dsdl/uavcan/protocol/551.GetNodeInfo.uavcan index 9360d59561..110cc2f4c9 100644 --- a/dsdl/uavcan/protocol/551.GetNodeInfo.uavcan +++ b/dsdl/uavcan/protocol/551.GetNodeInfo.uavcan @@ -16,4 +16,4 @@ HardwareVersion hardware_version # Empty string is not a valid node name. # Node name shall not be changed while the node is running. # The naming convention is like of Java packages (reversed internet domain names), e.g. "com.example.project.product". -uint8[<64] name +uint8[<=80] name From 4df5d41c11e39a5cea333011e6aeecdaef554d9f Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 16 Mar 2015 23:38:41 +0300 Subject: [PATCH 16/50] BatteryStatus - vendor-specific fields made reserved --- dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan b/dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan index 0da83846e1..6b164d2f73 100644 --- a/dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan +++ b/dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan @@ -33,8 +33,8 @@ uint11 STATUS_MASK_OVERLOAD = 32 # Safe operating area violation uint11 STATUS_MASK_BAD_BATTERY = 64 # This battery should not be used anymore (e.g. low SOH) uint11 STATUS_MASK_NEED_SERVICE = 128 # This battery requires maintenance (e.g. balancing, full recharge) uint11 STATUS_MASK_BMS_ERROR = 256 # Battery management system/controller error, smart battery interface error -uint11 STATUS_MASK_VENDOR_A = 512 # Vendor-specific flag -uint11 STATUS_MASK_VENDOR_B = 1024 # Vendor-specific flag +uint11 STATUS_MASK_RESERVED_A = 512 # Keep zero +uint11 STATUS_MASK_RESERVED_B = 1024 # Keep zero uint11 status_mask # From 560d9f3930e9fd194f06e7d9ba6b3062834ead22 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 17 Mar 2015 00:00:28 +0300 Subject: [PATCH 17/50] uavcan.nav.* namespace removed --- dsdl/uavcan/nav/540.AttitudeThrustCommand.uavcan | 6 ------ dsdl/uavcan/ranges | 4 ---- 2 files changed, 10 deletions(-) delete mode 100644 dsdl/uavcan/nav/540.AttitudeThrustCommand.uavcan diff --git a/dsdl/uavcan/nav/540.AttitudeThrustCommand.uavcan b/dsdl/uavcan/nav/540.AttitudeThrustCommand.uavcan deleted file mode 100644 index cd4ce9ab50..0000000000 --- a/dsdl/uavcan/nav/540.AttitudeThrustCommand.uavcan +++ /dev/null @@ -1,6 +0,0 @@ -# -# Orientation and thrust setpoint for VTOL crafts. -# - -float16[4] orientation_xyzw -float16 thrust # Normal range [0, 1]; or [-1, 1] if thrust can be reversed diff --git a/dsdl/uavcan/ranges b/dsdl/uavcan/ranges index b44ae3f110..9aaead3289 100644 --- a/dsdl/uavcan/ranges +++ b/dsdl/uavcan/ranges @@ -1,12 +1,8 @@ 256..399 - high priority equipment -540..549 - high priority nav - 550..599 - protocol 600..749 - low priority eqipment -760..766 - low priority nav - 767 - MAVLink From 1a295c0b50409c8da6f40400cb5dc7fdd8ba0120 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 17 Mar 2015 00:02:03 +0300 Subject: [PATCH 18/50] RangeMeasurement update --- .../range_sensor/292.RangeMeasurement.uavcan | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan b/dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan index ab5d6b240d..b90d1a984a 100644 --- a/dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan +++ b/dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan @@ -10,16 +10,16 @@ uavcan.equipment.CoarseOrientation beam_orientation # In body frame float16 field_of_view # Radians -uint4 SENSOR_TYPE_UNDEFINED = 0 -uint4 SENSOR_TYPE_SONAR = 1 -uint4 SENSOR_TYPE_LIDAR = 2 -uint4 SENSOR_TYPE_RADAR = 3 -uint4 sensor_type +uint5 SENSOR_TYPE_UNDEFINED = 0 +uint5 SENSOR_TYPE_SONAR = 1 +uint5 SENSOR_TYPE_LIDAR = 2 +uint5 SENSOR_TYPE_RADAR = 3 +uint5 sensor_type -uint4 READING_TYPE_UNDEFINED = 0 # Range is unknown -uint4 READING_TYPE_VALID_RANGE = 1 # Range field contains valid distance -uint4 READING_TYPE_TOO_CLOSE = 2 # Range field contains min range for the sensor -uint4 READING_TYPE_TOO_FAR = 3 # Range field contains max range for the sensor -uint4 reading_type +uint3 READING_TYPE_UNDEFINED = 0 # Range is unknown +uint3 READING_TYPE_VALID_RANGE = 1 # Range field contains valid distance +uint3 READING_TYPE_TOO_CLOSE = 2 # Range field contains min range for the sensor +uint3 READING_TYPE_TOO_FAR = 3 # Range field contains max range for the sensor +uint3 reading_type float16 range # Meters From ae053fc5a64331aadd59512b6c6a46003b28f93b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 17 Mar 2015 00:02:43 +0300 Subject: [PATCH 19/50] OpticalFlow removed --- .../uavcan/equipment/optical_flow/291.OpticalFlow.uavcan | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 dsdl/uavcan/equipment/optical_flow/291.OpticalFlow.uavcan diff --git a/dsdl/uavcan/equipment/optical_flow/291.OpticalFlow.uavcan b/dsdl/uavcan/equipment/optical_flow/291.OpticalFlow.uavcan deleted file mode 100644 index c6089fe696..0000000000 --- a/dsdl/uavcan/equipment/optical_flow/291.OpticalFlow.uavcan +++ /dev/null @@ -1,9 +0,0 @@ -# -# X/Y velocities estimated by a simple downward looking optical flow sensor. -# - -uavcan.Timestamp timestamp - -float16 linear_velocity_x -float16 linear_velocity_y -float16 linear_velocity_variance From 519a9f22a052ddf58fd6a33df4aa483a429852fc Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 18 Mar 2015 17:32:04 +0300 Subject: [PATCH 20/50] AltitudeAGL removed, because its functionality overlaps with RangeMeasurement. The latter was assigned a new DDTID --- .../range_sensor/290.AltitudeAGL.uavcan | 19 ------------------- ...ent.uavcan => 380.RangeMeasurement.uavcan} | 0 2 files changed, 19 deletions(-) delete mode 100644 dsdl/uavcan/equipment/range_sensor/290.AltitudeAGL.uavcan rename dsdl/uavcan/equipment/range_sensor/{292.RangeMeasurement.uavcan => 380.RangeMeasurement.uavcan} (100%) diff --git a/dsdl/uavcan/equipment/range_sensor/290.AltitudeAGL.uavcan b/dsdl/uavcan/equipment/range_sensor/290.AltitudeAGL.uavcan deleted file mode 100644 index 7ff1af2766..0000000000 --- a/dsdl/uavcan/equipment/range_sensor/290.AltitudeAGL.uavcan +++ /dev/null @@ -1,19 +0,0 @@ -# -# Altitude above ground level. -# A single node can publish measurements from different sensors concurrently. -# - -uavcan.Timestamp timestamp - -float16 altitude_agl # +inf - too far, -inf - too close -float16 altitude_agl_variance # +inf if too close or too far - -float16 sensor_max_range -float16 sensor_min_range - -uint8 SENSOR_UNKNOWN = 0 -uint8 SENSOR_SONAR = 1 -uint8 SENSOR_LASER = 2 -uint8 SENSOR_RADAR = 3 -uint8 SENSOR_CV = 4 -uint8 sensor_type diff --git a/dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan b/dsdl/uavcan/equipment/range_sensor/380.RangeMeasurement.uavcan similarity index 100% rename from dsdl/uavcan/equipment/range_sensor/292.RangeMeasurement.uavcan rename to dsdl/uavcan/equipment/range_sensor/380.RangeMeasurement.uavcan From 86c234fa9b91d1acc7b565c2c343574fe7700a72 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 18 Mar 2015 18:00:58 +0300 Subject: [PATCH 21/50] Gimbal message update --- ...mmand.uavcan => 390.AngularCommand.uavcan} | 23 +++++-------------- .../camera_gimbal/391.GEOPOICommand.uavcan | 23 +++++++++++++++++++ .../{391.Status.uavcan => 392.Status.uavcan} | 0 .../equipment/camera_gimbal/Mode.uavcan | 10 ++++---- 4 files changed, 34 insertions(+), 22 deletions(-) rename dsdl/uavcan/equipment/camera_gimbal/{390.Command.uavcan => 390.AngularCommand.uavcan} (55%) create mode 100644 dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan rename dsdl/uavcan/equipment/camera_gimbal/{391.Status.uavcan => 392.Status.uavcan} (100%) diff --git a/dsdl/uavcan/equipment/camera_gimbal/390.Command.uavcan b/dsdl/uavcan/equipment/camera_gimbal/390.AngularCommand.uavcan similarity index 55% rename from dsdl/uavcan/equipment/camera_gimbal/390.Command.uavcan rename to dsdl/uavcan/equipment/camera_gimbal/390.AngularCommand.uavcan index 36205851ec..98b696947f 100644 --- a/dsdl/uavcan/equipment/camera_gimbal/390.Command.uavcan +++ b/dsdl/uavcan/equipment/camera_gimbal/390.AngularCommand.uavcan @@ -1,31 +1,20 @@ # # Generic camera gimbal control. # +# This message can only be used in the following modes: +# - COMMAND_MODE_ANGULAR_VELOCITY +# - COMMAND_MODE_ORIENTATION_FIXED_FRAME +# - COMMAND_MODE_ORIENTATION_BODY_FRAME +# # # Target operation mode - how to handle this message. +# See the list of acceptable modes above. # Mode mode -# -# This field is only used in the following modes: -# - COMMAND_MODE_ANGULAR_VELOCITY -# - COMMAND_MODE_ORIENTATION_FIXED_FRAME -# - COMMAND_MODE_ORIENTATION_BODY_FRAME # # In the angular velocity mode, this field contains a rate quaternion. # In the orientation mode, this field contains orientation either in fixed frame or in body frame. # float16[4] quaternion_xyzw - -# -# These fields are only used in the following modes: -# - COMMAND_MODE_GEO_POI -# -int32 longitude_deg_1e7 # 1 LSB = 1e-7 deg -int32 latitude_deg_1e7 -int22 height_cm # 1 LSB = 10 mm - -uint2 HEIGHT_REFERENCE_ELLIPSOID = 0 -uint2 HEIGHT_REFERENCE_MEAN_SEA_LEVEL = 1 -uint2 height_reference diff --git a/dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan b/dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan new file mode 100644 index 0000000000..83236d52b0 --- /dev/null +++ b/dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan @@ -0,0 +1,23 @@ +# +# Generic camera gimbal control. +# +# This message can only be used in the following modes: +# - COMMAND_MODE_GEO_POI +# + +# +# Target operation mode - how to handle this message. +# See the list of acceptable modes above. +# +Mode mode + +# +# Coordinates of the POI (point of interest). +# +int32 longitude_deg_1e7 # 1 LSB = 1e-7 deg +int32 latitude_deg_1e7 +int22 height_cm # 1 LSB = 10 mm + +uint2 HEIGHT_REFERENCE_ELLIPSOID = 0 +uint2 HEIGHT_REFERENCE_MEAN_SEA_LEVEL = 1 +uint2 height_reference diff --git a/dsdl/uavcan/equipment/camera_gimbal/391.Status.uavcan b/dsdl/uavcan/equipment/camera_gimbal/392.Status.uavcan similarity index 100% rename from dsdl/uavcan/equipment/camera_gimbal/391.Status.uavcan rename to dsdl/uavcan/equipment/camera_gimbal/392.Status.uavcan diff --git a/dsdl/uavcan/equipment/camera_gimbal/Mode.uavcan b/dsdl/uavcan/equipment/camera_gimbal/Mode.uavcan index 383194cb16..2def06dcad 100644 --- a/dsdl/uavcan/equipment/camera_gimbal/Mode.uavcan +++ b/dsdl/uavcan/equipment/camera_gimbal/Mode.uavcan @@ -2,8 +2,8 @@ # Gimbal operating mode # -uint4 COMMAND_MODE_ANGULAR_VELOCITY = 0 -uint4 COMMAND_MODE_ORIENTATION_FIXED_FRAME = 1 -uint4 COMMAND_MODE_ORIENTATION_BODY_FRAME = 2 -uint4 COMMAND_MODE_GEO_POI = 3 -uint4 command_mode +uint8 COMMAND_MODE_ANGULAR_VELOCITY = 0 +uint8 COMMAND_MODE_ORIENTATION_FIXED_FRAME = 1 +uint8 COMMAND_MODE_ORIENTATION_BODY_FRAME = 2 +uint8 COMMAND_MODE_GEO_POI = 3 +uint8 command_mode From 7946ddd5bc9ee4b2925229b939ae78bd0041d382 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 18 Mar 2015 18:31:33 +0300 Subject: [PATCH 22/50] Global DDTID adjustment --- .../air_data/{280.Airspeed.uavcan => 290.Airspeed.uavcan} | 0 ...tudeAndClimbRate.uavcan => 291.AltitudeAndClimbRate.uavcan} | 0 .../{282.AngleOfAttack.uavcan => 292.AngleOfAttack.uavcan} | 0 .../air_data/{283.Sideslip.uavcan => 293.Sideslip.uavcan} | 0 .../{284.StaticAirData.uavcan => 294.StaticAirData.uavcan} | 0 .../{390.AngularCommand.uavcan => 400.AngularCommand.uavcan} | 0 .../{391.GEOPOICommand.uavcan => 401.GEOPOICommand.uavcan} | 0 .../camera_gimbal/{392.Status.uavcan => 402.Status.uavcan} | 0 dsdl/uavcan/equipment/gnss/{300.Fix.uavcan => 420.Fix.uavcan} | 0 .../gnss/{301.Auxiliary.uavcan => 421.Auxiliary.uavcan} | 0 .../hardpoint/{700.Command.uavcan => 660.Command.uavcan} | 0 .../hardpoint/{701.Status.uavcan => 661.Status.uavcan} | 0 .../{742.BeepCommand.uavcan => 747.BeepCommand.uavcan} | 0 .../{743.LightsCommand.uavcan => 748.LightsCommand.uavcan} | 0 ...SupplyStatus.uavcan => 720.PrimaryPowerSupplyStatus.uavcan} | 0 .../{711.CircuitStatus.uavcan => 721.CircuitStatus.uavcan} | 0 .../power/{712.BatteryInfo.uavcan => 722.BatteryInfo.uavcan} | 0 dsdl/uavcan/ranges | 3 ++- 18 files changed, 2 insertions(+), 1 deletion(-) rename dsdl/uavcan/equipment/air_data/{280.Airspeed.uavcan => 290.Airspeed.uavcan} (100%) rename dsdl/uavcan/equipment/air_data/{281.AltitudeAndClimbRate.uavcan => 291.AltitudeAndClimbRate.uavcan} (100%) rename dsdl/uavcan/equipment/air_data/{282.AngleOfAttack.uavcan => 292.AngleOfAttack.uavcan} (100%) rename dsdl/uavcan/equipment/air_data/{283.Sideslip.uavcan => 293.Sideslip.uavcan} (100%) rename dsdl/uavcan/equipment/air_data/{284.StaticAirData.uavcan => 294.StaticAirData.uavcan} (100%) rename dsdl/uavcan/equipment/camera_gimbal/{390.AngularCommand.uavcan => 400.AngularCommand.uavcan} (100%) rename dsdl/uavcan/equipment/camera_gimbal/{391.GEOPOICommand.uavcan => 401.GEOPOICommand.uavcan} (100%) rename dsdl/uavcan/equipment/camera_gimbal/{392.Status.uavcan => 402.Status.uavcan} (100%) rename dsdl/uavcan/equipment/gnss/{300.Fix.uavcan => 420.Fix.uavcan} (100%) rename dsdl/uavcan/equipment/gnss/{301.Auxiliary.uavcan => 421.Auxiliary.uavcan} (100%) rename dsdl/uavcan/equipment/hardpoint/{700.Command.uavcan => 660.Command.uavcan} (100%) rename dsdl/uavcan/equipment/hardpoint/{701.Status.uavcan => 661.Status.uavcan} (100%) rename dsdl/uavcan/equipment/indication/{742.BeepCommand.uavcan => 747.BeepCommand.uavcan} (100%) rename dsdl/uavcan/equipment/indication/{743.LightsCommand.uavcan => 748.LightsCommand.uavcan} (100%) rename dsdl/uavcan/equipment/power/{710.PrimaryPowerSupplyStatus.uavcan => 720.PrimaryPowerSupplyStatus.uavcan} (100%) rename dsdl/uavcan/equipment/power/{711.CircuitStatus.uavcan => 721.CircuitStatus.uavcan} (100%) rename dsdl/uavcan/equipment/power/{712.BatteryInfo.uavcan => 722.BatteryInfo.uavcan} (100%) diff --git a/dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan b/dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/280.Airspeed.uavcan rename to dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan diff --git a/dsdl/uavcan/equipment/air_data/281.AltitudeAndClimbRate.uavcan b/dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/281.AltitudeAndClimbRate.uavcan rename to dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan diff --git a/dsdl/uavcan/equipment/air_data/282.AngleOfAttack.uavcan b/dsdl/uavcan/equipment/air_data/292.AngleOfAttack.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/282.AngleOfAttack.uavcan rename to dsdl/uavcan/equipment/air_data/292.AngleOfAttack.uavcan diff --git a/dsdl/uavcan/equipment/air_data/283.Sideslip.uavcan b/dsdl/uavcan/equipment/air_data/293.Sideslip.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/283.Sideslip.uavcan rename to dsdl/uavcan/equipment/air_data/293.Sideslip.uavcan diff --git a/dsdl/uavcan/equipment/air_data/284.StaticAirData.uavcan b/dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/284.StaticAirData.uavcan rename to dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan diff --git a/dsdl/uavcan/equipment/camera_gimbal/390.AngularCommand.uavcan b/dsdl/uavcan/equipment/camera_gimbal/400.AngularCommand.uavcan similarity index 100% rename from dsdl/uavcan/equipment/camera_gimbal/390.AngularCommand.uavcan rename to dsdl/uavcan/equipment/camera_gimbal/400.AngularCommand.uavcan diff --git a/dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan b/dsdl/uavcan/equipment/camera_gimbal/401.GEOPOICommand.uavcan similarity index 100% rename from dsdl/uavcan/equipment/camera_gimbal/391.GEOPOICommand.uavcan rename to dsdl/uavcan/equipment/camera_gimbal/401.GEOPOICommand.uavcan diff --git a/dsdl/uavcan/equipment/camera_gimbal/392.Status.uavcan b/dsdl/uavcan/equipment/camera_gimbal/402.Status.uavcan similarity index 100% rename from dsdl/uavcan/equipment/camera_gimbal/392.Status.uavcan rename to dsdl/uavcan/equipment/camera_gimbal/402.Status.uavcan diff --git a/dsdl/uavcan/equipment/gnss/300.Fix.uavcan b/dsdl/uavcan/equipment/gnss/420.Fix.uavcan similarity index 100% rename from dsdl/uavcan/equipment/gnss/300.Fix.uavcan rename to dsdl/uavcan/equipment/gnss/420.Fix.uavcan diff --git a/dsdl/uavcan/equipment/gnss/301.Auxiliary.uavcan b/dsdl/uavcan/equipment/gnss/421.Auxiliary.uavcan similarity index 100% rename from dsdl/uavcan/equipment/gnss/301.Auxiliary.uavcan rename to dsdl/uavcan/equipment/gnss/421.Auxiliary.uavcan diff --git a/dsdl/uavcan/equipment/hardpoint/700.Command.uavcan b/dsdl/uavcan/equipment/hardpoint/660.Command.uavcan similarity index 100% rename from dsdl/uavcan/equipment/hardpoint/700.Command.uavcan rename to dsdl/uavcan/equipment/hardpoint/660.Command.uavcan diff --git a/dsdl/uavcan/equipment/hardpoint/701.Status.uavcan b/dsdl/uavcan/equipment/hardpoint/661.Status.uavcan similarity index 100% rename from dsdl/uavcan/equipment/hardpoint/701.Status.uavcan rename to dsdl/uavcan/equipment/hardpoint/661.Status.uavcan diff --git a/dsdl/uavcan/equipment/indication/742.BeepCommand.uavcan b/dsdl/uavcan/equipment/indication/747.BeepCommand.uavcan similarity index 100% rename from dsdl/uavcan/equipment/indication/742.BeepCommand.uavcan rename to dsdl/uavcan/equipment/indication/747.BeepCommand.uavcan diff --git a/dsdl/uavcan/equipment/indication/743.LightsCommand.uavcan b/dsdl/uavcan/equipment/indication/748.LightsCommand.uavcan similarity index 100% rename from dsdl/uavcan/equipment/indication/743.LightsCommand.uavcan rename to dsdl/uavcan/equipment/indication/748.LightsCommand.uavcan diff --git a/dsdl/uavcan/equipment/power/710.PrimaryPowerSupplyStatus.uavcan b/dsdl/uavcan/equipment/power/720.PrimaryPowerSupplyStatus.uavcan similarity index 100% rename from dsdl/uavcan/equipment/power/710.PrimaryPowerSupplyStatus.uavcan rename to dsdl/uavcan/equipment/power/720.PrimaryPowerSupplyStatus.uavcan diff --git a/dsdl/uavcan/equipment/power/711.CircuitStatus.uavcan b/dsdl/uavcan/equipment/power/721.CircuitStatus.uavcan similarity index 100% rename from dsdl/uavcan/equipment/power/711.CircuitStatus.uavcan rename to dsdl/uavcan/equipment/power/721.CircuitStatus.uavcan diff --git a/dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan b/dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan similarity index 100% rename from dsdl/uavcan/equipment/power/712.BatteryInfo.uavcan rename to dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan diff --git a/dsdl/uavcan/ranges b/dsdl/uavcan/ranges index 9aaead3289..5af05b409f 100644 --- a/dsdl/uavcan/ranges +++ b/dsdl/uavcan/ranges @@ -1,5 +1,6 @@ +All the unallocated space can be claimed later. -256..399 - high priority equipment +256..449 - high priority equipment 550..599 - protocol From 62dd62602546131acb1bba062901aea09d82f7e9 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 18 Mar 2015 23:32:58 +0300 Subject: [PATCH 23/50] Time synchronization message update: 1. field prev_utc_usec renamed to a more human-readable name; 2. UTC is no longer required, but rather recommended --- dsdl/uavcan/protocol/0.GlobalTimeSync.uavcan | 14 ++++++++------ .../src/protocol/uc_global_time_sync_master.cpp | 5 +++-- .../src/protocol/uc_global_time_sync_slave.cpp | 6 +++--- .../test/protocol/global_time_sync_slave.cpp | 16 ++++++++-------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/dsdl/uavcan/protocol/0.GlobalTimeSync.uavcan b/dsdl/uavcan/protocol/0.GlobalTimeSync.uavcan index d85fd3232b..40e3dd472b 100644 --- a/dsdl/uavcan/protocol/0.GlobalTimeSync.uavcan +++ b/dsdl/uavcan/protocol/0.GlobalTimeSync.uavcan @@ -1,15 +1,17 @@ # # Global time synchronization. -# Should be UTC time, not GPS time nor local time. +# Preferred time is UTC. # Any node that publishes timestamped data must use this time reference. # This message is not intended for unicast transfers. # +# Please refer to the specification to learn about time synchronization algorithm. +# -uint16 MAX_PUBLICATION_PERIOD_MS = 1100 -uint16 MIN_PUBLICATION_PERIOD_MS = 350 +uint16 MAX_PUBLICATION_PERIOD_MS = 1100 # Milliseconds +uint16 MIN_PUBLICATION_PERIOD_MS = 350 # Milliseconds -uint16 PUBLISHER_TIMEOUT_MS = 10000 +uint16 PUBLISHER_TIMEOUT_MS = 10000 # Milliseconds -# UTC time in microseconds when the PREVIOUS GlobalTimeSync message was transmitted. +# Time in microseconds when the PREVIOUS GlobalTimeSync message was transmitted. # If this message is the first one, this field must be zero. -uint64 prev_utc_usec +uint64 previous_transmission_timestamp_usec # Microseconds diff --git a/libuavcan/src/protocol/uc_global_time_sync_master.cpp b/libuavcan/src/protocol/uc_global_time_sync_master.cpp index 8f45c43c1a..8825c1ba85 100644 --- a/libuavcan/src/protocol/uc_global_time_sync_master.cpp +++ b/libuavcan/src/protocol/uc_global_time_sync_master.cpp @@ -56,11 +56,12 @@ int GlobalTimeSyncMaster::IfaceMaster::publish(TransferID tid, MonotonicTime cur const bool long_period = since_prev_pub.toMSec() >= protocol::GlobalTimeSync::MAX_PUBLICATION_PERIOD_MS; protocol::GlobalTimeSync msg; - msg.prev_utc_usec = long_period ? 0 : prev_tx_utc_.toUSec(); + msg.previous_transmission_timestamp_usec = long_period ? 0 : prev_tx_utc_.toUSec(); prev_tx_utc_ = UtcTime(); UAVCAN_TRACE("GlobalTimeSyncMaster", "Publishing %llu iface=%i tid=%i", - static_cast(msg.prev_utc_usec), int(iface_index_), int(tid.get())); + static_cast(msg.previous_transmission_timestamp_usec), + int(iface_index_), int(tid.get())); return pub_.broadcast(msg, tid); } diff --git a/libuavcan/src/protocol/uc_global_time_sync_slave.cpp b/libuavcan/src/protocol/uc_global_time_sync_slave.cpp index 67fe307efe..5a52ee29ae 100644 --- a/libuavcan/src/protocol/uc_global_time_sync_slave.cpp +++ b/libuavcan/src/protocol/uc_global_time_sync_slave.cpp @@ -11,8 +11,8 @@ namespace uavcan void GlobalTimeSyncSlave::adjustFromMsg(const ReceivedDataStructure& msg) { - UAVCAN_ASSERT(msg.prev_utc_usec > 0); - const UtcDuration adjustment = UtcTime::fromUSec(msg.prev_utc_usec) - prev_ts_utc_; + UAVCAN_ASSERT(msg.previous_transmission_timestamp_usec > 0); + const UtcDuration adjustment = UtcTime::fromUSec(msg.previous_transmission_timestamp_usec) - prev_ts_utc_; UAVCAN_TRACE("GlobalTimeSyncSlave", "Adjustment: usec=%lli snid=%i iface=%i suppress=%i", static_cast(adjustment.toUSec()), @@ -58,7 +58,7 @@ void GlobalTimeSyncSlave::processMsg(const ReceivedDataStructure protocol::GlobalTimeSync::MAX_PUBLICATION_PERIOD_MS; if (msg_invalid || wrong_tid || wrong_timing) diff --git a/libuavcan/test/protocol/global_time_sync_slave.cpp b/libuavcan/test/protocol/global_time_sync_slave.cpp index dbfde47502..5bb2e91c0d 100644 --- a/libuavcan/test/protocol/global_time_sync_slave.cpp +++ b/libuavcan/test/protocol/global_time_sync_slave.cpp @@ -37,9 +37,9 @@ TEST(GlobalTimeSyncSlave, Basic) * The slave must only register the timestamp and adjust nothing */ uavcan::protocol::GlobalTimeSync gts; - gts.prev_utc_usec = 0; + gts.previous_transmission_timestamp_usec = 0; gts_pub.broadcast(gts); - gts.prev_utc_usec = master_clock.utc; + gts.previous_transmission_timestamp_usec = master_clock.utc; nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)); ASSERT_EQ(0, slave_clock.utc); ASSERT_EQ(1000000, master_clock.utc); @@ -54,7 +54,7 @@ TEST(GlobalTimeSyncSlave, Basic) * Slave must adjust now */ gts_pub.broadcast(gts); - gts.prev_utc_usec = master_clock.utc; + gts.previous_transmission_timestamp_usec = master_clock.utc; nodes.spinBoth(uavcan::MonotonicDuration()); ASSERT_EQ(1000000, slave_clock.utc); ASSERT_EQ(1000000, master_clock.utc); @@ -72,7 +72,7 @@ TEST(GlobalTimeSyncSlave, Basic) * Will update */ gts_pub.broadcast(gts); - gts.prev_utc_usec = master_clock.utc; + gts.previous_transmission_timestamp_usec = master_clock.utc; nodes.spinBoth(uavcan::MonotonicDuration()); ASSERT_EQ(2000000, slave_clock.utc); ASSERT_EQ(2000000, master_clock.utc); @@ -88,7 +88,7 @@ TEST(GlobalTimeSyncSlave, Basic) * Will adjust */ gts_pub.broadcast(gts); - gts.prev_utc_usec = master_clock.utc; + gts.previous_transmission_timestamp_usec = master_clock.utc; nodes.spinBoth(uavcan::MonotonicDuration()); ASSERT_EQ(3000000, slave_clock.utc); ASSERT_EQ(3000000, master_clock.utc); @@ -117,9 +117,9 @@ TEST(GlobalTimeSyncSlave, Basic) /* * Update step, no adjustment yet */ - gts.prev_utc_usec = 0; + gts.previous_transmission_timestamp_usec = 0; gts_pub2.broadcast(gts); - gts.prev_utc_usec = master2_clock.utc; + gts.previous_transmission_timestamp_usec = master2_clock.utc; nodes.spinBoth(uavcan::MonotonicDuration()); ASSERT_EQ(4000000, slave_clock.utc); ASSERT_EQ(100, master2_clock.utc); @@ -142,7 +142,7 @@ TEST(GlobalTimeSyncSlave, Basic) /* * Another master will be ignored now */ - gts.prev_utc_usec = 99999999; + gts.previous_transmission_timestamp_usec = 99999999; // Update gts_pub.broadcast(gts); nodes.spinBoth(uavcan::MonotonicDuration()); From ddc4b649a89aaa8a501c5c16c71a73d6df3e77fd Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 18 Mar 2015 23:49:53 +0300 Subject: [PATCH 24/50] param.SaveErase --> param.ExecuteOpcode --- .../protocol/param/598.ExecuteOpcode.uavcan | 29 +++++++++++++++++++ .../protocol/param/598.SaveErase.uavcan | 17 ----------- .../include/uavcan/protocol/param_server.hpp | 13 +++++---- libuavcan/src/protocol/uc_param_server.cpp | 12 ++++---- libuavcan/test/protocol/param_server.cpp | 10 +++---- .../linux/apps/uavcan_nodetool.cpp | 14 ++++----- 6 files changed, 54 insertions(+), 41 deletions(-) create mode 100644 dsdl/uavcan/protocol/param/598.ExecuteOpcode.uavcan delete mode 100644 dsdl/uavcan/protocol/param/598.SaveErase.uavcan diff --git a/dsdl/uavcan/protocol/param/598.ExecuteOpcode.uavcan b/dsdl/uavcan/protocol/param/598.ExecuteOpcode.uavcan new file mode 100644 index 0000000000..626fb79c65 --- /dev/null +++ b/dsdl/uavcan/protocol/param/598.ExecuteOpcode.uavcan @@ -0,0 +1,29 @@ +# +# Service to control the node configuration. +# +# SAVE operation instructs the remote node to save the current configuration parameters to the non-volatile +# storage. The node may require a restart in order for some changes to take effect. +# +# ERASE operation instructs the remote node to clear its configuration storage and reinitialize the parameters +# with their default values. The node may require a restart in order for some changes to take effect. +# +# Other opcodes may be added in the future (for example, an opcode for switching between multiple configurations). +# + +uint8 OPCODE_SAVE = 0 # Save all parameters to non-volatile storage. +uint8 OPCODE_ERASE = 1 # Clear the non-volatile storage; some changes may take effect only after reboot. +uint8 opcode + +# +# Reserved, keep zero. +# +int48 argument + +--- + +# +# Reserved, keep zero. +# +int48 argument + +bool ok diff --git a/dsdl/uavcan/protocol/param/598.SaveErase.uavcan b/dsdl/uavcan/protocol/param/598.SaveErase.uavcan deleted file mode 100644 index 2f268283d1..0000000000 --- a/dsdl/uavcan/protocol/param/598.SaveErase.uavcan +++ /dev/null @@ -1,17 +0,0 @@ -# -# Service to control non-volatile parameter storage. -# -# SAVE operation instructs the remote node to save the current configuration parameters to the non-volatile -# storage. The device may require a restart in order for some changes to take effect. -# -# ERASE operation instructs the remote node to clear its configuration storage and reinitialize the parameters -# with their default values. The device may require a restart in order for some changes to take effect. -# - -uint8 OPCODE_SAVE = 0 # Save all parameters to non-volatile storage. -uint8 OPCODE_ERASE = 1 # Clear the non-volatile storage; some changes may take effect only after reboot. -uint8 opcode - ---- - -bool ok diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index f0292198a2..847095f430 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -6,7 +6,7 @@ #define UAVCAN_PROTOCOL_PARAM_SERVER_HPP_INCLUDED #include -#include +#include #include #include @@ -75,19 +75,20 @@ class UAVCAN_EXPORT ParamServer typedef MethodBinder GetSetCallback; - typedef MethodBinder SaveEraseCallback; + typedef MethodBinder ExecuteOpcodeCallback; ServiceServer get_set_srv_; - ServiceServer save_erase_srv_; + ServiceServer save_erase_srv_; IParamManager* manager_; static bool isValueNonEmpty(const protocol::param::Value& value); void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response); - void handleSaveErase(const protocol::param::SaveErase::Request& request, - protocol::param::SaveErase::Response& response); + void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request, + protocol::param::ExecuteOpcode::Response& response); public: explicit ParamServer(INode& node) diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 0096239fa0..164ac1316e 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -49,22 +49,22 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto } } -void ParamServer::handleSaveErase(const protocol::param::SaveErase::Request& in, - protocol::param::SaveErase::Response& out) +void ParamServer::handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& in, + protocol::param::ExecuteOpcode::Response& out) { UAVCAN_ASSERT(manager_ != NULL); - if (in.opcode == protocol::param::SaveErase::Request::OPCODE_SAVE) + if (in.opcode == protocol::param::ExecuteOpcode::Request::OPCODE_SAVE) { out.ok = manager_->saveAllParams() >= 0; } - else if (in.opcode == protocol::param::SaveErase::Request::OPCODE_ERASE) + else if (in.opcode == protocol::param::ExecuteOpcode::Request::OPCODE_ERASE) { out.ok = manager_->eraseAllParams() >= 0; } else { - UAVCAN_TRACE("ParamServer", "SaveErase: invalid opcode %i", int(in.opcode)); + UAVCAN_TRACE("ParamServer", "ExecuteOpcode: invalid opcode %i", int(in.opcode)); out.ok = false; } } @@ -83,7 +83,7 @@ int ParamServer::start(IParamManager* manager) return res; } - res = save_erase_srv_.start(SaveEraseCallback(this, &ParamServer::handleSaveErase)); + res = save_erase_srv_.start(ExecuteOpcodeCallback(this, &ParamServer::handleExecuteOpcode)); if (res < 0) { get_set_srv_.stop(); diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index dd65bb5c9e..c7a27a0f8e 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -93,23 +93,23 @@ TEST(ParamServer, Basic) uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _reg1; - uavcan::DefaultDataTypeRegistrator _reg2; + uavcan::DefaultDataTypeRegistrator _reg2; ASSERT_LE(0, server.start(&mgr)); ServiceClientWithCollector get_set_cln(nodes.b); - ServiceClientWithCollector save_erase_cln(nodes.b); + ServiceClientWithCollector save_erase_cln(nodes.b); /* * Save/erase */ - uavcan::protocol::param::SaveErase::Request save_erase_rq; - save_erase_rq.opcode = uavcan::protocol::param::SaveErase::Request::OPCODE_SAVE; + uavcan::protocol::param::ExecuteOpcode::Request save_erase_rq; + save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_SAVE; doCall(save_erase_cln, save_erase_rq, nodes); ASSERT_TRUE(save_erase_cln.collector.result.get()); ASSERT_TRUE(save_erase_cln.collector.result->response.ok); - save_erase_rq.opcode = uavcan::protocol::param::SaveErase::Request::OPCODE_ERASE; + save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_ERASE; doCall(save_erase_cln, save_erase_rq, nodes); ASSERT_TRUE(save_erase_cln.collector.result->response.ok); diff --git a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp index 822144701b..f580f39f6a 100644 --- a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp +++ b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp @@ -14,7 +14,7 @@ #include "debug.hpp" #include -#include +#include #include #include @@ -185,11 +185,11 @@ const std::map&) { - auto client = node->makeBlockingServiceClient(); - uavcan::protocol::param::SaveErase::Request request; + auto client = node->makeBlockingServiceClient(); + uavcan::protocol::param::ExecuteOpcode::Request request; request.opcode = request.OPCODE_SAVE; std::cout << call(*client, node_id, request) << std::endl; } @@ -198,11 +198,11 @@ const std::map&) { - auto client = node->makeBlockingServiceClient(); - uavcan::protocol::param::SaveErase::Request request; + auto client = node->makeBlockingServiceClient(); + uavcan::protocol::param::ExecuteOpcode::Request request; request.opcode = request.OPCODE_ERASE; std::cout << call(*client, node_id, request) << std::endl; } From 3b7669219e91cc9d19c5edcb12f0bcb17416e149 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 19 Mar 2015 00:19:40 +0300 Subject: [PATCH 25/50] Basic support for string parameters --- libuavcan/include/uavcan/protocol/param_server.hpp | 2 +- libuavcan/src/protocol/uc_param_server.cpp | 7 +++++-- libuavcan/test/protocol/param_server.cpp | 10 +++++++++- libuavcan_drivers/linux/apps/uavcan_nodetool.cpp | 5 +++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index 847095f430..666db73b59 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -88,7 +88,7 @@ class UAVCAN_EXPORT ParamServer void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response); void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request, - protocol::param::ExecuteOpcode::Response& response); + protocol::param::ExecuteOpcode::Response& response); public: explicit ParamServer(INode& node) diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 164ac1316e..1062332d3b 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -12,7 +12,10 @@ namespace uavcan bool ParamServer::isValueNonEmpty(const protocol::param::Value& value) { - return !value.value_bool.empty() || !value.value_int.empty() || !value.value_float.empty(); + return !value.value_bool.empty() || + !value.value_int.empty() || + !value.value_float.empty() || + !value.value_string.empty(); } void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out) @@ -50,7 +53,7 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto } void ParamServer::handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& in, - protocol::param::ExecuteOpcode::Response& out) + protocol::param::ExecuteOpcode::Response& out) { UAVCAN_ASSERT(manager_ != NULL); diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index c7a27a0f8e..861ca41cd3 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -43,6 +43,10 @@ struct ParamServerTestManager : public uavcan::IParamManager { it->second = double(value.value_float[0]); } + else if (!value.value_string.empty()) + { + it->second = std::atof(value.value_string[0].value.c_str()); + } else { assert(0); @@ -151,7 +155,11 @@ TEST(ParamServer, Basic) // Set by index get_set_rq = uavcan::protocol::param::GetSet::Request(); get_set_rq.index = 0; - get_set_rq.value.value_int.push_back(424242); + { + uavcan::protocol::param::ValueString str; + str.value = "424242"; + get_set_rq.value.value_string.push_back(str); + } doCall(get_set_cln, get_set_rq, nodes); ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str()); ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]); diff --git a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp index f580f39f6a..dd387591f2 100644 --- a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp +++ b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp @@ -88,6 +88,10 @@ std::string paramValueToString(const uavcan::protocol::param::Value& value) { return std::to_string(value.value_float[0]); } + else if (!value.value_string.empty()) + { + return std::string(value.value_string[0].value.c_str()); + } else { return "?"; @@ -176,6 +180,7 @@ const std::map Date: Thu, 19 Mar 2015 21:56:15 +0300 Subject: [PATCH 26/50] Max data type name length test --- libuavcan/src/uc_data_type.cpp | 2 +- libuavcan/test/data_type.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libuavcan/src/uc_data_type.cpp b/libuavcan/src/uc_data_type.cpp index 1e0453eb15..bfe12e8b2c 100644 --- a/libuavcan/src/uc_data_type.cpp +++ b/libuavcan/src/uc_data_type.cpp @@ -112,7 +112,7 @@ std::string DataTypeDescriptor::toString() const } using namespace std; // For snprintf() - char buf[80]; + char buf[128]; (void)snprintf(buf, sizeof(buf), "%s:%u%c:%016llx", full_name_, static_cast(id_.get()), kindch, static_cast(signature_.get())); diff --git a/libuavcan/test/data_type.cpp b/libuavcan/test/data_type.cpp index e3c6508b53..4d849076eb 100644 --- a/libuavcan/test/data_type.cpp +++ b/libuavcan/test/data_type.cpp @@ -105,6 +105,12 @@ TEST(DataTypeDescriptor, ToString) desc = uavcan::DataTypeDescriptor(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(0xdeadbeef1234), "Bar"); ASSERT_EQ("Bar:123m:0000deadbeef1234", desc.toString()); + + // Max length - 80 chars + desc = uavcan::DataTypeDescriptor(uavcan::DataTypeKindMessage, 1023, uavcan::DataTypeSignature(0xdeadbeef12345678), + "sirius_cybernetics_corporation.marvin.model_a.LongDataTypeName123456789abcdefghi"); + ASSERT_EQ("sirius_cybernetics_corporation.marvin.model_a.LongDataTypeName123456789abcdefghi:1023m:deadbeef12345678", + desc.toString()); } From f63f22bd2b52ad08fd3481765bc076891dd9e050 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 19 Mar 2015 22:03:00 +0300 Subject: [PATCH 27/50] Max parameter name length increased to 92 in order to provide enough space for messaging configuration parameters (12-byte prefix + 80-char type name) --- dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan | 2 +- dsdl/uavcan/protocol/param/599.GetSet.uavcan | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan index b63eeffcb1..cd4668e7f7 100644 --- a/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan +++ b/dsdl/uavcan/protocol/debug/1022.KeyValue.uavcan @@ -2,6 +2,6 @@ # Generic named parameter (key/value pair). # -uint8[<=80] key +uint8[<=92] key uavcan.protocol.param.Value value diff --git a/dsdl/uavcan/protocol/param/599.GetSet.uavcan b/dsdl/uavcan/protocol/param/599.GetSet.uavcan index 5a3746f002..65b1950afb 100644 --- a/dsdl/uavcan/protocol/param/599.GetSet.uavcan +++ b/dsdl/uavcan/protocol/param/599.GetSet.uavcan @@ -11,7 +11,7 @@ Value value uint8 index # Name of the parameter; always preferred over index if nonempty. -uint8[<=80] name +uint8[<=92] name --- @@ -27,4 +27,4 @@ Value max_value # Optional Value min_value # Optional # Empty name in response indicates that there is no such parameter -uint8[<=80] name +uint8[<=92] name From 659c2899d52fd63eec4fb6a57bac758413d3960f Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 19 Mar 2015 22:11:58 +0300 Subject: [PATCH 28/50] DSDL signature does not depend on constant definitions anymore (see specification) --- pyuavcan/pyuavcan/dsdl/parser.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyuavcan/pyuavcan/dsdl/parser.py b/pyuavcan/pyuavcan/dsdl/parser.py index e27da2eafd..7a10c822ff 100644 --- a/pyuavcan/pyuavcan/dsdl/parser.py +++ b/pyuavcan/pyuavcan/dsdl/parser.py @@ -183,16 +183,12 @@ class CompoundType(Type): txt = StringIO() txt.write(self.full_name + '\n') adjoin = lambda attrs: txt.write('\n'.join(x.get_normalized_definition() for x in attrs) + '\n') - const_sort_key = lambda x: x.get_normalized_definition() if self.kind == CompoundType.KIND_SERVICE: adjoin(self.request_fields) - adjoin(sorted(self.request_constants, key=const_sort_key)) txt.write('\n---\n') adjoin(self.response_fields) - adjoin(sorted(self.response_constants, key=const_sort_key)) elif self.kind == CompoundType.KIND_MESSAGE: adjoin(self.fields) - adjoin(sorted(self.constants, key=const_sort_key)) else: error('Compound type of unknown kind [%s]', self.kind) return txt.getvalue().strip().replace('\n\n\n', '\n').replace('\n\n', '\n') From 3b3c0d3b9ed7194304def96d89cc9b070ea3798b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 19 Mar 2015 23:03:04 +0300 Subject: [PATCH 29/50] Vendor-specific status code reduced to 16 bit --- dsdl/uavcan/protocol/550.NodeStatus.uavcan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsdl/uavcan/protocol/550.NodeStatus.uavcan b/dsdl/uavcan/protocol/550.NodeStatus.uavcan index 934e741c12..3af86791aa 100644 --- a/dsdl/uavcan/protocol/550.NodeStatus.uavcan +++ b/dsdl/uavcan/protocol/550.NodeStatus.uavcan @@ -27,4 +27,4 @@ uint4 STATUS_OFFLINE = 15 uint4 status_code # Optional, vendor-specific node status code, e.g. a fault code or a status bitmask. -uint32 vendor_specific_status_code +uint16 vendor_specific_status_code From a63c9510fc6d3c4a40a64bba379227dc784ec988 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 00:24:53 +0300 Subject: [PATCH 30/50] Vendor-specific status code support --- libuavcan/include/uavcan/node/node.hpp | 8 +++++ .../uavcan/protocol/node_status_provider.hpp | 12 +++++++ .../src/protocol/uc_node_status_provider.cpp | 5 +++ libuavcan_drivers/linux/apps/test_node.cpp | 1 + .../linux/apps/uavcan_status_monitor.cpp | 33 ++++++++++++++----- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/libuavcan/include/uavcan/node/node.hpp b/libuavcan/include/uavcan/node/node.hpp index c04bf1103b..a3e88ff829 100644 --- a/libuavcan/include/uavcan/node/node.hpp +++ b/libuavcan/include/uavcan/node/node.hpp @@ -180,6 +180,14 @@ public: (void)proto_nsp_.forcePublish(); } + /** + * Updates the vendor-specific status code. + */ + void setVendorSpecificStatusCode(NodeStatusProvider::VendorSpecificStatusCode code) + { + proto_nsp_.setVendorSpecificStatusCode(code); + } + /** * Sets the node version information. */ diff --git a/libuavcan/include/uavcan/protocol/node_status_provider.hpp b/libuavcan/include/uavcan/protocol/node_status_provider.hpp index 524dd43c35..ced87a08aa 100644 --- a/libuavcan/include/uavcan/protocol/node_status_provider.hpp +++ b/libuavcan/include/uavcan/protocol/node_status_provider.hpp @@ -49,6 +49,9 @@ class UAVCAN_EXPORT NodeStatusProvider : private TimerBase void handleGetNodeInfoRequest(const protocol::GetNodeInfo::Request&, protocol::GetNodeInfo::Response& rsp); public: + typedef typename StorageType::Type + VendorSpecificStatusCode; + explicit NodeStatusProvider(INode& node) : TimerBase(node) , creation_timestamp_(node.getMonotonicTime()) @@ -92,6 +95,15 @@ public: void setStatusCritical() { setStatusCode(protocol::NodeStatus::STATUS_CRITICAL); } void setStatusOffline() { setStatusCode(protocol::NodeStatus::STATUS_OFFLINE); } + /** + * Local node vendor-specific status code control. + */ + void setVendorSpecificStatusCode(VendorSpecificStatusCode code); + VendorSpecificStatusCode getVendorSpecificStatusCode() const + { + return node_info_.status.vendor_specific_status_code; + } + /** * Local node name control. * Can be set only once before the provider is started. diff --git a/libuavcan/src/protocol/uc_node_status_provider.cpp b/libuavcan/src/protocol/uc_node_status_provider.cpp index 7a6425684e..ebff29c533 100644 --- a/libuavcan/src/protocol/uc_node_status_provider.cpp +++ b/libuavcan/src/protocol/uc_node_status_provider.cpp @@ -130,6 +130,11 @@ void NodeStatusProvider::setStatusCode(uint8_t code) node_info_.status.status_code = code; } +void NodeStatusProvider::setVendorSpecificStatusCode(VendorSpecificStatusCode code) +{ + node_info_.status.vendor_specific_status_code = code; +} + void NodeStatusProvider::setName(const char* name) { if ((name != NULL) && (*name != '\0') && (node_info_.name.empty())) diff --git a/libuavcan_drivers/linux/apps/test_node.cpp b/libuavcan_drivers/linux/apps/test_node.cpp index 2241f246ca..4bd4eb872f 100644 --- a/libuavcan_drivers/linux/apps/test_node.cpp +++ b/libuavcan_drivers/linux/apps/test_node.cpp @@ -84,6 +84,7 @@ static void runForever(const uavcan_linux::NodePtr& node) auto do_nothing_once_a_minute = [&node](const uavcan::TimerEvent&) { node->logInfo("timer", "Another minute passed..."); + node->setVendorSpecificStatusCode(static_cast(std::rand())); // Setting to an arbitrary value }; auto timer = node->makeTimer(uavcan::MonotonicDuration::fromMSec(60000), do_nothing_once_a_minute); diff --git a/libuavcan_drivers/linux/apps/uavcan_status_monitor.cpp b/libuavcan_drivers/linux/apps/uavcan_status_monitor.cpp index c8374ded0d..540c68dce6 100644 --- a/libuavcan_drivers/linux/apps/uavcan_status_monitor.cpp +++ b/libuavcan_drivers/linux/apps/uavcan_status_monitor.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ struct OstreamColorizer Yellow = 33, Blue = 34, Magenta = 35, + Cyan = 36, Default = 39 }; explicit OstreamColorizer(Color color = Default) : color_(color) { } @@ -33,11 +35,11 @@ private: class Monitor : public uavcan::NodeStatusMonitor { uavcan_linux::TimerPtr timer_; - std::unordered_map uptimes_; + std::unordered_map status_registry_; virtual void handleNodeStatusMessage(const uavcan::ReceivedDataStructure& msg) { - uptimes_[msg.getSrcNodeID().get()] = msg.uptime_sec; + status_registry_[msg.getSrcNodeID().get()] = msg; } static std::pair @@ -49,7 +51,7 @@ class Monitor : public uavcan::NodeStatusMonitor } if (status_code == uavcan::protocol::NodeStatus::STATUS_INITIALIZING) { - return { OstreamColorizer(OstreamColorizer::Blue), "INITIALIZING" }; + return { OstreamColorizer(OstreamColorizer::Cyan), "INITIALIZING" }; } if (status_code == uavcan::protocol::NodeStatus::STATUS_WARNING) { @@ -68,20 +70,33 @@ class Monitor : public uavcan::NodeStatusMonitor void printStatusLine(uavcan::NodeID nid, const uavcan::NodeStatusMonitor::NodeStatus& status) { + const auto original_flags = std::cout.flags(); + const auto color_and_string = statusCodeToColoredString(status.status_code); const int nid_int = nid.get(); + const auto uptime = status_registry_[nid_int].uptime_sec; + const int vendor_code = status_registry_[nid_int].vendor_specific_status_code; + std::cout << color_and_string.first; - std::cout << " " << std::setw(3) << std::left << nid_int << " | " - << std::setw(13) << std::left << color_and_string.second << " | " - << uptimes_[nid_int]; - std::cout << OstreamColorizer() << "\n"; + + std::cout << " " << std::setw(3) << std::left << nid_int << " | " // Node ID + << std::setw(13) << std::left << color_and_string.second << " | " // Status name + << std::setw(12) << uptime << " | " // Uptime + << "0x" << std::hex << std::setw(4) << std::setfill('0') << vendor_code // Vendor, hex + << " 0b" << std::dec << std::bitset<8>((vendor_code >> 8) & 0xFF) // Vendor, bin, high + << "'" << std::bitset<8>(vendor_code & 0xFF) // Vendor, bin, low + << " " << vendor_code; // Vendor, dec + + std::cout << OstreamColorizer() << std::setfill(' ') << "\n"; + std::cout.width(0); + std::cout.flags(original_flags); } void redraw(const uavcan::TimerEvent&) { std::cout << "\x1b\x5b\x48" << "\x1b\x5b\x32\x4a" - << " NID | Status | Uptime\n" - << "-----+---------------+--------\n"; + << " NID | Status | Uptime (sec) | Vendor-specific status (hex/bin/dec)\n" + << "-----+---------------+--------------+--------------------------------------\n"; for (unsigned i = 1; i <= uavcan::NodeID::Max; i++) { const auto s = getNodeStatus(i); From 79d167a84cde9c54722abf02040a59d3f5f3378e Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 00:32:24 +0300 Subject: [PATCH 31/50] Tests for vendor-specific status code management --- libuavcan/test/protocol/node_status_provider.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libuavcan/test/protocol/node_status_provider.cpp b/libuavcan/test/protocol/node_status_provider.cpp index eaa160b6e1..9a3eb18545 100644 --- a/libuavcan/test/protocol/node_status_provider.cpp +++ b/libuavcan/test/protocol/node_status_provider.cpp @@ -70,6 +70,22 @@ TEST(NodeStatusProvider, Basic) ASSERT_TRUE(status_sub.collector.msg.get()); // Was published at startup ASSERT_EQ(uavcan::protocol::NodeStatus::STATUS_OK, status_sub.collector.msg->status_code); + ASSERT_EQ(0, status_sub.collector.msg->vendor_specific_status_code); + ASSERT_GE(1, status_sub.collector.msg->uptime_sec); + + /* + * Altering the vendor-specific status code, forcePublish()-ing it and checking the result + */ + ASSERT_EQ(0, nsp.getVendorSpecificStatusCode()); + nsp.setVendorSpecificStatusCode(1234); + ASSERT_EQ(1234, nsp.getVendorSpecificStatusCode()); + + ASSERT_LE(0, nsp.forcePublish()); + + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)); + + ASSERT_EQ(uavcan::protocol::NodeStatus::STATUS_OK, status_sub.collector.msg->status_code); + ASSERT_EQ(1234, status_sub.collector.msg->vendor_specific_status_code); ASSERT_GE(1, status_sub.collector.msg->uptime_sec); /* From 8417b475753db7bf52cae333c09647a5f21befd2 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 01:48:37 +0300 Subject: [PATCH 32/50] Reduced min pub period of NodeStatus --- dsdl/uavcan/protocol/550.NodeStatus.uavcan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsdl/uavcan/protocol/550.NodeStatus.uavcan b/dsdl/uavcan/protocol/550.NodeStatus.uavcan index 3af86791aa..f3c42c6cbc 100644 --- a/dsdl/uavcan/protocol/550.NodeStatus.uavcan +++ b/dsdl/uavcan/protocol/550.NodeStatus.uavcan @@ -7,7 +7,7 @@ # uint16 MAX_PUBLICATION_PERIOD_MS = 1000 -uint16 MIN_PUBLICATION_PERIOD_MS = 20 +uint16 MIN_PUBLICATION_PERIOD_MS = 2 # If a node fails to publish this message in this amount of time, it should be considered offline. uint16 OFFLINE_TIMEOUT_MS = 3000 From fbdf07fa74dc45e94688f81d5951d0571a2622dc Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 01:51:25 +0300 Subject: [PATCH 33/50] Cleaner naming --- .../include/uavcan/protocol/node_status_provider.hpp | 4 ++-- libuavcan/src/protocol/uc_node_status_provider.cpp | 6 +++--- libuavcan/test/protocol/node_status_provider.cpp | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/node_status_provider.hpp b/libuavcan/include/uavcan/protocol/node_status_provider.hpp index ced87a08aa..6b06fa76dd 100644 --- a/libuavcan/include/uavcan/protocol/node_status_provider.hpp +++ b/libuavcan/include/uavcan/protocol/node_status_provider.hpp @@ -81,8 +81,8 @@ public: * Refer to the DSDL definition of uavcan.protocol.NodeStatus to see what is the default rate. * Doesn't fail; if the value is outside of acceptable range, a closest valid value will be used instead. */ - void setStatusPublishingPeriod(uavcan::MonotonicDuration period); - uavcan::MonotonicDuration getStatusPublishingPeriod() const; + void setStatusPublicationPeriod(uavcan::MonotonicDuration period); + uavcan::MonotonicDuration getStatusPublicationPeriod() const; /** * Local node status code control. diff --git a/libuavcan/src/protocol/uc_node_status_provider.cpp b/libuavcan/src/protocol/uc_node_status_provider.cpp index ebff29c533..d83b48f191 100644 --- a/libuavcan/src/protocol/uc_node_status_provider.cpp +++ b/libuavcan/src/protocol/uc_node_status_provider.cpp @@ -92,7 +92,7 @@ int NodeStatusProvider::startAndPublish() goto fail; } - setStatusPublishingPeriod(MonotonicDuration::fromMSec(protocol::NodeStatus::MAX_PUBLICATION_PERIOD_MS)); + setStatusPublicationPeriod(MonotonicDuration::fromMSec(protocol::NodeStatus::MAX_PUBLICATION_PERIOD_MS)); return res; @@ -104,7 +104,7 @@ fail: return res; } -void NodeStatusProvider::setStatusPublishingPeriod(uavcan::MonotonicDuration period) +void NodeStatusProvider::setStatusPublicationPeriod(uavcan::MonotonicDuration period) { const MonotonicDuration maximum = MonotonicDuration::fromMSec(protocol::NodeStatus::MAX_PUBLICATION_PERIOD_MS); const MonotonicDuration minimum = MonotonicDuration::fromMSec(protocol::NodeStatus::MIN_PUBLICATION_PERIOD_MS); @@ -120,7 +120,7 @@ void NodeStatusProvider::setStatusPublishingPeriod(uavcan::MonotonicDuration per period.toString().c_str(), node_status_pub_.getTxTimeout().toString().c_str()); } -uavcan::MonotonicDuration NodeStatusProvider::getStatusPublishingPeriod() const +uavcan::MonotonicDuration NodeStatusProvider::getStatusPublicationPeriod() const { return TimerBase::getPeriod(); } diff --git a/libuavcan/test/protocol/node_status_provider.cpp b/libuavcan/test/protocol/node_status_provider.cpp index 9a3eb18545..31c4e5cc20 100644 --- a/libuavcan/test/protocol/node_status_provider.cpp +++ b/libuavcan/test/protocol/node_status_provider.cpp @@ -48,15 +48,15 @@ TEST(NodeStatusProvider, Basic) // Checking the publishing rate settings ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_PUBLICATION_PERIOD_MS), - nsp.getStatusPublishingPeriod()); + nsp.getStatusPublicationPeriod()); - nsp.setStatusPublishingPeriod(uavcan::MonotonicDuration()); + nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration()); ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MIN_PUBLICATION_PERIOD_MS), - nsp.getStatusPublishingPeriod()); + nsp.getStatusPublicationPeriod()); - nsp.setStatusPublishingPeriod(uavcan::MonotonicDuration::fromMSec(3600 * 1000 * 24)); + nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration::fromMSec(3600 * 1000 * 24)); ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_PUBLICATION_PERIOD_MS), - nsp.getStatusPublishingPeriod()); + nsp.getStatusPublicationPeriod()); /* * Initial status publication From a6b5f753f1dd01fd57eca62b98c84c186b70b583 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 22:20:30 +0300 Subject: [PATCH 34/50] Test fix --- libuavcan/test/dsdl_test/dsdl_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libuavcan/test/dsdl_test/dsdl_test.cpp b/libuavcan/test/dsdl_test/dsdl_test.cpp index ee582e18ed..96c99d2f2d 100644 --- a/libuavcan/test/dsdl_test/dsdl_test.cpp +++ b/libuavcan/test/dsdl_test/dsdl_test.cpp @@ -57,7 +57,7 @@ TEST(Dsdl, Signature) ASSERT_EQ("root_ns_a.EmptyService", root_ns_a::EmptyService::getDataTypeFullName()); ASSERT_EQ(uavcan::DataTypeKindService, root_ns_a::EmptyService::DataTypeKind); - ASSERT_EQ(0x41a2582ee72be419, root_ns_a::NestedMessage::getDataTypeSignature().get()); // Computed manually + ASSERT_EQ(0x99604d7066e0d713, root_ns_a::NestedMessage::getDataTypeSignature().get()); // Computed manually ASSERT_EQ("root_ns_a.NestedMessage", root_ns_a::NestedMessage::getDataTypeFullName()); ASSERT_EQ(uavcan::DataTypeKindMessage, root_ns_a::NestedMessage::DataTypeKind); } From 241ae8a538fd0695fc8e0350f43e329dea5d32c1 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 20 Mar 2015 23:37:42 +0300 Subject: [PATCH 35/50] Array methods for case conversion --- libuavcan/include/uavcan/marshal/array.hpp | 32 ++++++++++++++++++++++ libuavcan/test/marshal/array.cpp | 18 ++++++++++++ 2 files changed, 50 insertions(+) diff --git a/libuavcan/include/uavcan/marshal/array.hpp b/libuavcan/include/uavcan/marshal/array.hpp index 70f1c27d97..46215e311b 100644 --- a/libuavcan/include/uavcan/marshal/array.hpp +++ b/libuavcan/include/uavcan/marshal/array.hpp @@ -742,6 +742,38 @@ public: } } + /** + * Converts the string to upper/lower case in place, assuming that encoding is ASCII. + * These methods can only be used with string-like arrays; otherwise compilation will fail. + */ + void convertToUpperCaseASCII() + { + StaticAssert::check(); + + for (SizeType i = 0; i < size(); i++) + { + const int x = Base::at(i); + if ((x <= 'z') && (x >= 'a')) + { + Base::at(i) = static_cast(x + ('Z' - 'z')); + } + } + } + + void convertToLowerCaseASCII() + { + StaticAssert::check(); + + for (SizeType i = 0; i < size(); i++) + { + const int x = Base::at(i); + if ((x <= 'Z') && (x >= 'A')) + { + Base::at(i) = static_cast(x - ('Z' - 'z')); + } + } + } + /** * Fills this array as a packed square matrix from a static array. * Please refer to the specification to learn more about matrix packing. diff --git a/libuavcan/test/marshal/array.cpp b/libuavcan/test/marshal/array.cpp index e0402ec0cc..f3dfebb3ad 100644 --- a/libuavcan/test/marshal/array.cpp +++ b/libuavcan/test/marshal/array.cpp @@ -1278,3 +1278,21 @@ TEST(Array, FuzzyComparison) uavcan::YamlStreamer::stream(std::cout, array_d64, 0); std::cout << std::endl; } + +TEST(Array, CaseConversion) +{ + Array, ArrayModeDynamic, 30> str; + + str.convertToLowerCaseASCII(); + str.convertToUpperCaseASCII(); + + ASSERT_STREQ("", str.c_str()); + + str = "Hello World!"; + + ASSERT_STREQ("Hello World!", str.c_str()); + str.convertToLowerCaseASCII(); + ASSERT_STREQ("hello world!", str.c_str()); + str.convertToUpperCaseASCII(); + ASSERT_STREQ("HELLO WORLD!", str.c_str()); +} From 80c2c175aa9cfca55c8f15b64f662cbcc34ebdae Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 00:12:06 +0300 Subject: [PATCH 36/50] ParamServer - automatic case conversion for parameter names --- .../include/uavcan/protocol/param_server.hpp | 28 +++++++- libuavcan/src/protocol/uc_param_server.cpp | 18 +++++ libuavcan/test/protocol/param_server.cpp | 67 ++++++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index 666db73b59..2c23ac2bb5 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -79,22 +79,48 @@ class UAVCAN_EXPORT ParamServer void (ParamServer::*)(const protocol::param::ExecuteOpcode::Request&, protocol::param::ExecuteOpcode::Response&)> ExecuteOpcodeCallback; +public: + /** + * This class can automatically enforce that parameter names are not case-sensitive, by means of + * automatic conversion to either upper or lower case whenever a parameter name is received. + * For instance, if the lower-case conversion is enabled, then a UAVCAN request for a parameter + * named "Foo" will be passed to the application as "foo". Similarly, when the application reports + * that it has a parameter named "FOO", the class will convert the name to "foo". + */ + enum ParamNameCaseConversion + { + ParamNameCaseConversionDisabled, ///< Do not convert parameter names. The case will remain intact. + ParamNameCaseConversionToLower, ///< Convert parameter names to lower case. + ParamNameCaseConversionToUpper ///< Convert parameter names to upper case. + }; + +private: ServiceServer get_set_srv_; ServiceServer save_erase_srv_; IParamManager* manager_; + const ParamNameCaseConversion param_name_case_conversion_mode_; static bool isValueNonEmpty(const protocol::param::Value& value); + void convertParamNameCase(IParamManager::ParamName& name) const; + void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response); void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request, protocol::param::ExecuteOpcode::Response& response); public: - explicit ParamServer(INode& node) + /** + * @param param_name_case_conversion Specifies the parameter name conversion mode. Lower case is default, + * which means that an external request for a parameter named "Foo" will + * be relayed to the application as "foo". + */ + explicit ParamServer(INode& node, + ParamNameCaseConversion param_name_case_conversion = ParamNameCaseConversionToLower) : get_set_srv_(node) , save_erase_srv_(node) , manager_(NULL) + , param_name_case_conversion_mode_(param_name_case_conversion) { } /** diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 1062332d3b..4d5f54b7e3 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -18,6 +18,22 @@ bool ParamServer::isValueNonEmpty(const protocol::param::Value& value) !value.value_string.empty(); } +void ParamServer::convertParamNameCase(IParamManager::ParamName& name) const +{ + if (param_name_case_conversion_mode_ == ParamNameCaseConversionToLower) + { + name.convertToLowerCaseASCII(); + } + else if (param_name_case_conversion_mode_ == ParamNameCaseConversionToUpper) + { + name.convertToUpperCaseASCII(); + } + else + { + ; // Conversion is not needed + } +} + void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out) { UAVCAN_ASSERT(manager_ != NULL); @@ -33,6 +49,8 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto out.name = in.name; } + convertParamNameCase(out.name); + // Assign if needed, read back if (isValueNonEmpty(in.value)) { diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index 861ca41cd3..054b007395 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -145,7 +145,7 @@ TEST(ParamServer, Basic) // Get by name get_set_rq = uavcan::protocol::param::GetSet::Request(); - get_set_rq.name = "foobar"; + get_set_rq.name = "FOOBAR"; // Requesting in upper case doCall(get_set_cln, get_set_rq, nodes); ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str()); ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); @@ -171,3 +171,68 @@ TEST(ParamServer, Basic) ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str()); ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]); } + +TEST(ParamServer, UpperCaseConversion) +{ + InterlinkedTestNodesWithSysClock nodes; + + uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionToUpper); + + ParamServerTestManager mgr; + + uavcan::GlobalDataTypeRegistry::instance().reset(); + uavcan::DefaultDataTypeRegistrator _reg1; + uavcan::DefaultDataTypeRegistrator _reg2; + + ASSERT_LE(0, server.start(&mgr)); + + ServiceClientWithCollector get_set_cln(nodes.b); + + mgr.kv["foobar"] = 0.0; // Will be ignored because not upper case + mgr.kv["FOOBAR"] = 123.456; + + /* + * Get/set + */ + uavcan::protocol::param::GetSet::Request get_set_rq; + get_set_rq = uavcan::protocol::param::GetSet::Request(); + get_set_rq.name = "foobar"; // Requesting in upper case + doCall(get_set_cln, get_set_rq, nodes); + ASSERT_STREQ("FOOBAR", get_set_cln.collector.result->response.name.c_str()); + ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); + ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty()); + ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]); +} + +TEST(ParamServer, NoCaseConversion) +{ + InterlinkedTestNodesWithSysClock nodes; + + uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionDisabled); + + ParamServerTestManager mgr; + + uavcan::GlobalDataTypeRegistry::instance().reset(); + uavcan::DefaultDataTypeRegistrator _reg1; + uavcan::DefaultDataTypeRegistrator _reg2; + + ASSERT_LE(0, server.start(&mgr)); + + ServiceClientWithCollector get_set_cln(nodes.b); + + mgr.kv["foobar"] = 0.0; + mgr.kv["FooBar"] = 123.456; + mgr.kv["FOOBAR"] = 0.0; + + /* + * Get/set + */ + uavcan::protocol::param::GetSet::Request get_set_rq; + get_set_rq = uavcan::protocol::param::GetSet::Request(); + get_set_rq.name = "FooBar"; + doCall(get_set_cln, get_set_rq, nodes); + ASSERT_STREQ("FooBar", get_set_cln.collector.result->response.name.c_str()); + ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); + ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty()); + ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]); +} From a5bc052d3119e18fe40cbe3cc653302a66661ce5 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 00:25:35 +0300 Subject: [PATCH 37/50] Notes on GDTR case sensitivity --- libuavcan/include/uavcan/node/global_data_type_registry.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libuavcan/include/uavcan/node/global_data_type_registry.hpp b/libuavcan/include/uavcan/node/global_data_type_registry.hpp index 7e27d92886..e2139f948c 100644 --- a/libuavcan/include/uavcan/node/global_data_type_registry.hpp +++ b/libuavcan/include/uavcan/node/global_data_type_registry.hpp @@ -37,6 +37,9 @@ typedef BitSet DataTypeIDMask; * * Attempt to use a data type that was not registered with this singleton (e.g. publish, subscribe, * perform a service call etc.) will fail with an error code @ref ErrUnknownDataType. + * + * Note that this class treats data type names in case-sensitive manner, although the UAVCAN + * specification allows them to be case-insensitive. TODO: make it non-case sensitive. */ class UAVCAN_EXPORT GlobalDataTypeRegistry : Noncopyable { @@ -128,6 +131,7 @@ public: * Finds data type descriptor by full data type name, e.g. "uavcan.protocol.NodeStatus". * Messages are searched first, then services. * Returns null pointer if the data type with this name is not registered. + * Note that search is case sensitive. * @param name Full data type name * @return Descriptor for this data type or null pointer if not found */ @@ -136,6 +140,7 @@ public: /** * Finds data type descriptor by full data type name, e.g. "uavcan.protocol.NodeStatus", and data type kind. * Returns null pointer if the data type with this name is not registered. + * Note that search is case sensitive. * @param kind Data Type Kind - message or service * @param name Full data type name * @return Descriptor for this data type or null pointer if not found From 6e15a541e65b2f7aecc1596497e5dcd6bda44e94 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 13:06:40 +0300 Subject: [PATCH 38/50] uavcan::Array<> - compile-time check fix in appendFormatted() --- libuavcan/include/uavcan/marshal/array.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libuavcan/include/uavcan/marshal/array.hpp b/libuavcan/include/uavcan/marshal/array.hpp index 46215e311b..2248a161bd 100644 --- a/libuavcan/include/uavcan/marshal/array.hpp +++ b/libuavcan/include/uavcan/marshal/array.hpp @@ -714,7 +714,8 @@ public: StaticAssert::check(); StaticAssert= A(0))>::check(); // This check allows to weed out most compound types - StaticAssert::check(); // Another stupid check to catch non-primitive types + StaticAssert<(sizeof(A) <= sizeof(long double)) || + (sizeof(A) <= sizeof(long long))>::check(); // Another stupid check to catch non-primitive types if (!format) { @@ -731,7 +732,7 @@ public: using namespace std; // For snprintf() const int ret = snprintf(reinterpret_cast(ptr), SizeType(max_size + 1U), format, value); - for (int i = 0; i < min(ret, int(max_size)); i++) + for (int i = 0; i < ::uavcan::min(ret, int(max_size)); i++) { Base::grow(); } From 63c5f2742a4cc79b9ef7884728a4fde43a2ca3a9 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 13:24:44 +0300 Subject: [PATCH 39/50] Revert "Notes on GDTR case sensitivity" This reverts commit a5bc052d3119e18fe40cbe3cc653302a66661ce5. --- libuavcan/include/uavcan/node/global_data_type_registry.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libuavcan/include/uavcan/node/global_data_type_registry.hpp b/libuavcan/include/uavcan/node/global_data_type_registry.hpp index e2139f948c..7e27d92886 100644 --- a/libuavcan/include/uavcan/node/global_data_type_registry.hpp +++ b/libuavcan/include/uavcan/node/global_data_type_registry.hpp @@ -37,9 +37,6 @@ typedef BitSet DataTypeIDMask; * * Attempt to use a data type that was not registered with this singleton (e.g. publish, subscribe, * perform a service call etc.) will fail with an error code @ref ErrUnknownDataType. - * - * Note that this class treats data type names in case-sensitive manner, although the UAVCAN - * specification allows them to be case-insensitive. TODO: make it non-case sensitive. */ class UAVCAN_EXPORT GlobalDataTypeRegistry : Noncopyable { @@ -131,7 +128,6 @@ public: * Finds data type descriptor by full data type name, e.g. "uavcan.protocol.NodeStatus". * Messages are searched first, then services. * Returns null pointer if the data type with this name is not registered. - * Note that search is case sensitive. * @param name Full data type name * @return Descriptor for this data type or null pointer if not found */ @@ -140,7 +136,6 @@ public: /** * Finds data type descriptor by full data type name, e.g. "uavcan.protocol.NodeStatus", and data type kind. * Returns null pointer if the data type with this name is not registered. - * Note that search is case sensitive. * @param kind Data Type Kind - message or service * @param name Full data type name * @return Descriptor for this data type or null pointer if not found From 8bab5c0f5d8a452085696986d28323e1cc10689f Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 13:30:26 +0300 Subject: [PATCH 40/50] ParamServer fix - no case conversion by default --- libuavcan/include/uavcan/protocol/param_server.hpp | 7 +++---- libuavcan/test/protocol/param_server.cpp | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index 2c23ac2bb5..a5818736c0 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -111,12 +111,11 @@ private: public: /** - * @param param_name_case_conversion Specifies the parameter name conversion mode. Lower case is default, - * which means that an external request for a parameter named "Foo" will - * be relayed to the application as "foo". + * @param param_name_case_conversion Specifies the parameter name conversion mode. Conversion is + * disabled by default, i.e. parameter names are case-sensitive. */ explicit ParamServer(INode& node, - ParamNameCaseConversion param_name_case_conversion = ParamNameCaseConversionToLower) + ParamNameCaseConversion param_name_case_conversion = ParamNameCaseConversionDisabled) : get_set_srv_(node) , save_erase_srv_(node) , manager_(NULL) diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index 054b007395..9eb84c5667 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -91,7 +91,7 @@ TEST(ParamServer, Basic) { InterlinkedTestNodesWithSysClock nodes; - uavcan::ParamServer server(nodes.a); + uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionToLower); ParamServerTestManager mgr; @@ -208,7 +208,7 @@ TEST(ParamServer, NoCaseConversion) { InterlinkedTestNodesWithSysClock nodes; - uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionDisabled); + uavcan::ParamServer server(nodes.a); ParamServerTestManager mgr; From 23dd75f1b0fd15ed7ace00cd95930cb822c5256a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 13:40:08 +0300 Subject: [PATCH 41/50] Revert case-insensitive ParamServer --- .../include/uavcan/protocol/param_server.hpp | 27 +------- libuavcan/src/protocol/uc_param_server.cpp | 18 ----- libuavcan/test/protocol/param_server.cpp | 69 +------------------ 3 files changed, 3 insertions(+), 111 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index a5818736c0..666db73b59 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -79,47 +79,22 @@ class UAVCAN_EXPORT ParamServer void (ParamServer::*)(const protocol::param::ExecuteOpcode::Request&, protocol::param::ExecuteOpcode::Response&)> ExecuteOpcodeCallback; -public: - /** - * This class can automatically enforce that parameter names are not case-sensitive, by means of - * automatic conversion to either upper or lower case whenever a parameter name is received. - * For instance, if the lower-case conversion is enabled, then a UAVCAN request for a parameter - * named "Foo" will be passed to the application as "foo". Similarly, when the application reports - * that it has a parameter named "FOO", the class will convert the name to "foo". - */ - enum ParamNameCaseConversion - { - ParamNameCaseConversionDisabled, ///< Do not convert parameter names. The case will remain intact. - ParamNameCaseConversionToLower, ///< Convert parameter names to lower case. - ParamNameCaseConversionToUpper ///< Convert parameter names to upper case. - }; - -private: ServiceServer get_set_srv_; ServiceServer save_erase_srv_; IParamManager* manager_; - const ParamNameCaseConversion param_name_case_conversion_mode_; static bool isValueNonEmpty(const protocol::param::Value& value); - void convertParamNameCase(IParamManager::ParamName& name) const; - void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response); void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request, protocol::param::ExecuteOpcode::Response& response); public: - /** - * @param param_name_case_conversion Specifies the parameter name conversion mode. Conversion is - * disabled by default, i.e. parameter names are case-sensitive. - */ - explicit ParamServer(INode& node, - ParamNameCaseConversion param_name_case_conversion = ParamNameCaseConversionDisabled) + explicit ParamServer(INode& node) : get_set_srv_(node) , save_erase_srv_(node) , manager_(NULL) - , param_name_case_conversion_mode_(param_name_case_conversion) { } /** diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 4d5f54b7e3..1062332d3b 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -18,22 +18,6 @@ bool ParamServer::isValueNonEmpty(const protocol::param::Value& value) !value.value_string.empty(); } -void ParamServer::convertParamNameCase(IParamManager::ParamName& name) const -{ - if (param_name_case_conversion_mode_ == ParamNameCaseConversionToLower) - { - name.convertToLowerCaseASCII(); - } - else if (param_name_case_conversion_mode_ == ParamNameCaseConversionToUpper) - { - name.convertToUpperCaseASCII(); - } - else - { - ; // Conversion is not needed - } -} - void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out) { UAVCAN_ASSERT(manager_ != NULL); @@ -49,8 +33,6 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto out.name = in.name; } - convertParamNameCase(out.name); - // Assign if needed, read back if (isValueNonEmpty(in.value)) { diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index 9eb84c5667..861ca41cd3 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -91,7 +91,7 @@ TEST(ParamServer, Basic) { InterlinkedTestNodesWithSysClock nodes; - uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionToLower); + uavcan::ParamServer server(nodes.a); ParamServerTestManager mgr; @@ -145,7 +145,7 @@ TEST(ParamServer, Basic) // Get by name get_set_rq = uavcan::protocol::param::GetSet::Request(); - get_set_rq.name = "FOOBAR"; // Requesting in upper case + get_set_rq.name = "foobar"; doCall(get_set_cln, get_set_rq, nodes); ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str()); ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); @@ -171,68 +171,3 @@ TEST(ParamServer, Basic) ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str()); ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]); } - -TEST(ParamServer, UpperCaseConversion) -{ - InterlinkedTestNodesWithSysClock nodes; - - uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionToUpper); - - ParamServerTestManager mgr; - - uavcan::GlobalDataTypeRegistry::instance().reset(); - uavcan::DefaultDataTypeRegistrator _reg1; - uavcan::DefaultDataTypeRegistrator _reg2; - - ASSERT_LE(0, server.start(&mgr)); - - ServiceClientWithCollector get_set_cln(nodes.b); - - mgr.kv["foobar"] = 0.0; // Will be ignored because not upper case - mgr.kv["FOOBAR"] = 123.456; - - /* - * Get/set - */ - uavcan::protocol::param::GetSet::Request get_set_rq; - get_set_rq = uavcan::protocol::param::GetSet::Request(); - get_set_rq.name = "foobar"; // Requesting in upper case - doCall(get_set_cln, get_set_rq, nodes); - ASSERT_STREQ("FOOBAR", get_set_cln.collector.result->response.name.c_str()); - ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); - ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty()); - ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]); -} - -TEST(ParamServer, NoCaseConversion) -{ - InterlinkedTestNodesWithSysClock nodes; - - uavcan::ParamServer server(nodes.a); - - ParamServerTestManager mgr; - - uavcan::GlobalDataTypeRegistry::instance().reset(); - uavcan::DefaultDataTypeRegistrator _reg1; - uavcan::DefaultDataTypeRegistrator _reg2; - - ASSERT_LE(0, server.start(&mgr)); - - ServiceClientWithCollector get_set_cln(nodes.b); - - mgr.kv["foobar"] = 0.0; - mgr.kv["FooBar"] = 123.456; - mgr.kv["FOOBAR"] = 0.0; - - /* - * Get/set - */ - uavcan::protocol::param::GetSet::Request get_set_rq; - get_set_rq = uavcan::protocol::param::GetSet::Request(); - get_set_rq.name = "FooBar"; - doCall(get_set_cln, get_set_rq, nodes); - ASSERT_STREQ("FooBar", get_set_cln.collector.result->response.name.c_str()); - ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty()); - ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty()); - ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]); -} From ec9006381b9ed0848eb12704a2beb9e74aea74bf Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 14:08:37 +0300 Subject: [PATCH 42/50] Removing all dirty 'using namespace std' that were used as C++ library compatibility work-around --- libuavcan/include/uavcan/build_config.hpp | 1 - libuavcan/include/uavcan/data_type.hpp | 2 +- libuavcan/include/uavcan/driver/can.hpp | 2 +- libuavcan/include/uavcan/driver/system_clock.hpp | 2 +- libuavcan/include/uavcan/dynamic_memory.hpp | 3 +-- libuavcan/include/uavcan/error.hpp | 2 +- .../uavcan/helpers/component_status_manager.hpp | 2 +- libuavcan/include/uavcan/marshal/array.hpp | 4 ++-- libuavcan/include/uavcan/marshal/bit_stream.hpp | 2 +- libuavcan/include/uavcan/marshal/float_spec.hpp | 2 +- libuavcan/include/uavcan/marshal/integer_spec.hpp | 2 +- libuavcan/include/uavcan/marshal/scalar_codec.hpp | 2 +- .../uavcan/node/global_data_type_registry.hpp | 2 +- libuavcan/include/uavcan/node/timer.hpp | 2 +- libuavcan/include/uavcan/{stdint.hpp => std.hpp} | 12 ++++++++---- libuavcan/include/uavcan/time.hpp | 4 +--- .../uavcan/transport/abstract_transfer_buffer.hpp | 2 +- libuavcan/include/uavcan/transport/can_io.hpp | 2 +- libuavcan/include/uavcan/transport/crc.hpp | 2 +- libuavcan/include/uavcan/transport/dispatcher.hpp | 2 +- .../uavcan/transport/outgoing_transfer_registry.hpp | 2 +- libuavcan/include/uavcan/transport/perf_counter.hpp | 2 +- libuavcan/include/uavcan/transport/transfer.hpp | 2 +- .../include/uavcan/transport/transfer_buffer.hpp | 2 +- .../include/uavcan/transport/transfer_listener.hpp | 2 +- libuavcan/src/driver/uc_can.cpp | 2 -- libuavcan/src/transport/uc_frame.cpp | 1 - .../src/transport/uc_outgoing_transfer_registry.cpp | 1 - libuavcan/src/transport/uc_transfer_buffer.cpp | 1 - libuavcan/src/uc_data_type.cpp | 1 - 30 files changed, 32 insertions(+), 38 deletions(-) rename libuavcan/include/uavcan/{stdint.hpp => std.hpp} (76%) diff --git a/libuavcan/include/uavcan/build_config.hpp b/libuavcan/include/uavcan/build_config.hpp index fac52be812..eab0e386fe 100644 --- a/libuavcan/include/uavcan/build_config.hpp +++ b/libuavcan/include/uavcan/build_config.hpp @@ -123,7 +123,6 @@ #if UAVCAN_TOSTRING # include -# include #endif /** diff --git a/libuavcan/include/uavcan/data_type.hpp b/libuavcan/include/uavcan/data_type.hpp index 8e47751647..323b6f8a18 100644 --- a/libuavcan/include/uavcan/data_type.hpp +++ b/libuavcan/include/uavcan/data_type.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/libuavcan/include/uavcan/driver/can.hpp b/libuavcan/include/uavcan/driver/can.hpp index ad77abfcf7..3fca51c9ed 100644 --- a/libuavcan/include/uavcan/driver/can.hpp +++ b/libuavcan/include/uavcan/driver/can.hpp @@ -7,7 +7,7 @@ #define UAVCAN_DRIVER_CAN_HPP_INCLUDED #include -#include +#include #include #include diff --git a/libuavcan/include/uavcan/driver/system_clock.hpp b/libuavcan/include/uavcan/driver/system_clock.hpp index 22055b457e..1939e5d553 100644 --- a/libuavcan/include/uavcan/driver/system_clock.hpp +++ b/libuavcan/include/uavcan/driver/system_clock.hpp @@ -6,7 +6,7 @@ #ifndef UAVCAN_DRIVER_SYSTEM_CLOCK_HPP_INCLUDED #define UAVCAN_DRIVER_SYSTEM_CLOCK_HPP_INCLUDED -#include +#include #include #include diff --git a/libuavcan/include/uavcan/dynamic_memory.hpp b/libuavcan/include/uavcan/dynamic_memory.hpp index 7c0ffb2038..813d5480be 100644 --- a/libuavcan/include/uavcan/dynamic_memory.hpp +++ b/libuavcan/include/uavcan/dynamic_memory.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -157,7 +157,6 @@ bool PoolManager::addPool(IPoolAllocator* pool) } } // We need to keep the pools in order, so that smallest blocks go first - using namespace std; // for qsort() qsort(pools_, MaxPools, sizeof(IPoolAllocator*), &PoolManager::qsortComparePoolAllocators); return retval; } diff --git a/libuavcan/include/uavcan/error.hpp b/libuavcan/include/uavcan/error.hpp index 1cbeafcc22..bce8b4ed00 100644 --- a/libuavcan/include/uavcan/error.hpp +++ b/libuavcan/include/uavcan/error.hpp @@ -6,7 +6,7 @@ #define UAVCAN_ERROR_HPP_INCLUDED #include -#include +#include namespace uavcan { diff --git a/libuavcan/include/uavcan/helpers/component_status_manager.hpp b/libuavcan/include/uavcan/helpers/component_status_manager.hpp index 78d700b758..f33da0a583 100644 --- a/libuavcan/include/uavcan/helpers/component_status_manager.hpp +++ b/libuavcan/include/uavcan/helpers/component_status_manager.hpp @@ -6,7 +6,7 @@ #define UAVCAN_HELPERS_COMPONENT_STATUS_MANAGER_HPP_INCLUDED #include -#include +#include #include namespace uavcan diff --git a/libuavcan/include/uavcan/marshal/array.hpp b/libuavcan/include/uavcan/marshal/array.hpp index 2248a161bd..67d5ee41d0 100644 --- a/libuavcan/include/uavcan/marshal/array.hpp +++ b/libuavcan/include/uavcan/marshal/array.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef UAVCAN_CPP_VERSION # error UAVCAN_CPP_VERSION @@ -729,10 +730,9 @@ public: const SizeType max_size = SizeType(capacity() - size()); // We have one extra byte for the null terminator, hence +1 - using namespace std; // For snprintf() const int ret = snprintf(reinterpret_cast(ptr), SizeType(max_size + 1U), format, value); - for (int i = 0; i < ::uavcan::min(ret, int(max_size)); i++) + for (int i = 0; i < min(ret, int(max_size)); i++) { Base::grow(); } diff --git a/libuavcan/include/uavcan/marshal/bit_stream.hpp b/libuavcan/include/uavcan/marshal/bit_stream.hpp index b7504112ec..1ac9fe400c 100644 --- a/libuavcan/include/uavcan/marshal/bit_stream.hpp +++ b/libuavcan/include/uavcan/marshal/bit_stream.hpp @@ -6,7 +6,7 @@ #define UAVCAN_MARSHAL_BIT_STREAM_HPP_INCLUDED #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/marshal/float_spec.hpp b/libuavcan/include/uavcan/marshal/float_spec.hpp index ab0063056a..2ee680f184 100644 --- a/libuavcan/include/uavcan/marshal/float_spec.hpp +++ b/libuavcan/include/uavcan/marshal/float_spec.hpp @@ -6,7 +6,7 @@ #define UAVCAN_MARSHAL_FLOAT_SPEC_HPP_INCLUDED #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/marshal/integer_spec.hpp b/libuavcan/include/uavcan/marshal/integer_spec.hpp index 2a74218581..b7424310db 100644 --- a/libuavcan/include/uavcan/marshal/integer_spec.hpp +++ b/libuavcan/include/uavcan/marshal/integer_spec.hpp @@ -5,7 +5,7 @@ #ifndef UAVCAN_MARSHAL_INTEGER_SPEC_HPP_INCLUDED #define UAVCAN_MARSHAL_INTEGER_SPEC_HPP_INCLUDED -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/marshal/scalar_codec.hpp b/libuavcan/include/uavcan/marshal/scalar_codec.hpp index b46c1b16bb..2690f6e1d6 100644 --- a/libuavcan/include/uavcan/marshal/scalar_codec.hpp +++ b/libuavcan/include/uavcan/marshal/scalar_codec.hpp @@ -6,7 +6,7 @@ #define UAVCAN_MARSHAL_SCALAR_CODEC_HPP_INCLUDED #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/node/global_data_type_registry.hpp b/libuavcan/include/uavcan/node/global_data_type_registry.hpp index 7e27d92886..d7f837c199 100644 --- a/libuavcan/include/uavcan/node/global_data_type_registry.hpp +++ b/libuavcan/include/uavcan/node/global_data_type_registry.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/node/timer.hpp b/libuavcan/include/uavcan/node/timer.hpp index 1521489f99..13fc4f5ed9 100644 --- a/libuavcan/include/uavcan/node/timer.hpp +++ b/libuavcan/include/uavcan/node/timer.hpp @@ -5,7 +5,7 @@ #ifndef UAVCAN_NODE_TIMER_HPP_INCLUDED #define UAVCAN_NODE_TIMER_HPP_INCLUDED -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/stdint.hpp b/libuavcan/include/uavcan/std.hpp similarity index 76% rename from libuavcan/include/uavcan/stdint.hpp rename to libuavcan/include/uavcan/std.hpp index 4fc668a2a7..9e1cbc9a84 100644 --- a/libuavcan/include/uavcan/stdint.hpp +++ b/libuavcan/include/uavcan/std.hpp @@ -6,6 +6,7 @@ #define UAVCAN_STDINT_HPP_INCLUDED #include +#include #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11) # error UAVCAN_CPP_VERSION @@ -14,10 +15,13 @@ #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 # include +# include namespace uavcan { +using std::snprintf; // Can be used to replace standard snprintf() with a user-provided one. + typedef std::uint8_t uint8_t; typedef std::uint16_t uint16_t; typedef std::uint32_t uint32_t; @@ -32,14 +36,14 @@ typedef std::int64_t int64_t; #else -/* - * C++03 doesn't define standard integer types, so we pull it from the C library as a workaround. - */ -# include +# include // Standard integer types from C library +# include // snprintf() from the C library namespace uavcan { +using ::snprintf; + typedef ::uint8_t uint8_t; typedef ::uint16_t uint16_t; typedef ::uint32_t uint32_t; diff --git a/libuavcan/include/uavcan/time.hpp b/libuavcan/include/uavcan/time.hpp index 094016fb35..39528b045b 100644 --- a/libuavcan/include/uavcan/time.hpp +++ b/libuavcan/include/uavcan/time.hpp @@ -6,7 +6,7 @@ #define UAVCAN_TIME_HPP_INCLUDED #include -#include +#include #include #include #include @@ -223,7 +223,6 @@ const unsigned TimeBase::StringBufSize; template void DurationBase::toString(char buf[StringBufSize]) const { - using namespace std; // For snprintf() char* ptr = buf; if (isNegative()) { @@ -238,7 +237,6 @@ void DurationBase::toString(char buf[StringBufSize]) const template void TimeBase::toString(char buf[StringBufSize]) const { - using namespace std; // For snprintf() (void)snprintf(buf, StringBufSize, "%llu.%06lu", static_cast(toUSec() / 1000000UL), static_cast(toUSec() % 1000000UL)); diff --git a/libuavcan/include/uavcan/transport/abstract_transfer_buffer.hpp b/libuavcan/include/uavcan/transport/abstract_transfer_buffer.hpp index 7cc703c4c2..e4a276d1ce 100644 --- a/libuavcan/include/uavcan/transport/abstract_transfer_buffer.hpp +++ b/libuavcan/include/uavcan/transport/abstract_transfer_buffer.hpp @@ -6,7 +6,7 @@ #define UAVCAN_TRANSPORT_ABSTRACT_TRANSFER_BUFFER_HPP_INCLUDED #include -#include +#include namespace uavcan { diff --git a/libuavcan/include/uavcan/transport/can_io.hpp b/libuavcan/include/uavcan/transport/can_io.hpp index cee418569d..867407d056 100644 --- a/libuavcan/include/uavcan/transport/can_io.hpp +++ b/libuavcan/include/uavcan/transport/can_io.hpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/transport/crc.hpp b/libuavcan/include/uavcan/transport/crc.hpp index abee099522..aae2c4d964 100644 --- a/libuavcan/include/uavcan/transport/crc.hpp +++ b/libuavcan/include/uavcan/transport/crc.hpp @@ -6,7 +6,7 @@ #define UAVCAN_TRANSPORT_CRC_HPP_INCLUDED #include -#include +#include #include namespace uavcan diff --git a/libuavcan/include/uavcan/transport/dispatcher.hpp b/libuavcan/include/uavcan/transport/dispatcher.hpp index a34789bf36..ac12bbd2b7 100644 --- a/libuavcan/include/uavcan/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/transport/dispatcher.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp index 9d91ac1955..114cecee22 100644 --- a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp +++ b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp @@ -6,7 +6,7 @@ #define UAVCAN_TRANSPORT_OUTGOING_TRANSFER_REGISTRY_HPP_INCLUDED #include -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/transport/perf_counter.hpp b/libuavcan/include/uavcan/transport/perf_counter.hpp index 009dfeec81..58861897bd 100644 --- a/libuavcan/include/uavcan/transport/perf_counter.hpp +++ b/libuavcan/include/uavcan/transport/perf_counter.hpp @@ -5,7 +5,7 @@ #ifndef UAVCAN_TRANSPORT_PERF_COUNTER_HPP_INCLUDED #define UAVCAN_TRANSPORT_PERF_COUNTER_HPP_INCLUDED -#include +#include #include namespace uavcan diff --git a/libuavcan/include/uavcan/transport/transfer.hpp b/libuavcan/include/uavcan/transport/transfer.hpp index d5c3f8268f..50255fe37c 100644 --- a/libuavcan/include/uavcan/transport/transfer.hpp +++ b/libuavcan/include/uavcan/transport/transfer.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace uavcan { diff --git a/libuavcan/include/uavcan/transport/transfer_buffer.hpp b/libuavcan/include/uavcan/transport/transfer_buffer.hpp index d29bcce9ed..0911f106e4 100644 --- a/libuavcan/include/uavcan/transport/transfer_buffer.hpp +++ b/libuavcan/include/uavcan/transport/transfer_buffer.hpp @@ -5,7 +5,7 @@ #ifndef UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED #define UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED -#include +#include #include #include #include diff --git a/libuavcan/include/uavcan/transport/transfer_listener.hpp b/libuavcan/include/uavcan/transport/transfer_listener.hpp index a8210821ce..e71d50f1e3 100644 --- a/libuavcan/include/uavcan/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/transport/transfer_listener.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/libuavcan/src/driver/uc_can.cpp b/libuavcan/src/driver/uc_can.cpp index ed5723eecd..739740343b 100644 --- a/libuavcan/src/driver/uc_can.cpp +++ b/libuavcan/src/driver/uc_can.cpp @@ -59,8 +59,6 @@ bool CanFrame::priorityHigherThan(const CanFrame& rhs) const #if UAVCAN_TOSTRING std::string CanFrame::toString(StringRepresentation mode) const { - using namespace std; // For snprintf() - UAVCAN_ASSERT(mode == StrTight || mode == StrAligned); static const unsigned AsciiColumnOffset = 36U; diff --git a/libuavcan/src/transport/uc_frame.cpp b/libuavcan/src/transport/uc_frame.cpp index 510b60e6e3..3a3938a01b 100644 --- a/libuavcan/src/transport/uc_frame.cpp +++ b/libuavcan/src/transport/uc_frame.cpp @@ -198,7 +198,6 @@ bool Frame::operator==(const Frame& rhs) const #if UAVCAN_TOSTRING std::string Frame::toString() const { - using namespace std; // For snprintf() /* * Frame ID fields, according to UAVCAN specs: * - Data Type ID diff --git a/libuavcan/src/transport/uc_outgoing_transfer_registry.cpp b/libuavcan/src/transport/uc_outgoing_transfer_registry.cpp index 8054b7f9e0..66cb4a5ad8 100644 --- a/libuavcan/src/transport/uc_outgoing_transfer_registry.cpp +++ b/libuavcan/src/transport/uc_outgoing_transfer_registry.cpp @@ -12,7 +12,6 @@ namespace uavcan #if UAVCAN_TOSTRING std::string OutgoingTransferRegistryKey::toString() const { - using namespace std; char buf[40]; (void)snprintf(buf, sizeof(buf), "dtid=%u tt=%u dnid=%u", int(data_type_id_.get()), int(transfer_type_), int(destination_node_id_.get())); diff --git a/libuavcan/src/transport/uc_transfer_buffer.cpp b/libuavcan/src/transport/uc_transfer_buffer.cpp index 4a56b75632..fb3774c7d9 100644 --- a/libuavcan/src/transport/uc_transfer_buffer.cpp +++ b/libuavcan/src/transport/uc_transfer_buffer.cpp @@ -14,7 +14,6 @@ namespace uavcan #if UAVCAN_TOSTRING std::string TransferBufferManagerKey::toString() const { - using namespace std; // For snprintf() char buf[24]; (void)snprintf(buf, sizeof(buf), "nid=%i tt=%i", int(node_id_.get()), int(transfer_type_)); return std::string(buf); diff --git a/libuavcan/src/uc_data_type.cpp b/libuavcan/src/uc_data_type.cpp index bfe12e8b2c..184d6dc610 100644 --- a/libuavcan/src/uc_data_type.cpp +++ b/libuavcan/src/uc_data_type.cpp @@ -111,7 +111,6 @@ std::string DataTypeDescriptor::toString() const } } - using namespace std; // For snprintf() char buf[128]; (void)snprintf(buf, sizeof(buf), "%s:%u%c:%016llx", full_name_, static_cast(id_.get()), kindch, From 71d4b02a7fa8ee5c00cadf633e22de6dc07c158e Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 14:14:48 +0300 Subject: [PATCH 43/50] Dependency on math.h and the last 'using namespace std' were removed --- libuavcan/include/uavcan/marshal/float_spec.hpp | 10 +++------- libuavcan/include/uavcan/util/templates.hpp | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/libuavcan/include/uavcan/marshal/float_spec.hpp b/libuavcan/include/uavcan/marshal/float_spec.hpp index 2ee680f184..b77328f44a 100644 --- a/libuavcan/include/uavcan/marshal/float_spec.hpp +++ b/libuavcan/include/uavcan/marshal/float_spec.hpp @@ -16,9 +16,7 @@ #ifndef UAVCAN_CPP_VERSION # error UAVCAN_CPP_VERSION #endif -#if UAVCAN_CPP_VERSION < UAVCAN_CPP11 -# include // Needed for isfinite() -#else +#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 # include // Assuming that in C++11 mode all standard headers are available #endif @@ -169,8 +167,7 @@ public: private: static inline void saturate(StorageType& value) { - using namespace std; - if ((IsExactRepresentation == 0) && isfinite(value)) + if ((IsExactRepresentation == 0) && isFinite(value)) { if (value > max()) { @@ -189,8 +186,7 @@ private: static inline void truncate(StorageType& value) { - using namespace std; - if ((IsExactRepresentation == 0) && isfinite(value)) + if ((IsExactRepresentation == 0) && isFinite(value)) { if (value > max()) { diff --git a/libuavcan/include/uavcan/util/templates.hpp b/libuavcan/include/uavcan/util/templates.hpp index e25102790d..e2572ff3d3 100644 --- a/libuavcan/include/uavcan/util/templates.hpp +++ b/libuavcan/include/uavcan/util/templates.hpp @@ -470,6 +470,20 @@ inline bool isInfinity(T arg) #endif } +/** + * Replacement for std::isfinite(). + * Note that direct float comparison (==, !=) is intentionally avoided. + */ +template +inline bool isFinite(T arg) +{ +#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 + return std::isfinite(arg); +#else + return !isNaN(arg) && !isInfinity(arg); +#endif +} + /** * Replacement for std::signbit(). * Note that direct float comparison (==, !=) is intentionally avoided. From bc5d07ab2a8493b5b343f9f661d3529e6b33ad2d Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 21 Mar 2015 16:01:16 +0300 Subject: [PATCH 44/50] snprintf() fix --- libuavcan/include/uavcan/build_config.hpp | 8 +++++ libuavcan/include/uavcan/std.hpp | 42 ++++++++++++++++++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/libuavcan/include/uavcan/build_config.hpp b/libuavcan/include/uavcan/build_config.hpp index eab0e386fe..13a6725f4d 100644 --- a/libuavcan/include/uavcan/build_config.hpp +++ b/libuavcan/include/uavcan/build_config.hpp @@ -134,6 +134,14 @@ # define UAVCAN_IMPLEMENT_PLACEMENT_NEW 0 #endif +/** + * Allows the user's application to provide custom implementation of uavcan::snprintf(), + * which is often useful on deeply embedded systems. + */ +#ifndef UAVCAN_USE_EXTERNAL_SNPRINTF +# define UAVCAN_USE_EXTERNAL_SNPRINTF 0 +#endif + /** * Run time checks. * Resolves to the standard assert() by default. diff --git a/libuavcan/include/uavcan/std.hpp b/libuavcan/include/uavcan/std.hpp index 9e1cbc9a84..c04ced0c89 100644 --- a/libuavcan/include/uavcan/std.hpp +++ b/libuavcan/include/uavcan/std.hpp @@ -2,11 +2,11 @@ * Copyright (C) 2014 Pavel Kirienko */ -#ifndef UAVCAN_STDINT_HPP_INCLUDED -#define UAVCAN_STDINT_HPP_INCLUDED +#ifndef UAVCAN_STD_HPP_INCLUDED +#define UAVCAN_STD_HPP_INCLUDED #include -#include +#include #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11) # error UAVCAN_CPP_VERSION @@ -20,8 +20,6 @@ namespace uavcan { -using std::snprintf; // Can be used to replace standard snprintf() with a user-provided one. - typedef std::uint8_t uint8_t; typedef std::uint16_t uint16_t; typedef std::uint32_t uint32_t; @@ -37,13 +35,11 @@ typedef std::int64_t int64_t; #else # include // Standard integer types from C library -# include // snprintf() from the C library +# include // vsnprintf() from the C library namespace uavcan { -using ::snprintf; - typedef ::uint8_t uint8_t; typedef ::uint16_t uint16_t; typedef ::uint32_t uint32_t; @@ -58,4 +54,32 @@ typedef ::int64_t int64_t; #endif -#endif // UAVCAN_STDINT_HPP_INCLUDED +namespace uavcan +{ +/** + * Wrapper over the standard snprintf(). This wrapper is needed because different standards and different + * implementations of C++ do not agree whether snprintf() should be defined in std:: or in ::. The solution + * is to use 'using namespace std' hack inside the wrapper, so the compiler will be able to pick whatever + * definition is available in the standard library. Alternatively, the user's application can provide a + * custom implementation of uavcan::snprintf(). + */ +#if __GNUC__ +__attribute__ ((format(printf, 3, 4))) +#endif +extern int snprintf(char* out, std::size_t maxlen, const char* format, ...); + +#if !UAVCAN_USE_EXTERNAL_SNPRINTF +inline int snprintf(char* out, std::size_t maxlen, const char* format, ...) +{ + using namespace std; // This way we can pull vsnprintf() either from std:: or from ::. + va_list args; + va_start(args, format); + const int return_value = vsnprintf(out, maxlen, format, args); + va_end(args); + return return_value; +} +#endif + +} + +#endif // UAVCAN_STD_HPP_INCLUDED From bd7a08872827c92980015e82d8d713435daa8d57 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 22 Mar 2015 13:58:27 +0300 Subject: [PATCH 45/50] Air data update --- dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan | 10 ---------- .../equipment/air_data/290.TrueAirspeed.uavcan | 6 ++++++ .../air_data/291.AltitudeAndClimbRate.uavcan | 12 ------------ .../equipment/air_data/291.IndicatedAirspeed.uavcan | 6 ++++++ .../equipment/air_data/294.StaticAirData.uavcan | 9 --------- ...AngleOfAttack.uavcan => 295.AngleOfAttack.uavcan} | 2 +- .../{293.Sideslip.uavcan => 296.Sideslip.uavcan} | 0 .../equipment/air_data/298.StaticPressure.uavcan | 6 ++++++ .../equipment/air_data/410.StaticTemperature.uavcan | 6 ++++++ 9 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan create mode 100644 dsdl/uavcan/equipment/air_data/290.TrueAirspeed.uavcan delete mode 100644 dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan create mode 100644 dsdl/uavcan/equipment/air_data/291.IndicatedAirspeed.uavcan delete mode 100644 dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan rename dsdl/uavcan/equipment/air_data/{292.AngleOfAttack.uavcan => 295.AngleOfAttack.uavcan} (83%) rename dsdl/uavcan/equipment/air_data/{293.Sideslip.uavcan => 296.Sideslip.uavcan} (100%) create mode 100644 dsdl/uavcan/equipment/air_data/298.StaticPressure.uavcan create mode 100644 dsdl/uavcan/equipment/air_data/410.StaticTemperature.uavcan diff --git a/dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan b/dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan deleted file mode 100644 index 46306b28ff..0000000000 --- a/dsdl/uavcan/equipment/air_data/290.Airspeed.uavcan +++ /dev/null @@ -1,10 +0,0 @@ -# -# IAS and TAS in meters per second. -# Unknown values should be assigned NAN. -# - -float16 indicated_airspeed -float16 indicated_airspeed_variance - -float16 true_airspeed -float16 true_airspeed_variance diff --git a/dsdl/uavcan/equipment/air_data/290.TrueAirspeed.uavcan b/dsdl/uavcan/equipment/air_data/290.TrueAirspeed.uavcan new file mode 100644 index 0000000000..ace10e61cb --- /dev/null +++ b/dsdl/uavcan/equipment/air_data/290.TrueAirspeed.uavcan @@ -0,0 +1,6 @@ +# +# TAS. +# + +float16 true_airspeed # m/s +float16 true_airspeed_variance # (m/s)^2 diff --git a/dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan b/dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan deleted file mode 100644 index dc43c54aed..0000000000 --- a/dsdl/uavcan/equipment/air_data/291.AltitudeAndClimbRate.uavcan +++ /dev/null @@ -1,12 +0,0 @@ -# -# Pressure altitude in meters and barometric climb rate in meters per second. -# - -uavcan.Timestamp timestamp - -float32 pressure_altitude # m -float16 pressure_altitude_variance # m^2 - -# Positive if climbing up -float16 climb_rate # m/s -float16 climb_rate_variance # m^2/s^2 diff --git a/dsdl/uavcan/equipment/air_data/291.IndicatedAirspeed.uavcan b/dsdl/uavcan/equipment/air_data/291.IndicatedAirspeed.uavcan new file mode 100644 index 0000000000..c11ea903a6 --- /dev/null +++ b/dsdl/uavcan/equipment/air_data/291.IndicatedAirspeed.uavcan @@ -0,0 +1,6 @@ +# +# IAS. +# + +float16 indicated_airspeed # m/s +float16 indicated_airspeed_variance # (m/s)^2 diff --git a/dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan b/dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan deleted file mode 100644 index 245218669a..0000000000 --- a/dsdl/uavcan/equipment/air_data/294.StaticAirData.uavcan +++ /dev/null @@ -1,9 +0,0 @@ -# -# Static air data for barometric altitude and altitude rate measurements. -# - -float32 static_pressure # Pascal -float16 static_pressure_variance # Pascal^2 - -float16 static_temperature # Kelvin -float16 static_temperature_variance # Kelvin^2 diff --git a/dsdl/uavcan/equipment/air_data/292.AngleOfAttack.uavcan b/dsdl/uavcan/equipment/air_data/295.AngleOfAttack.uavcan similarity index 83% rename from dsdl/uavcan/equipment/air_data/292.AngleOfAttack.uavcan rename to dsdl/uavcan/equipment/air_data/295.AngleOfAttack.uavcan index 89aef90848..c14d7fdcbc 100644 --- a/dsdl/uavcan/equipment/air_data/292.AngleOfAttack.uavcan +++ b/dsdl/uavcan/equipment/air_data/295.AngleOfAttack.uavcan @@ -1,5 +1,5 @@ # -# Angle of attack in radians. +# Angle of attack. # uint8 SENSOR_ID_LEFT = 254 diff --git a/dsdl/uavcan/equipment/air_data/293.Sideslip.uavcan b/dsdl/uavcan/equipment/air_data/296.Sideslip.uavcan similarity index 100% rename from dsdl/uavcan/equipment/air_data/293.Sideslip.uavcan rename to dsdl/uavcan/equipment/air_data/296.Sideslip.uavcan diff --git a/dsdl/uavcan/equipment/air_data/298.StaticPressure.uavcan b/dsdl/uavcan/equipment/air_data/298.StaticPressure.uavcan new file mode 100644 index 0000000000..75d3cc7e06 --- /dev/null +++ b/dsdl/uavcan/equipment/air_data/298.StaticPressure.uavcan @@ -0,0 +1,6 @@ +# +# Static pressure. +# + +float32 static_pressure # Pascal +float16 static_pressure_variance # Pascal^2 diff --git a/dsdl/uavcan/equipment/air_data/410.StaticTemperature.uavcan b/dsdl/uavcan/equipment/air_data/410.StaticTemperature.uavcan new file mode 100644 index 0000000000..7e8d570fe5 --- /dev/null +++ b/dsdl/uavcan/equipment/air_data/410.StaticTemperature.uavcan @@ -0,0 +1,6 @@ +# +# Static temperature. +# + +float16 static_temperature # Kelvin +float16 static_temperature_variance # Kelvin^2 From a12dc5aa98cfd8d998fb385990344e61da0bd93b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 23 Mar 2015 17:34:55 +0300 Subject: [PATCH 46/50] param.GetSet clarifications --- dsdl/uavcan/protocol/param/599.GetSet.uavcan | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsdl/uavcan/protocol/param/599.GetSet.uavcan b/dsdl/uavcan/protocol/param/599.GetSet.uavcan index 65b1950afb..edfa47a5ca 100644 --- a/dsdl/uavcan/protocol/param/599.GetSet.uavcan +++ b/dsdl/uavcan/protocol/param/599.GetSet.uavcan @@ -1,5 +1,7 @@ # # Get or set a parameter by name or by index. +# Note that access by index should only be used to retreive the list of parameters; it is higly +# discouraged to use it for anything else, because persistent ordering is not guaranteed. # # If set - parameter will be assigned this value, then the new value will be returned. @@ -8,6 +10,7 @@ Value value # Index of the parameter starting from 0; ignored if name is nonempty. +# Use index only to retrieve the list of parameters. uint8 index # Name of the parameter; always preferred over index if nonempty. From 6598b15d88d1c5d98119423dd4366296eda0ec7b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 23 Mar 2015 18:14:44 +0300 Subject: [PATCH 47/50] ParamServer logic improvement --- libuavcan/src/protocol/uc_param_server.cpp | 6 ++++++ libuavcan/test/protocol/param_server.cpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 1062332d3b..0a02a97e3e 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -33,6 +33,12 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto out.name = in.name; } + if (out.name.empty()) + { + UAVCAN_TRACE("ParamServer", "GetSet: Can't resolve parameter name, index=%i", int(in.index)); + return; + } + // Assign if needed, read back if (isValueNonEmpty(in.value)) { diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index 861ca41cd3..e43c8f4e43 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -27,6 +27,7 @@ struct ParamServerTestManager : public uavcan::IParamManager virtual void assignParamValue(const ParamName& name, const ParamValue& value) { + assert(!name.empty()); std::cout << "ASSIGN [" << name.c_str() << "]\n" << value << "\n---" << std::endl; KeyValue::iterator it = kv.find(name.c_str()); if (it != kv.end()) @@ -56,6 +57,7 @@ struct ParamServerTestManager : public uavcan::IParamManager virtual void readParamValue(const ParamName& name, ParamValue& out_value) const { + assert(!name.empty()); KeyValue::const_iterator it = kv.find(name.c_str()); if (it != kv.end()) { From 0affb0eaec692412b61f13869716c0b87e074dbd Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 23 Mar 2015 18:34:19 +0300 Subject: [PATCH 48/50] Convenience method IParamManager::isParamValueEmpty() --- libuavcan/include/uavcan/protocol/param_server.hpp | 13 +++++++++++-- libuavcan/src/protocol/uc_param_server.cpp | 12 ++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index 666db73b59..01fe7af545 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -64,6 +64,17 @@ public: * @return Negative if failed. */ virtual int eraseAllParams() = 0; + + /** + * Convenience method that can be used to check if a param value is empty. + */ + static bool isParamValueEmpty(const ParamValue& val) + { + return val.value_bool.empty() && + val.value_int.empty() && + val.value_float.empty() && + val.value_string.empty(); + } }; /** @@ -83,8 +94,6 @@ class UAVCAN_EXPORT ParamServer ServiceServer save_erase_srv_; IParamManager* manager_; - static bool isValueNonEmpty(const protocol::param::Value& value); - void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response); void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request, diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 0a02a97e3e..326995b47c 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -10,14 +10,6 @@ namespace uavcan { -bool ParamServer::isValueNonEmpty(const protocol::param::Value& value) -{ - return !value.value_bool.empty() || - !value.value_int.empty() || - !value.value_float.empty() || - !value.value_string.empty(); -} - void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out) { UAVCAN_ASSERT(manager_ != NULL); @@ -40,14 +32,14 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto } // Assign if needed, read back - if (isValueNonEmpty(in.value)) + if (!IParamManager::isParamValueEmpty(in.value)) { manager_->assignParamValue(out.name, in.value); } manager_->readParamValue(out.name, out.value); // Check if the value is OK, otherwise reset the name to indicate that we have no idea what is it all about - if (isValueNonEmpty(out.value)) + if (!IParamManager::isParamValueEmpty(out.value)) { manager_->readParamDefaultMaxMin(out.name, out.default_value, out.max_value, out.min_value); } From d41a2165464f3080d6c301860fbb6c6a14b778dd Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 24 Mar 2015 02:06:33 +0300 Subject: [PATCH 49/50] BatteryInfo update --- dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan b/dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan index 6b164d2f73..64d1a4da87 100644 --- a/dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan +++ b/dsdl/uavcan/equipment/power/722.BatteryInfo.uavcan @@ -53,11 +53,10 @@ uint7 state_of_charge_pct_stdev # SOC error standard deviation; use best # # Battery identification. -# Instance ID must be unique within the same battery model name. +# Model instance ID must be unique within the same battery model name. # Model name is a human-readable string that normally should include the vendor name, model name, and chemistry # type of this battery. This field should be assumed case-insensitive. Example: "Zubax Smart Battery v1.1 LiPo". # -uint32 instance_id # Set to zero if not applicable -uint6 battery_index # Identifies the battery within this vehicle, e.g. 0 - primary battery -uint2 group_id # Not used, set zero +uint8 battery_id # Identifies the battery within this vehicle, e.g. 0 - primary battery +uint32 model_instance_id # Set to zero if not applicable uint8[<32] model_name # Battery model name From 0c8f0700af72baf1f43829620feccfa647a992a4 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 24 Mar 2015 22:25:25 +0300 Subject: [PATCH 50/50] protocol.param.GetSet update - min/max only for numeric types, longer string value --- dsdl/uavcan/protocol/param/599.GetSet.uavcan | 7 ++--- .../uavcan/protocol/param/NumericValue.uavcan | 8 ++++++ .../{ValueString.uavcan => String.uavcan} | 2 +- dsdl/uavcan/protocol/param/Value.uavcan | 2 +- .../include/uavcan/protocol/param_server.hpp | 27 ++++++++++++------- libuavcan/src/protocol/uc_param_server.cpp | 4 +-- libuavcan/test/protocol/param_server.cpp | 10 +++---- .../linux/apps/uavcan_nodetool.cpp | 20 ++++++++++++-- 8 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 dsdl/uavcan/protocol/param/NumericValue.uavcan rename dsdl/uavcan/protocol/param/{ValueString.uavcan => String.uavcan} (66%) diff --git a/dsdl/uavcan/protocol/param/599.GetSet.uavcan b/dsdl/uavcan/protocol/param/599.GetSet.uavcan index edfa47a5ca..296b91266d 100644 --- a/dsdl/uavcan/protocol/param/599.GetSet.uavcan +++ b/dsdl/uavcan/protocol/param/599.GetSet.uavcan @@ -25,9 +25,10 @@ uint8[<=92] name # Empty value indicates that there is no such parameter. Value value -Value default_value # Optional -Value max_value # Optional -Value min_value # Optional +Value default_value # Optional + +NumericValue max_value # Optional, not applicable for bool/string +NumericValue min_value # Optional, not applicable for bool/string # Empty name in response indicates that there is no such parameter uint8[<=92] name diff --git a/dsdl/uavcan/protocol/param/NumericValue.uavcan b/dsdl/uavcan/protocol/param/NumericValue.uavcan new file mode 100644 index 0000000000..76d782f9a0 --- /dev/null +++ b/dsdl/uavcan/protocol/param/NumericValue.uavcan @@ -0,0 +1,8 @@ +# +# Numeric-only value. +# The actual type should be inferred from the available values, as described below. +# If none of the values below are present, the value is considered empty. +# + +int64[<=1] value_int # Preferred over float if ambiguous +float32[<=1] value_float # Only if int is empty diff --git a/dsdl/uavcan/protocol/param/ValueString.uavcan b/dsdl/uavcan/protocol/param/String.uavcan similarity index 66% rename from dsdl/uavcan/protocol/param/ValueString.uavcan rename to dsdl/uavcan/protocol/param/String.uavcan index 1607f0935f..e5e42bfb5c 100644 --- a/dsdl/uavcan/protocol/param/ValueString.uavcan +++ b/dsdl/uavcan/protocol/param/String.uavcan @@ -2,4 +2,4 @@ # This type is nested in Value. # -uint8[<64] value +uint8[<=127] value diff --git a/dsdl/uavcan/protocol/param/Value.uavcan b/dsdl/uavcan/protocol/param/Value.uavcan index 44bf6f98e2..5a47150eff 100644 --- a/dsdl/uavcan/protocol/param/Value.uavcan +++ b/dsdl/uavcan/protocol/param/Value.uavcan @@ -7,4 +7,4 @@ bool[<=1] value_bool # Preferred over int, float and string if ambiguous int64[<=1] value_int # Preferred over float and string if ambiguous float32[<=1] value_float # Preferred over string if ambiguous -ValueString[<=1] value_string # This one will be used only if all above are empty +String[<=1] value_string # This one will be used only if all above are empty diff --git a/libuavcan/include/uavcan/protocol/param_server.hpp b/libuavcan/include/uavcan/protocol/param_server.hpp index 01fe7af545..8f7bdef5e0 100644 --- a/libuavcan/include/uavcan/protocol/param_server.hpp +++ b/libuavcan/include/uavcan/protocol/param_server.hpp @@ -19,33 +19,35 @@ namespace uavcan class UAVCAN_EXPORT IParamManager { public: - typedef typename StorageType::Type ParamName; - typedef typename StorageType::Type ParamIndex; - typedef protocol::param::Value ParamValue; + typedef typename StorageType::Type Name; + typedef typename StorageType::Type Index; + typedef protocol::param::Value Value; + typedef protocol::param::NumericValue NumericValue; virtual ~IParamManager() { } /** * Copy the parameter name to @ref out_name if it exists, otherwise do nothing. */ - virtual void getParamNameByIndex(ParamIndex index, ParamName& out_name) const = 0; + virtual void getParamNameByIndex(Index index, Name& out_name) const = 0; /** * Assign by name if exists. */ - virtual void assignParamValue(const ParamName& name, const ParamValue& value) = 0; + virtual void assignParamValue(const Name& name, const Value& value) = 0; /** * Read by name if exists, otherwise do nothing. */ - virtual void readParamValue(const ParamName& name, ParamValue& out_value) const = 0; + virtual void readParamValue(const Name& name, Value& out_value) const = 0; /** * Read param's default/max/min if available. + * Note that min/max are only applicable to numeric params. * Implementation is optional. */ - virtual void readParamDefaultMaxMin(const ParamName& name, ParamValue& out_default, - ParamValue& out_max, ParamValue& out_min) const + virtual void readParamDefaultMaxMin(const Name& name, Value& out_default, + NumericValue& out_max, NumericValue& out_min) const { (void)name; (void)out_default; @@ -66,15 +68,20 @@ public: virtual int eraseAllParams() = 0; /** - * Convenience method that can be used to check if a param value is empty. + * Convenience methods that can be used to check if a param value is empty. */ - static bool isParamValueEmpty(const ParamValue& val) + static bool isValueEmpty(const Value& val) { return val.value_bool.empty() && val.value_int.empty() && val.value_float.empty() && val.value_string.empty(); } + static bool isValueEmpty(const NumericValue& val) + { + return val.value_int.empty() && + val.value_float.empty(); + } }; /** diff --git a/libuavcan/src/protocol/uc_param_server.cpp b/libuavcan/src/protocol/uc_param_server.cpp index 326995b47c..908400af91 100644 --- a/libuavcan/src/protocol/uc_param_server.cpp +++ b/libuavcan/src/protocol/uc_param_server.cpp @@ -32,14 +32,14 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto } // Assign if needed, read back - if (!IParamManager::isParamValueEmpty(in.value)) + if (!IParamManager::isValueEmpty(in.value)) { manager_->assignParamValue(out.name, in.value); } manager_->readParamValue(out.name, out.value); // Check if the value is OK, otherwise reset the name to indicate that we have no idea what is it all about - if (!IParamManager::isParamValueEmpty(out.value)) + if (!IParamManager::isValueEmpty(out.value)) { manager_->readParamDefaultMaxMin(out.name, out.default_value, out.max_value, out.min_value); } diff --git a/libuavcan/test/protocol/param_server.cpp b/libuavcan/test/protocol/param_server.cpp index e43c8f4e43..245864a83f 100644 --- a/libuavcan/test/protocol/param_server.cpp +++ b/libuavcan/test/protocol/param_server.cpp @@ -12,9 +12,9 @@ struct ParamServerTestManager : public uavcan::IParamManager typedef std::map KeyValue; KeyValue kv; - virtual void getParamNameByIndex(ParamIndex index, ParamName& out_name) const + virtual void getParamNameByIndex(Index index, Name& out_name) const { - ParamIndex current_idx = 0; + Index current_idx = 0; for (KeyValue::const_iterator it = kv.begin(); it != kv.end(); ++it, ++current_idx) { if (current_idx == index) @@ -25,7 +25,7 @@ struct ParamServerTestManager : public uavcan::IParamManager } } - virtual void assignParamValue(const ParamName& name, const ParamValue& value) + virtual void assignParamValue(const Name& name, const Value& value) { assert(!name.empty()); std::cout << "ASSIGN [" << name.c_str() << "]\n" << value << "\n---" << std::endl; @@ -55,7 +55,7 @@ struct ParamServerTestManager : public uavcan::IParamManager } } - virtual void readParamValue(const ParamName& name, ParamValue& out_value) const + virtual void readParamValue(const Name& name, Value& out_value) const { assert(!name.empty()); KeyValue::const_iterator it = kv.find(name.c_str()); @@ -158,7 +158,7 @@ TEST(ParamServer, Basic) get_set_rq = uavcan::protocol::param::GetSet::Request(); get_set_rq.index = 0; { - uavcan::protocol::param::ValueString str; + uavcan::protocol::param::String str; str.value = "424242"; get_set_rq.value.value_string.push_back(str); } diff --git a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp index dd387591f2..2c2d60ae42 100644 --- a/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp +++ b/libuavcan_drivers/linux/apps/uavcan_nodetool.cpp @@ -90,11 +90,27 @@ std::string paramValueToString(const uavcan::protocol::param::Value& value) } else if (!value.value_string.empty()) { - return std::string(value.value_string[0].value.c_str()); + return std::string(value.value_string[0].value.c_str()) + " "; } else { - return "?"; + return ""; + } +} + +std::string paramValueToString(const uavcan::protocol::param::NumericValue& value) +{ + if (!value.value_int.empty()) + { + return std::to_string(value.value_int[0]); + } + else if (!value.value_float.empty()) + { + return std::to_string(value.value_float[0]); + } + else + { + return ""; } }