2025-06-05

The make system has received a major update.
cmake minimum version is now 3.16. This value should be updated in all existing mira projects' top CMakeLists.txt file,
to ensure consistent make behaviour!
Support for mira on Windows is completely dropped, enabling a lot of code cleanup (it had been not really maintained for years).
Use of AddressSanitizer (ASan) and Ccache compiler cache can be enabled by global options (see make/GlobalConfig.cmake).
In some cases, small changes are required to package make definitions, package maintainers should see MIRAenvironment.changelog.

The runtime version check applied during manifest and library loading is now able to detect more cases of inconsistent lib versions,
(e.g. from incomplete rebuilds), and the framework will throw an exception (essentially abort the application) if this
is encountered during startup.
Errors from library loading AFTER startup (e.g. when a visualization plugin is loaded triggered by user interaction) do NOT
abort the application, they are logged as errors and can also be observed in the Libraries View (for local or remote frameworks).

XMLDom (used most prominently for configuration of applications) now supports xml macros, providing a way to much better organize
complex content. See https://www.mira-project.org/MIRA-doc/XMLMacrosPage.html.

The behaviour of reading from channels has significantly changed: For small datatypes, the ChannelRead object
will now just hold a copy of the read channel slot's content, instead of locking and referencing it. This will be more efficient
and in particular resolves a nasty deadlock error when a subscriber tries to read from a channel twice, possibly
hidden through some call hierarchy.
Datatypes must be marked using the new IsCheapToCopy trait to make use of this. All C++ fundamental types and "small" MIRA
datatypes are defined as 'cheap to copy'. For other types, the channel read behavious is unchanged.

Thread monitoring data is now serializable, the ThreadMonitor tool in miracenter allows to observe remote frameworks.

The Framework option "--save-processed-config" is now accompanied by "--save-processed-config-annotated",
which will not only show the complete result of the XML preprocessor, but also add source info (file+line) to each
line of the document. Helpful for debugging complex configs consisting of nested inclusions.

mirapackage supports clientID/clientSecret potentially required by (GitLab) repositories. Repos at gitlab.metralabs.com
do not require this info (yet), though.



2024-11-01

There is a new option to build MIRA without any GUI components and tools (avoiding some dependencies),
see make/GlobalConfig.cmake.
We also added support for newer systems which use libproc2 instead of libprocps.

Installation directories during compile time are stripped from file paths shown in exception or log messages.

Serialization:
Legacy format binary serializers are not fully supported anymore by default (to save compilation time and size),
they can be re-enabled in make/GlobalConfig.cmake if needed.
For Time, Date and Duration, accessors and alternative classes are added that serialize to/from human-readable
XML/JSON content instead of plain millisecond count.
XML deserialization of maps (<key>+<item> 'lists') requires matching number of keys and items instead
of ignoring extra <key> tags (which should indicate missing items and would often confuse key/item relations).
Fixed wrong errors or even wrong results without indicating an error when deserializing some JSON data
not matching the object definition (e.g. number/string mismatches).

DispatcherThread and Authority have a new method hasWork(), useful in combination with manual
invocation of spin().

The framework allows ad-hoc creation of channels with the new RPC method createChannel(name, type).

TapePlayerUnit and TapeRecorderUnit interfaces have been cleaned up. The TapeRecorderUnit is only
controlled through RPC, a new AutoTapeRecorderUnit can be used to record automatically through a config file.

Using TextView to write to a channel now registers a publisher, so the channel update can actually be forwarded
to remote connected frameworks.
A bug has been fixed in the MIRACenter TapePlayer widget which would prevent playback of tapes shorter than 1 second.

RotateTask: fixed a serialization bug making it impossible to properly control the direction of motion.



2024-04-16

If multiple occurences of a library are found during manifest generation (e.g. same package installed
in multiple project directories), ManifestGen lists them in the error message.

The generic stream operator>> for JSONValue was not correctly implementing input of arbitrary JSON from
string based streams, this has been fixed by adding a specific operator overload for std::basic_stringstream.
Another issue was fixed which was preventing compilation of JSONValue stream operators with gcc12 and newer
(and clang).

OpenSSL integration has been updated, removing calls to deprecated functions when using OpenSSL v3.

In analogy to writeJSON(), a writeXML() method has been added to Channel, ChannelBuffer etc., allowing
to directly post data encoded in XML, e.g. within an XML configuration file.

Authority::unsubscribe() does not require the channel type anymore. For compatibility, the template method
unsubscribe<Type>() remains valid, but the type is ignored. In particular, a wrong type (different from
subscription) does not cause a crash from a null pointer dereference anymore.

In DispatcherThread, several issues have been fixed related to stop() interrupting scheduled functions,
which could lead to incomplete initialization or timers not starting again on next start().
MicroUnits already enter 'Bootup' state before they are checked in (instead of when they start to initialize),
allowing to reliably query if their bootup has finished and their initialization is complete.

  Note: it is possible now that a MicroUnit's initialize() function is called repeatedly if the MicroUnit
        (Authority) is stopped during execution of initialize(). Although stopping+restarting during
        initialization can and should be avoided in normal operation, implementation of initialize()
        may need to be aware of this.
        E.g. subscribing a channel callback again will lead to the callback function being called
        twice for each channel update!

In the AuthorityManager, locking against concurrent access has been improved to avoid deadlocks
from recursive calls such as when an Authority's start() or stop() implementation creates/destroys another
Authority.



2023-12-15

The MIRA environment enables C++17 standard for compilation, compilers not supporting C++17 are
not supported anymore.

Added a serialization adapter for std::variant.

Added RigidTransform::isWellDefined() to check against NaN elements and invalid covariance matrices.

The variadic function implementation for the RPC framework has been reworked, resulting in unlimited
number of parameters for RPC functions, and better compile time error diagnostics.

Authority has a new startWithParent() method, to control whether child authorities are started
when their parent authority starts (required for dynamical switching of submodule activity
when the parent authority can be stopped and restarted within an application).

A ServiceCall class was added, which acts as a proxy for RPC service methods, with the possibility
to check the existence of the service and method (name + signature) at initialization.

miracenter AuthorityView:
The displayed autority status is queried by Authority::isStarted()
(not Authority::isRunning()), giving more granular status for child authorities.



2023-10-13

Build system: New required versions for cmake (>= 3.10) and gcc (>= 7.0).

XMLDomPreprocessor: variable 'filePath' resolves correctly in files included from xml with no URI.

Parameter names for RPC signatures are explicitly stripped of const/reference qualifiers.

The performance of the JSONSerializer was improved by avoiding unnecessary copy operations.

Framework: restructured all commandline parameters for clearer presentation.

Fixed potential crash when closing a remote framework connection.

When an exception is thrown while querying properties of a remote authority,
a copy of the original exception will be thrown to the caller (instead of generic XIO).

PropertyEditor supports properties of type int64/uint64.

mirapackage: Added a lot of new command line options and most functions
can now be used from the command line.



2023-03-17

During build, when there is a discrepancy between a class' abstractness declaration
from MIRA_[ABSTRACT_]OBJECT and its actual abstractness, the manifest generator will not just
output an error message, but make the build fail by returning an exit code.

Serialization: added support for boost::variant.

The type name string created by typeName() includes the type's const/volatile qualifiers
by default (can be disabled by an optional parameter).

Toolbox CameraParameters: added DepthCameraIntrinsic, depth camera visualization.

Toolbox RigidModel (Markers): added a new MeshMarker class, allowing to 
dynamically create objects of arbitrary shape, based on a mesh file
(which can be created with 3D editing software like Blender).

Toolbox RobotDataTypes: added wrench transformation operators and 3D visualization.

miracenter: fullscreen view is restored correctly when loading a respective workspace.



2023-02-01

Geometry: MIRABase provides a new rasterPolygon() method. This provides a generally more
exact shape rendering compared to CollisionTest from RigidModel toolbox, while relative performance
heavily depends on the actual shape.
CollisionTest performance has also been improved by storing a bounding box for the active cells from the
calculation of lookup tables (best speedup for shapes with high length:width ratio).

Toolbox Navigation: Added new task RestrictAreaTask 

miracenter: with the Ctrl-P command, the view is now captured immediately before displaying
the 'Save as' dialogue, improving the possibility to capture dynamic view content.

mirapackage: fixed some errors related to handling upper/lower case in URLs.



2022-11-25

XML configs (XMLDOM processing): <include> tag now also supports 'select_not' attribute.

QtUtils::toQImage() has been refactored improving clarity, safety and efficiency, and thus replaced by
makeQImage() and asQImage().

mirapackage supports index files for gitlab repositories -> reindexing a repo can be accelerated
substantially by providing server-side index.

Recording time for a tape is shown correctly in miracenter TapePlayer even if the tape
was recorded in a different timezone than where it is played back.



2022-09-13

External dependencies: Updated to eigen 3.4.0.

General: Added some compiler and linker flags for hardening the MIRA binaries and shared libraries.

Handling of angle values: implicit conversion of Angle and related types to float/int has been
removed, to avoid semantical ambiguity and misguided arithmetics. Replaced many instances of
Angle type variables by float etc. where they were used for values counting in degrees (or derived units),
but not restricted to a 360 degrees interval (velocities, tolerances etc.). In all cases of type changes,
serialization compatibility is retained (existing configs etc. are read without requiring any change).
Simplified usage of rad2degGetter/deg2radSetter and added combined radAsDegAccessor for these cases
(degrees but not angle). Enabled conversion functions deg2rad/rad2deg for integral types.

Accessing JSON values: Existing functions json::getElement()/getNumberElement() are complemented by
has[Number]Element()/get[Number]ElementIfExists(), to avoid having to rely on exceptions if structure not
exactly defined.

Serialization: Added REFLECT_CTRLFLAG_MEMBER_AS_ROPROPERTY to simplify exposing a member as read-only
property additionally. Trying to use an empty initializer list ('{}') as deserialization default is rejected
by the compiler as ambiguous instead of unambiguously matching the initializer to the 'flags' argument (most
probably not what was intended).

mirapackage: Fixed some package confusion when working with multiple Gitlab repositories. Fixed parsing of empty
command parameters in package file (e.g. MIRA_TAGS("")).

miracenter:
AuthorityView: fix errors in case both a namespace and an authority exist with the same name.
RPCConsole: tab completion can be used for quoted parameters ('> Service.load(" + TAB') to auto-complete filenames.



2022-05-05

Introduced a protection mechanism against making classes abstract by mistake, e.g. by adding pure virtual
methods to a base class and failing to implement them in the (meant as non-abstract) subclass. This
is a mistake easily overlooked with MIRA's class factory providing 'instantiate by name' or 'instantiate
by ancestry' options, meaning there may be no code explicitly instantiating a class, which would result
in compiler errors inevitably.
The class factory now demands to declare abstract classes by the use of MIRA_ABSTRACT_OBJECT
(in place of MIRA_OBJECT). Failing to do so will show an error message at build time (manifest generation)
naming the class.
For now, the build still continues after this error (of course abstract classes can still not be
instantiated), in a later release we intend to make the build fail entirely at this point to prevent
missing/ignoring the error. Developers are expected to adapt their code (only required for abstract classes
registered with the class factory, i.e. using MIRA_OBJECT).



2022-03-25

Framework connections to remote frameworks can be defined as 'monitor-only', then they will not publish
local channels, services and authorities to the remote framework. This can help to avoid subtle errors
inadvertently influencing a running application's behaviour.

Generally replaced QObject::trUtf8() by QObject::tr() for translations, as the former is deprecated in Qt5.15
(released May 2020). When using MIRA with Qt4 (for which developer support ended 2015), this may or may not
result in problems with string representations for translations using exotic characters. In other words,
support for MIRA with Qt4 is deprecated (but it should still remain usable for most purposes).

New command line tool 'miracat' can be used to view contents of a file located in a mira package
(similar to miraedit, but only displays the file content in the terminal).

miracenter has a new command line option '--ignore-desktop-settings', making the GUI ignore the desktop's
display settings for colors, fonts, sizes, effects etc. This can help make better use of screen estate
on some systems.



2021-12-09

The clock offset estimation protocol was buggy in the previous release (2021-11-12). It has been fixed now.
Any instances running the previous release should be updated as soon as possible to enable connections with
correct time sync.



2021-11-12

When serializing an object, it is now possible to request the serializer to create specific versions for
certain classes (older than their respective current versions), by means of
ReflectorInterface::desireClassVersions(). Note that most classes' serialization implementations do not yet
support this feature and will have to be updated before it becomes comprehensively usable. Desiring an older
version from a class that does not implement it will only result in a warning output, but not change the
behaviour otherwise (compared to past releases).

The service level for a remote channel subscription can now include an update interval, i.e. there will be a
minimum time between channel updates sent to the remote subscriber (in other words, the update rate is limited).
The purpose is of course to save transfer bandwidth for large data/high publish rate channels. The implementation
ensures the latest update is always sent to the remote subscriber if the minimum interval expires without newer
data being published (ensuring the subscriber will not permanently miss the latest channel state).
Of course this only works if local (subscriber) and remote (publisher) framework run with this newest release
(or later). For connections to older remote frameworks, a ServiceLevel.Interval setting is ignored, just showing
a warning.

More consistent clock offset estimation for remote framework connections:
The clock offset is now only estimated on one end of the connection (the outgoing side), and applied to both
received and sent channel updates.
Formerly, both ends of the connection estimated the offset independently and applied it to received messages
only. This mostly lead to different estimates, which would then e.g. be applied as different corrections to
timestamps sent on a 'round trip'. That means when a publisher at framework A was publishing to channel CA
with a timestamp, and a subscriber in framework B was copying the received timestamp from CA, using it
to publish to channel CB, a subscriber to CB in framework A would then receive a timestamp significantly
different from the original publish to CA.
With the new correction scheme, the offsets applied on sending and receiving will cancel out, except for
changes of the offset estimation over time (which should be nearly insignificant for data sent and received
in quick succession).

Names of a couple of basic visualization classes have changed, in order to improve naming scheme consistency.
This may lead to existing workspace files becoming unloadable, as some stored class names are not valid
anymore. For convenience, an update script is provided which can be used to substitute the changed class
names in a workspace file: scripts/updateWorkspaces-Visualization.sh 

Clearer presentation of available visualizations when drag+dropping a channel to the MDI area or a view:
Visualizations can be marked as 'auxiliary' and will not appear in the visualization selection list although
they could take the respective channel as input. All items in the selection list got a tooltip showing their
description.
The 'auxiliary' categorization is done by the visualization's developer (together with the description).
E.g. Plot Threshold visualizations from 2021-05-19 release have been marked as auxiliary, for less clutter
in visualization selection dialog.
Auxiliary visualization can still be created from the VisualizationControl panel, as before. Users can also
change MIRACenter preferences to include them in selection lists again.

BarChart plots/visualizations from toolbox PlotVisualization have been not working since at least
MIRA Release 2017-01-18, they have now been fixed and are available again.



2021-07-28

Pending RPC calls will automatically return with an error when the corresponding service is removed (e.g. the
connection to a remote framework is lost), without having to wait for a timeout (or, even worse, wait infinitely).

The CRSplineInterpolator has been completed to be usable as an alternative to e.g. LinearInterpolator.

Authority constructor was ignoring the flag INDEPENDENT_SUBSCRIBER_THREAD,
and Authority::subscribeInterval() was ignoring the independentThread parameter. Both issues have been fixed.
(Authority::subscribe() was properly respecting its independentThread parameter though.)

Specifying explicit transformation types FIXED/MOVING (introduced 2021-12-23) has been simplified:
the type can be specified in config <link> tags (read by LinkLoader), and also in Authority::addTransformLink().
The documentation of the transformation framework has been updated to explain the meaning of fixed and moving
transformations.

Numerous improvements to tape handling:
Trying to open a tape that is not a file will throw with a meaningful error message (instead of reading garbage).
TapePlayer::stepTo(channel) could add some unnecessary waiting time, which was fixed. Also added stepToAnyOf()
to use multiple channels.
TapeRecorder could mess up message order when used with avoidDataLoss=true, fixed. Instead of waiting for
the recording queue to be processed in the background thread, TapeRecorder::stop() can return immediately and
rely on the caller to clean up the queue. This is used by the TapeRecorderWidget to show a progress bar while
waiting for the queue to finish. That widget now also allows to set a time limit when starting a recording.

Writing/posting to channels with an invalid timestamp (Time::invalid()) could easily terminate the entire program.
This could happen e.g. when unknowingly creating an unitialized Stamped<> while trying to post a channel-type
object to be initialized with an empty initializer-list. A number of fixes have been added to remove the risk
of termination (ensuring an exception is thrown, or, if that is unsafe, an error message displayed) and prevent
accidental wrong usage of Channel::post().

A possible deadlock was fixed between channel writers and interval readers when using up the channel's
maximum slot number (when writing faster than reading).

Toolbox Navigation: documentation has been updated for complete description of all task types provided by
the toolbox.

Toolbox RobotDataTypes: added IPTU (generic interface for Pan-Tilt-Unit driver).

Tool mirapackage supports git repositories whose default branch is not 'master'.

Tool miratape: simplified selection of a common time interval for play/merge with multiple tapes.



2021-05-19

Framework gets a new RPC method 'loadConfig' (designated by the new interface 'IConfigurationLoader'). Using
this RPC, additional configuration parts can be loaded at any time (just as they normally are at startup). Since
it is an RPC, this can even be done remotely.
MIRACenter's 'Configuration Editor' view has been upgraded and is now using this RPC. That means any valid
configuration can be entered (using the usual xml syntax) and executed. If remote frameworks are connected,
the config can be loaded to those, via a selection combobox.

RPC calls using parameters of type std::string do not need to explicitly cast string literals to search for the
correct RPC signature (like callService<void>("Service", "method", "std::string("foo"));). Such literals will be
recognized as std::string type automatically.

3D view gets new tools: "Localize - Position only" and "Localize - Orientation only". Services supporting the
respective RPC methods setInitPosition/setInitorientation will only re-initialize the position and keep the
current orientation distribution unchanged (or vice versa).
Furthermore, the interpretation of the selected range (for pose and orientation) by the Localize tools has
been changed to allow more intuitive input: where before the region was taken as sigma^2 (=variance), it
is now a 2*sigma range, i.e. 95% of distribution should be in this region.

PlotVisualization gets a bunch of useful new items: The Events visualization can plot a vertical line marker
for just the time of each channel update. Thresholds visualizations plot horizontal line markers, either from
channel data or from a manually edited property.



2021-04-07

Definition of RPC methods without RPC parameter documentation is marked as deprecated. Such definitions will
show compile time deprecation warnings. To get rid of these warnings, add parameter documentation (name, description
[, sample value] for each parameter) to the service's RPC method definitions (= calls to r.method() in reflect()).

RemoteConnection has been overhauled to make it more stable and fix frequent crashes on disconnection.



2021-02-17

Process supports recursive shutdown, i.e. stopping the spawned process will (optionally) also terminate all
descendant processes. The <process> configuration tag makes this available through its new attribute
'shutdownRecursively'.

Framework gets a new option '--show-variables' (available to tools like mira, miracenter etc.), which lists all
known configuration variables and their values at startup.

ConfigurationLoader plugins (handlers for configuration tags) hold the list of associated tags in their class
factory metadata. It is not required anymore to load all libraries with the loader implementations just to
determine which loader handles which tags. Only loader libraries required for present tags will be loaded.



2020-12-23

MIRA libraries are automatically registered to a LibraryRegistry on application start. The registry keeps track
of known libraries (=manifests) and loaded libraries, with their respective versions. The registry information is
available through new Framework RPC methods 'getLibraries'/'getLoadedLibraries'. MIRACenter gets a new
LibrariesListView where this information can be looked up, for the local or any connected framework.

The print() function gets a new 'CompactPrint' mode (no line breaks, helpful e.g. for logging), and a new parameter
to control the output floating point precision.

PropertyNode and property interaction tools like MIRACenter's property editor are significantly extended to support
dynamic properties (adding or removing properties at runtime).
The most notable use case is containers of dynamic size: the property editor will automatically update itself to
show when items are added or removed by internal processing (the option to let the user add or remove items through
the GUI is planned for the future).
This enables to add the RemoteModule with its (updating) list of current remote connections as read-only property
of the Framework itself.

A number of optimizations has been implemented to reduce overhead for internal copying of RPC parameters/results. In
some cases, internal processing amounted to up to 15 copy operations on a parameter object! Now copies are avoided
in favor of moves whereever possible, no more than 3 copies are ever necessary.
Note:
1. const& parameters and return values are more efficient than value parameters, even when used through RPC.
2. non-const reference parameters in RPC methods will lead to compile errors now. However, this has never been a valid
   option anyway, as RPCs are callable from a different process. That means there is no assumption of shared memory
   between caller and function, the reference will most likely just refer to a temporary variable in the RPC framework,
   no use modifying it.

FrameworkTransformer nodes can be marked as FIXED or MOVING. Creating such transformation nodes from model files will
automatically set their types, based on the Joint type. For fixed nodes, the corresponding channel's slot limit is
automatically set to 1, preventing (unwanted) interpolation when the transformation is changed (e.g. calibration, not
motion). MIRACenter's TransformTreeView shows the type of each node.

GUI widgets with filters do not filter once when the filter string is edited, but keep filtering when their content
changes (e.g. AuthorityView will show any authorities added later as long as they are matching the currently set filter).

The new interface IResourceFileProvider complements IRigidModelProvider: a service providing a model description can
also provide resource files for its visualization. RigidModelVisualization (for 3D view) tries downloading mesh files
that the model is referring to from the service, if they are not found locally.



2020-09-10

The time synchronisation between connected frameworks is smoothed: offset is aligned slowly between estimates,
to prevent changing the time order of channel updates received from remote framework when the offset estimation
changes by more than the channel update interval.

MIRACenter 3DView: camera motion discontinuities are fixed. Changing the CameraFrame property will adapt the camera pose
reversely to keep the current view unchanged, instead of moving around the camera.



2020-07-21

The RPC framework shows a warning when a service registers multiple methods with same name and parameter count (even with
different parameter types, aka 'overloading'), as these are not distinguishable for JSON RPC (all parameters are presented
as JSON representation, their type cannot be determined in general).

RemoteConnection stores incoming RPC requests and responses (to be transferred to the remote framework) in a queue
and handles the actual transfer in a separate thread. This avoids blocking the local RPC framework while waiting for a
slow/overloaded network connection.

Service levels for channel connections can now also be set by channel type (in addition to channel name). Thus it is
possible to e.g. select PngCodec to be used for all channels of type 'mira::Img<>'. Service levels set for individual
channel names take priority over service levels set for a channel type.

When writing a tape, compression can not just be enabled or disabled, but different levels of compression can be selected.
The TapeRecorder widget in MIRACenter presents a combobox for compression level instead of a checkbox.

MIRACenter AuthorityView shows unknown authority status (not queried yet or query RPC timed out) as 'Unknown' instead of
'Paused'. Start/Stop is split into two buttons, which also work while the respective authority status is locally unknown.



2020-06-03

Framework's variables and aliases (<using> declarations) are exposed through new RPC methods 'getAliases'/'getVariables'.
MIRACenter DefinitionsListView uses these to query and present the definitions from all connected frameworks.



2020-04-26

JSON values always keep maximum floating point precision when transferred to a remote framework
(not limited to local default display precision). Most notable case is JSON RPC parameters/return values.

MIRA exception types are now serializable. When an exception is thrown within an RPC method, it is serialized
and transfered to the call site. The caller can choose whether in that case a generic XRPC or the restored specific
exception should be thrown to him by the RPC framework, via a parameter in his call to RPCFuture::get().
(Previously, XRPC was the only option, in that case the message string is the only element identifying the original
error).
