First Commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
This article compares different actuators that are used in robotic systems.
|
||||
@@ -0,0 +1,8 @@
|
||||
https://www.geeksforgeeks.org/a-search-algorithm/
|
||||
|
||||
|
||||
# To Remember
|
||||
1.
|
||||
|
||||
# To Study / Verify
|
||||
1. Can we add wind to heuristic function --> it is easier to move with wind instead of against the wind
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: Divide and Conquer
|
||||
created_date: 2024-10-22
|
||||
updated_date: 2024-10-22
|
||||
aliases:
|
||||
tags:
|
||||
---
|
||||
# Divide and Conquer
|
||||
|
||||
This is an algorithm design paradigm, where the main problem is split into sub problems, which then are split into further sub problems to be finally solved on a smaller level and if needed stitched back together to the overall solution. This recursive approach is often used in [[computer science]].
|
||||
Mathematically, the algorithms are often proved to be true by [[mathematical induction]].
|
||||
## Example Algorithms
|
||||
- [[Sorting Algorithms]] such as quicksort or merge sort
|
||||
- Multiplying large numbers: [[Karatsuba Algorithm]]
|
||||
- Find the closest pair of points
|
||||
- Computing the discrete Fourier Transform ([[Fast Fourier Transform |FFT]])
|
||||
|
||||
It can also be used in [[Computer Vision]] by first defining interesting [[Region of Interests |ROI]]s and only running the heavy algorithm on the subpart of the image.
|
||||
|
||||
## Advantages
|
||||
- [[GPU]]s can be used to parallelize those subtasks and thus run the process much faster
|
||||
- simplification: the problems become simpler to solve
|
||||
- Algorithmic efficiency: reduce the [[big-O notation]]
|
||||
- Memory Access: If the problem is small enough one can use only the computer [[cache]] to solve the subproblem, which makes it way faster
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
aliases:
|
||||
- ICP
|
||||
---
|
||||
[Iterative closest point](https://en.wikipedia.org/wiki/Iterative_closest_point) (ICP) is an algorithm to minimize the difference between two clouds of points, which means it can be used to reconstruct 2D or 3D surfaces from different scans. It is an algorithm that tries to solve the generic problem of [Point-Set registration](https://en.wikipedia.org/wiki/Point-set_registration)
|
||||
|
||||
|
||||
|
||||
# Implementations
|
||||
- The library [libpointmatcher](https://github.com/norlab-ulaval/libpointmatcher?tab=readme-ov-file)
|
||||
- The lightweight library [simpleICP](https://github.com/pglira/simpleICP)
|
||||
-
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Karatsuba Algorithm
|
||||
created_date: 2024-10-22
|
||||
updated_date: 2024-10-22
|
||||
aliases:
|
||||
tags:
|
||||
big-O: 1.58
|
||||
---
|
||||
# Karatsuba Algorithm
|
||||
|
||||
The Karatsuba Algorithm is used to multiply two numbers. It uses a [[Divide and Conquer]] strategy to make it computationally efficient, having a [[big-O notation]] of $n^{log_{2}3}\approx n^{1.58}$.
|
||||
|
||||
The main takeaway of the algorithm is that it uses a higher base to perform three easier and faster multiplications with less digits and then subtracts corrective terms to get the correct result
|
||||
@@ -0,0 +1,47 @@
|
||||
Sources
|
||||
https://www.youtube.com/watch?v=kRp3eA09JkM&ab_channel=HummingbirdRobotics
|
||||
https://github.com/thehummingbird/robotics_demos/blob/main/behavior_trees/grasp_place_robot_demo/bt_demo.cpp
|
||||
|
||||
- https://github.com/polymathrobotics/ros2_behavior_tree_example/tree/main/src/plugins
|
||||
- https://github.com/BehaviorTree/BehaviorTree.CPP/issues/412
|
||||
- https://github.com/Adlink-ROS/BT_ros2
|
||||
|
||||
# Using BT with ROS2
|
||||
https://www.youtube.com/watch?v=KO4S0Lsba6I&ab_channel=TheConstruct
|
||||
|
||||
![[Pasted image 20231005132551.png]]
|
||||
|
||||
![[Pasted image 20231005134909.png]]
|
||||
![[Pasted image 20231005135001.png]]
|
||||
});
|
||||
|
||||
![[Pasted image 20231005135120.png]]
|
||||
|
||||
### Move Robot
|
||||
![[Pasted image 20231005135254.png]]
|
||||
![[Pasted image 20231005135348.png]]
|
||||
![[Pasted image 20231005135419.png]]
|
||||
|
||||
|
||||
Rotate class
|
||||
![[Pasted image 20231005135545.png]]
|
||||
|
||||
|
||||
|
||||
main
|
||||
![[Pasted image 20231005135626.png]]
|
||||
|
||||
![[Pasted image 20231005135643.png]]
|
||||
|
||||
## Definitions
|
||||
- Sequence: can be considered as a logical AND gate
|
||||
- Fallback: can be considered as a logical OR gate
|
||||
# Library Description
|
||||
Alternatively you can use the python library: https://github.com/splintered-reality/py_trees_ros/tree/devel
|
||||
|
||||
## Behaviortree Factory
|
||||
Here the behaviortree logic is stored and managed. Nodes that implement actions or conditions need to be registered here such that they can be executed. The BehaviorTree Factory is the place where the [[Business Logic]] is implemented.
|
||||
|
||||
|
||||
# BehaviorTree Design
|
||||
![[Pasted image 20231005172207.png]]
|
||||
@@ -0,0 +1,3 @@
|
||||
Mapping in robotics is the process of measuring and sensing the environment and using this information to populate a map. In the process the information is categorized (usually into obstacles and free space) into useful categories that are needed for the specific robotic application.
|
||||
|
||||
In order to start mapping we need to have information about where we are and thus [[Localization]] is required.
|
||||
@@ -0,0 +1,6 @@
|
||||
It is a open-loop control system that tries to predict and counteract vibrations in a actuated system such as a 3D printer. The first couple of minutes of [this video](https://youtu.be/Fe_BFGg_ojg) explain a bit more.
|
||||
|
||||
# Use
|
||||
## 3D Printers
|
||||
This year, 3d printers have become 10 times faster while keeping the same print quality mostly because of input shaper technology. The guy in the video above uses a frequency test suite to test for resonance peaks. Next to the large peaks there are often small peaks that often correspond to screws that are slightly loose. In the image below you can see a pre / post tightening of all screws of the frame. The first of the doublepeak around 40Hz completely disappeared after the tightening.
|
||||
![[Pasted image 20240312175212.png]]
|
||||
@@ -0,0 +1,2 @@
|
||||
Path planning is the process of finding a path between a starting pose and a goal pose.
|
||||
In order to plan a path we need a map, which is a representation of the environment. The map usually is dynamic and calculated by a process called [[Mapping]].
|
||||
@@ -0,0 +1,41 @@
|
||||
[[ROS2]] is a bit tedious to debug, because it is inherently asynchronous and multi threaded.
|
||||
|
||||
A good way is to use VSCode for example like this:
|
||||
https://gist.github.com/JADC362/a4425c2d05cdaadaaa71b697b674425f
|
||||
|
||||
As always the nav2 library is a good place for resources: [get backtrace explanation](https://navigation.ros.org/tutorials/docs/get_backtrace.html).
|
||||
## Requirements
|
||||
In order to run this we need to install gdbserver: `sudo apt install gdbserver`
|
||||
## Launch Files
|
||||
In the launch file, when adding a Node, add a `prefix="gdbserver localhost:3000"`:
|
||||
```python
|
||||
Node(
|
||||
package='nav3_controller',
|
||||
executable='controller_server',
|
||||
output='screen',
|
||||
respawn=use_respawn,
|
||||
respawn_delay=2.0,
|
||||
parameters=[configured_params],
|
||||
prefix='gdbserver localhost:3000',
|
||||
arguments=['--ros-args', '--log-level', log_level],
|
||||
remappings=remappings + [('offboard_cmd', 'offboard_velocity_cmd')]
|
||||
)
|
||||
```
|
||||
|
||||
This will create gdb as a server. Now we need to configure VSCode to attach to this debug session (as explained [here](https://answers.ros.org/question/267261/how-can-i-run-ros2-nodes-in-a-debugger-eg-gdb/)) add a new launch configuration like this:
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "C++ Debugger",
|
||||
"request": "launch",
|
||||
"type": "cppdbg",
|
||||
"miDebuggerServerAddress": "localhost:3000",
|
||||
"cwd": "/",
|
||||
"program": "[build-path-executable]"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
Also known as managed Nodes in [[ROS2]]. The [[ROS2 - NAV2 Library|NAV2]] library makes good use of it.
|
||||
From [ROS2 Design](https://design.ros2.org/articles/node_lifecycle.html):
|
||||
>A managed life cycle for nodes allows greater control over the state of ROS system. It will allow roslaunch to ensure that all components have been instantiated correctly before it allows any component to begin executing its behaviour. It will also allow nodes to be restarted or replaced on-line.
|
||||
|
||||
>The most important concept of this document is that a managed node presents a known interface, executes according to a known life cycle state machine, and otherwise can be considered a black box. This allows freedom to the node developer on how they provide the managed life cycle functionality, while also ensuring that any tools created for managing nodes can work with any compliant node.
|
||||
|
||||
There are 4 primary states: *unconfigured, inactive, active, finalized*
|
||||
There are 7 transitions: *create, configure, cleanup, activate, deactivate, shutdown and destroy*
|
||||
## States
|
||||
All nodes start with the **unconfigured** state, which is kind of like an empty state where everything starts but it might also end there
|
||||
More important is the **inactive** state. its purpose is to breath life into a node. It allows the user to read parameters, add subscriptions and publications and (re)configure it such that it can fulfill its job. This is done while the node is not running. While a node is in this state it will not receive any data from other processes.
|
||||
## Transition Callbacks
|
||||
The main functions to implement for a custom node in the lifecycle scheme are:
|
||||
### onConfigure()
|
||||
Here the things are implemented that are executed only once in the Node's lifetime, such as obtaining permanent memory buffers and setting up topic publications/subscriptions that do not change.
|
||||
|
||||
### onCleanup()
|
||||
This is the transition function that is called when a Node is being taken out of service (essentially the oposite of *onConfigure()*. Essentially it leaves the node without a state, such that there is no difference between a node that got cleaned up and another that was just created.
|
||||
|
||||
### onActivate()
|
||||
This callback is responsible to implement any final preparations before the node is executing its main purpose. Examples are acquiring resources needed for execution such as access to hardware (it should return fast without a lengthy hardware startup).
|
||||
|
||||
### onDeactivate()
|
||||
This callback should undo anything that *onActivate()* did.
|
||||
|
||||
## Management Interface
|
||||
This is a common interface to allow a managing node to manage the different lifecycle nodes accordingly.
|
||||
|
||||
## Managing Node
|
||||
This is the node that loads the different lifecycle nodes and is responsible to bring them from one state into the next and handle any error they feed back.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
aliases:
|
||||
- NAV2
|
||||
- Navigation
|
||||
- ROS2
|
||||
---
|
||||
- How is the NAV2 library structured?
|
||||
- What are the core concepts?
|
||||
- How can we utilize it to improve our own code?
|
||||
|
||||
# ROS2 and NAV2
|
||||
Because navigation is usually a long running task, [[ROS2 - NAV2 Library|NAV2]] uses [[ROS2]] actions (servers and clients) to implement and execute navigation tasks. Actions servers implement the actual execution in a separate thread and thus can be running in a blocking manner (a [shared Future object](https://en.wikipedia.org/wiki/Futures_and_promises) is used to communicate Feedback and results). The feedback can be shared both synchronously through callbacks and asynchronously through requesting information from the shared future object. In any case we spinning the client node is required.
|
||||
## Lifecycle Nodes (aka. Mangaged Nodes)
|
||||
NAV2 relies heavily on [[ROS2 - Lifecycle Nodes]], because it helps to structure the program in reasonable ways for commercial uses and debugging.
|
||||
All servers in NAV2 use the lifecycle nodes and it is the best convention for all ROS systems to use lifecycle nodes if possible.
|
||||
|
||||
# Behavior Trees
|
||||
[[Behaviour Trees]] are used as the main concept to implement complex tasks and the application logic. In order to do that behaviors are broken down into primitives (very basic behavior).
|
||||
|
||||
From [NAV2 documentation:](https://navigation.ros.org/concepts/index.html)
|
||||
>For this project, we use [BehaviorTree CPP V3](https://www.behaviortree.dev/) as the behavior tree library. We create node plugins which can be constructed into a tree, inside the `BT Navigator`. The node plugins are loaded into the BT and when the XML file of the tree is parsed, the registered names are associated. At this point, we can march through the behavior tree to navigate.
|
||||
|
||||
|
||||
# Source Code Walk Through
|
||||
The version of nav2 I used to write our own nav3 library was: 7009ffba on october 16th 2023.
|
||||
## NAV2 Common
|
||||
This package contains only launchfiles that implement classes to facilitate writing other launch files. Functions like rewriting part of a file, replacing strings, check if node parameters are available, etc.
|
||||
# Navigation Servers
|
||||
## Planners
|
||||
## Controllers
|
||||
There is a single GoalChecker Plugin that implements the GoalChecker interface. It is called SimpleGoalChecker
|
||||
|
||||
# Navigation illumination Video
|
||||
[Vimeo Video](https://vimeo.com/106994708)
|
||||
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/106994708?h=5972d2a502" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
|
||||
|
||||
|
||||
Controller (Local Planner)
|
||||
![[Pasted image 20231019145329.png]]
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
The Pluginlib is a library for [[ROS2]] that allows a very modular development. It is heavily used in the [[ROS2 - NAV2 Library|NAV2]] Library.
|
||||
From the [pluginlib tutorial]():
|
||||
>`pluginlib` is a C++ library for loading and unloading plugins from within a ROS package. Plugins are dynamically loadable classes that are loaded from a runtime library (i.e. shared object, dynamically linked library). With pluginlib, you do not have to explicitly link your application against the library containing the classes – instead `pluginlib` can open a library containing exported classes at any point without the application having any prior awareness of the library or the header file containing the class definition. Plugins are useful for extending/modifying application behavior without needing the application source code.
|
||||
|
||||
Basically it allows to define an abstract base class that defines the interface of the plugin. It defines what functions (`virtual`) need to be overwritten and what variables are there. You can then derive multiple packages with different implementations of this plugin base class which is used by an executor function. Those plugins can then be loaded at runtime without prior knowledge about them because they follow the same structure.
|
||||
|
||||
Requirements:
|
||||
1. Constructor without parameters -> use initialization function instead.
|
||||
2. Make header available to other classes
|
||||
1. Add the following snippet to `CMakeLists.txt`:
|
||||
```cmake
|
||||
install(
|
||||
DIRECTORY include/
|
||||
DESTINATION include
|
||||
)
|
||||
...
|
||||
ament_export_include_directories(
|
||||
include
|
||||
)
|
||||
```
|
||||
3. In the c++ file where you define your plugins you need to add the following macro at the very end. This creates the plugin instances when the corresponding library is loaded.
|
||||
```cpp
|
||||
#include <pluginlib/class_list_macros.hpp>
|
||||
|
||||
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)
|
||||
PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon)
|
||||
```
|
||||
4. The plugin loader needs some information to find the library and to know what to reference in the libary. Thus an xml-file needs to be written as well as an export line in the package.xml file. With those 2 additions ROS knows everything it needs to know in order to use the plugins. In the following snippets we have the two Plugins: Square and Triangle defined in a plugin.xml file.
|
||||
```xml
|
||||
<library path="polygon_plugins">
|
||||
<class type="polygon_plugins::Square" base_class_type="polygon_base::RegularPolygon">
|
||||
<description>This is a square plugin.</description>
|
||||
</class>
|
||||
<class type="polygon_plugins::Triangle" base_class_type="polygon_base::RegularPolygon">
|
||||
<description>This is a triangle plugin.</description>
|
||||
</class>
|
||||
</library>
|
||||
```
|
||||
|
||||
```cmake
|
||||
# polygon_base: package with base class
|
||||
# plugins.xml: relative path to plugin file defined above
|
||||
pluginlib_export_plugin_description_file(polygon_base plugins.xml)
|
||||
```
|
||||
|
||||
How to use the plugins
|
||||
The plugins can be used in any package that you want
|
||||
```cpp
|
||||
#include <pluginlib/class_loader.hpp>
|
||||
#include <polygon_base/regular_polygon.hpp>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// To avoid unused parameter warnings
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("polygon_base", "polygon_base::RegularPolygon");
|
||||
|
||||
try
|
||||
{
|
||||
std::shared_ptr<polygon_base::RegularPolygon> triangle = poly_loader.createSharedInstance("polygon_plugins::Triangle");
|
||||
triangle->initialize(10.0);
|
||||
|
||||
std::shared_ptr<polygon_base::RegularPolygon> square = poly_loader.createSharedInstance("polygon_plugins::Square");
|
||||
square->initialize(10.0);
|
||||
|
||||
printf("Triangle area: %.2f\n", triangle->area());
|
||||
printf("Square area: %.2f\n", square->area());
|
||||
}
|
||||
catch(pluginlib::PluginlibException& ex)
|
||||
{
|
||||
printf("The plugin failed to load for some reason. Error: %s\n", ex.what());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
>Important note: the `polygon_base` package in which this node is defined does NOT depend on the `polygon_plugins` class. The plugins will be loaded dynamically without any dependency needing to be declared. Furthermore, we’re instantiating the classes with hardcoded plugin names, but you can also do so dynamically with parameters, etc.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
- [ ] #todo/b Write overview of what ros2 does in my own words. Advantages / disadvantages
|
||||
|
||||
# Build System
|
||||
The ROS2 [build system](https://docs.ros.org/en/humble/Concepts/Advanced/About-Build-System.html)is a challenging part, because packages written in different languages such as [[C++]] or [[Python]] need to be built together in order to form a unit.
|
||||
To achieve this ROS2 relies heavily on the [[Colcon]] build system, which under the hood uses [[CMake]] for C++ packages and setuptools for Python. In order to define dependencies across the different packages and languages, ROS2 packages always contain a `package.xml` file also known as manifest file that contains essential metadata about the package, such as dependencies and others.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: AnySkin
|
||||
created_date: 2024-10-28
|
||||
updated_date: 2024-10-28
|
||||
aliases:
|
||||
tags:
|
||||
- sensor
|
||||
---
|
||||
# AnySkin
|
||||
This is a skin sensor, which detects tactile touch by measuring distortions in magnetic fields, generated by iron particles in a silicon moulded skin. The skin is therefore soft and can be fabricated in any shape.
|
||||
|
||||
## Source
|
||||
[AnySkin: Plug-and-play Skin Sensing for Robotic Touch](https://any-skin.github.io/)
|
||||
@@ -0,0 +1,7 @@
|
||||
[This article ](https://robohub.org/anatomy-of-a-robotic-system/) does a good job in describing the different levels of abstraction within a robotic system. The key takeaways for me are:
|
||||
- In a robot there must be a high level feedback loop (not control systems) within the robot that does not require human input, else it is a machine.
|
||||
- A robot operates in the physical world. A chat-bot is not a robot.
|
||||
- Several layers of abstractions can be used to define robotic behavior:
|
||||
- Functional layer: control, raw sensory perception, actuation and speech generation (move arm to position XY, apply force Z)
|
||||
- Behavioral layer: motion planning, navigation and making sense of language (open the door --> which makes use of the functional layer)
|
||||
- Abstract layer: Task and behavior planning ([[Behaviour Trees]] or Finite State Machines), Semantic Understanding and Reasoning (What is our environment made of, can I interact with it? What do I want to achieve and what can I do to succeed?)
|
||||
Reference in New Issue
Block a user