A set of algorithms and other tools for robotics in Rust.
It is almost entirely no_std and most things work without alloc. It does not currently integrate with any API directly. This may be added in the future, probably through another crate.
This basically means that you can do whatever you want as long as you give me attribution and you don't remove the license notices or use my name to endorse stuff I don't. Read the actual license for details though.
RRTK was previously licensed under LGPL. Versions 0.5.0-alpha.1 and earlier have been retroactively dual licensed under LGPL-3.0-only OR BSD-3-Clause. Versions after 0.5.0-alpha.1 are just BSD-3-Clause. This transition does not remove any freedoms, and the LGPL for old versions is maintained solely due to its irrevocability. It is entirely redundant freedoms-wise.
- Architecture based on
Getter,Settable, andUpdatabletraits - Node-like stream system for data processing
- Basic arithmetic + integral and derivative
- Logic and control flow management
- PID
- Moving average
- EWMA
- Trait for making your own
- Graph-based device control system
- Devices hold terminals which can be connected together
- Differential, axle, and direction reversal builtin
- Easily connect streams to the device system through wrappers
- Trapezoidal motion profile following
RRTK Stream Builder: Code generation from visual nodes for the stream system.
RRTK Procedural Macros [HIGHLY EXPERIMENTAL]: Procedural math! macro making the stream system easier to use.
Initial release.
Fix motion profile issue.
Start new motor-encoder system.
Function for motors to follow motion profiles.
Allow the user to run a custom update loop for motion profile following as an alternative to the single function.
Add an update method to encoders.
Add an update method to motors, allow easier detection of parts of motion profiles, and reorganize the package to use features with the motor-encoder system in a module.
Start new stream system.
Reorganize a bit and add EWMA stream.
Add moving average stream.
- performance improvements
- use array instead of vec for inputs to
SumStreamandProductStream - avoid unnecessary weight sum calculation in
MovingAverageStream - make the number of shifts in
PIDControllerShifta constant
- use array instead of vec for inputs to
- replace all instances of
MotionProfileStatewithMotionProfilePiece - add
Historytrait, which is like aStreambut you specify a time when youget - reorganize streams into modules
- remove unnecessary
stdrequirement for a couple types
- Move from
Streamand the previous device system toGetterandSettable.Getteris like a stream or encoder andSettableis like a writable device. - Add
Devicetype which makes rawGetters andSettables work together better as mechanical devices in a system. This should represent a physical device. - Add
Axletype which contains multipleDeviceobjects. It uses the capabilities of each device to control the real-life system. Eg. Data is gathered fromGetterdevices (Device::Readfor encoders andDevice::ReadWritefor servos) and used to control motors that do not contain their own control theory processing (Device::ImpreciseWrite), but motors that can do this on their own (Device::ReadWriteandDevice::PreciseWritedepending on whether the internal data can be read) do not need this control. This object should represent a physical linkage between devices. - Don't require a feature to be enabled for PID controller types
- Change API for PID controller types to be constructed with a k-values type rather than three individual
f32s.
- Don't require a feature to be enabled for motion profiles.
- Make
Settableable to followGetters of the same type. - Add
GetterFromHistorystruct allowingHistoryobjects to be used asGetters.
- Add
set_deltaandset_timemethods toGetterFromHistory. - Move
streams::ConstanttoConstantGetter. - Implement
SettableforConstantGetter. - Add
get_last_requestmethod toSettable. - Move
MotionProfileget_*methods toOptioninstead ofResult. - Rename
UpdateOutputtoNothingOrError. - Fix
Axlebug where it would try to use nonexistent PID controllers forDevice::ImpreciseWriteobjects if it had not yet received aCommand. - Instead of directly implementing
setinSettable, you now implementdirect_set. You should still call justsetthough. This is a workaround required to makeSettableDataandget_last_requestwork correctly. - Move
MotionProfiletoHistory<Command, E>instead ofHistory<State, E>. - Move timestamps to
i64instread off32. The recommended unit is nanoseconds. This is notu64due to the use of deltas. - Fix
MovingAverageStreampanicing issue. - Rename
StreamPIDtoPIDControllerStream. - Improve performance of
PIDControllerStream. - Mark
Errorenum as non-exhaustive. - Write three example files.
- Derive additional traits for a few structs.
- Give
MotionProfilea return value after it has completed. This is based on the end state provided to the constructor. It will choose the lowest possible position derivative to satisfy the end state. This means that if acceleration is 0, the position derivative in the command will be velocity, otherwise acceleration. If velocity is also 0, it will be position, otherwise just velocity. - Add
get_(position|velocity|acceleration)methods toCommand. - Add
Lateststream allowing you to choose the output of whichever of a set of streams has the later timestamp. - Implement
From<State>forCommand. - Rename
TimeGetterFromStreamtoTimeGetterFromGetter.
- Implement several
core::opstraits andCopyforState - Fix name of
PositionToState - Slightly improve performance of
MotionProfileand(Position|Velocity|Acceleration)ToStateby removing unnecessary code - Improve tests
- Minor documentation fixes
- Add missing LGPL license notice to a few files
- Begin new device system.
- Make everything use
&RefCell<Terminal>rather thanRc<RefCell<Terminal>> - Make math streams use generics.
- Add
SettableCommandDeviceWrapperandGetterStateDeviceWrapperallowing types only implementingSettable<Command, _>to be used as motors and types only implementingGetter<State, _>to be used as encoders. - Revive
PositionDerivativeDependentPIDKValues, now with aget_k_valuesmethod for getting the k-values for a specific position derivative. - Add
evaluatemethods forPIDKValuesandPositionDerivativeDependentPIDKValues. - Add
CommandPID, an easier and faster way to use PID control to turn a standard DC motor and an encoder into a de facto servo. - Add
latestfunction which gets the newer of twoDatumobjects.
- Add new
streamssubmodulesflowandlogic. - Add new streams
Expirerflow::IfStreamflow::IfElseStreamflow::FreezeStreamlogic::AndStreamlogic::OrStreamlogic::NotStream
- Pass through
NotforDatum<T>whereTimplementsNot. - Add
NoneGetter. - Add
Axlevery similar to 0.4.0-alpha.1 one. - Move
(SettableCommand|GetterState)DeviceWrappertodevices::wrappersmodule. - Add experimental
Deviceimplementor for a differential mechanism. - Remove now-unused
GetterSettablemarker trait. - Move new device system to a new
devicesfeature. - Minor documentation fix for
devicesmodule.
- Make differential calculations able to trust all branches equally instead of ignoring one.
- Remove unnecessary
Boxing fromInputGetterandInputTimeGetter.
- Rename
following_updatetoupdate_following_dataand removeupdatecalls from it. - Make
GetterFromHistoryuse&mut dyn Historyinstead ofBox<dyn History>and make its constructors takeimpl Historyinstead ofdyn History. - Remove now-unnecessary
new_for_motion_profileconstructor forGetterFromHistory. - Remove
Clonebound onHistory<T, _>'sT. - Make
GetterFromHistoryreturn the requested timestamp as itsDatumtimestamp rather than that that the internalHistoryreturns. - Make
make_input_getterandmake_input_time_getterfunctions instead of macros. - Add
NoneGetterconstructor. (It is a unit struct, so this is redundant.); - Add a
disconnectmethod toTerminal. - Add methods to builtin devices for getting references to their terminals.
- Slightly improve performance of
Terminal'sgetimplementation by using an array ofMaybeUninitrather thanVec. - Minor documentation fixes.
- Fix
Invertget_terminal_2which was returning terminal 1. - Make terminals pass commands to their connected counterparts.
- Rename
SettableCommandDeviceWrappertoActuatorWrapper. - Make
ActuatorWrapperupdate its innerSettable. - Make
ActuatorWrappercallupdate_terminalsin itsUpdatableimplementation. - Fix
CommandPIDerror integral doubling bug. - Add
TerminalDatatype containing a timestamp, an optional command, and an optional state. - Implement
Getter<TerminalData, _>forTerminal. - Add
PIDWrapper, a wrapper very similar toActuatorWrapperthat uses aCommandPIDto control a DC motor rather than needing a servo or a control system set up by the user. - Implement
TimeGetterfori64. It will always return its value as a time. - Remove unused
CannotConnectTerminalserror variant. - Make
GetterStateDeviceWrapperupdate its innerGetter. - Keep
CommandPIDfrom resetting itself whenever it gets a new command rather than only when the command is different. - Mark constructors for
State,Datum,PIDKValues,PositionDerivativeDependentPIDKValues, andCommandasconst. - Documentation improvements.
- Make a new
Referencetype that can hold a*mut T,Rc<RefCell<T>>, or*const RwLock<T>, allowing you to not need a dynamic allocator. - Add
allocfeature. - Temporarily remove
devices::wrappers::PIDWrapper. It will be back by the time this is stable.
- Move to BSD 3-Clause license.
- Implement
CloneforReference - Add
to_dyn!macro for creatingReference<dyn Trait>objects. - Add function
rc_refcell_referenceand macrosstatic_reference!andstatic_rwlock_reference!which work similarly to the formermake_input_getter. They put their input into a container if required and then return aReferenceto it. - Make all stream inputs
?Sized. This allows the use ofReference<dyn Getter<_, _>>andReference<dyn TimeGetter<_, _>>in the builtin streams. - Add
PIDWrapperback. - Update many tests to use
Reference. - Minor documentation changes.
- Add
ArcRwLock,PtrMutex, andArcMutexReferencevariants. - Standardize snake_case of
ref_cellandrw_lock. - Standardize that the outermost container comes first in variable and function names: a
*const RwLockisptr_rw_lock, notrw_lock_ptr.
- Fix the potential for undefined behavior without an unsafe block by directly constructing
Referencevariants.- Rename
ReferencetoReferenceUnsafe.- Make
borrowandborrow_mutmethods ofReferenceUnsafeunsafe.
- Make
- Add a wrapper struct for
ReferenceUnsafeunder the nameReference.Reference(the wrapper struct) cannot be constructed with a raw pointer without an unsafe block or a macro that ensures that the pointer's target is static.Referencehas all of the same methods asReferenceUnsafeexcept thatborrowandborrow_mutare safe.Referencehas one additional method,into_inner, which returns its innerReferenceUnsafe.
- Rename
- Rewrite
SumStreamandProductStreamto not requirealloc. - Change macro scoping to allow both
rrtk::reference::to_dyn!andrrtk::to_dyn!as valid paths, and similar scoping for otherReference-related macros. See the documentation for more information. - Derive
EqforDatum. - Documentation improvements.
- Begin new dimensional analysis system.
- Use correct units in
Mul<Time>andDiv<Time>implementations forQuantity. - Move constant
Units to thedimensions::constantsmodule, all of the items of which are reexported both to thedimensionsmodule and at the crate's top level. - Add many new constant units in addition to the original 6.
- Add
dim_check_debuganddim_check_releasefeatures. - Document feature flags in crate-level documentation.
- Add
FloatToQuantityandQuantityToFloatstreams. - Add
Sum2andProduct2streams, which are optimized for adding or multiplying two inputs faster thanSumStreamandProductStream, which take any number of inputs. - Implement:
AddAssignforTimeSubAssignforTimeMulAssign<DimensionlessInteger>forTimeDivAssign<DimensionlessInteger>forTimeAdd<Quantity>forTimeSub<Quantity>forTimeMul<Quantity>forTimeDiv<Quantity>forTimeAddAssignforDimensionlessIntegerSubAssignforDimensionlessIntegerMulAssignforDimensionlessIntegerDivAssignforDimensionlessIntegerAdd<Quantity>forDimensionlessIntegerSub<Quantity>forDimensionlessIntegerMul<Quantity>forDimensionlessIntegerDiv<Quantity>forDimensionlessIntegerAddAssignforQuantitySubAssignforQuantityMulAssignforQuantityDivAssignforQuantityAdd<Time>forQuantitySub<Time>forQuantityAddAssign<Time>forQuantitySubAssign<Time>forQuantityMulAssign<Time>forQuantityDivAssign<Time>forQuantityAdd<DimensionlessInteger>forQuantitySub<DimensionlessInteger>forQuantityMul<DimensionlessInteger>forQuantityDiv<DimensionlessInteger>forQuantityAddAssign<DimensionlessInteger>forQuantitySubAssign<DimensionlessInteger>forQuantityMulAssign<DimensionlessInteger>forQuantityDivAssign<DimensionlessInteger>forQuantityAddAssignforUnitSubAssignforUnitMulAssignforUnitDivAssignforUnitNegforUnit
- Make
State::updatetakeTime. - Make
State::set_constant_(position|velocity|acceleration)takeQuantity. - Add
State::set_constant_(position|velocity|acceleration)_rawfunctions to still allow setting each position derivative withf32. - Make
State::newtakeQuantityfor position, velocity, and acceleration. - Add
State::new_rawto still allow constructingStatewithf32values. - Make
(Position|Velocity|Acceleration)ToStatetakeQuantity. - Make
IntegralStreamandDerivativeStreamtakeQuantity. - Make
EWMAStreammore generic, allowing it to take bothf32andQuantity. - Make
MovingAverageStreammore generic, allowing it to take bothf32andQuantity. - Mark
State::set_constant_(position|velocity|acceleration)and their "raw" equivalents as const fn. - Fix bug where the implementation of
From<PositionDerivative> for Unitwould return an incorrect second exponent. - Fix unit issue in
MovingAverageStream. - Example improvements.
- Unit testing improvements.
- Documentation improvements.
- Add optional support for
libmandmicromathforno_stdfloat computation. Both are disabled by default. - Propagate commands from terminals in
AxleandInvertdevices. (It is not possible inDifferential). - Add
GearTraindevice which also propagates commands. - Add
replace_if_older_thanmethod toDatum. - Add
OptionDatumExttrait used for addingreplace_if_none_or_older_thanandreplace_if_none_or_older_than_optionmethods toOption<Datum<T>>. - Implement
NegforCommand. - Implement
Add,Sub,Mul<f32>, andDiv<f32>and their respective*Assigntraits forCommand. - Implement
Getter<Command, E>forTerminal. - Minor documentation fixes.