diff --git a/docs/hardware/lte_connection.md b/docs/hardware/lte_connection.md index a35e2c4a..1fadab87 100644 --- a/docs/hardware/lte_connection.md +++ b/docs/hardware/lte_connection.md @@ -24,7 +24,7 @@ However, there are several types of devices and ways to connect them. The device ## SW setup The MRS UAV system uses systemd-newtorkd to control network connections. networkd doesn't support the modems option. Therefore NetworkManager needs to be used. It is disabled by default. Use the following command to start it: -``` +```bash sudo systemctl start NetworkManager -- to start program in current session sudo systemctl enable NetworkManager -- to start automatically on boot ``` @@ -32,17 +32,17 @@ It also requires a `modem-manager` to be installed, but this should already be d ### Netplan config Before updating the control, you have to find the device name. To do that, call: -``` +```bash nmcli device ``` this will output all available devices for NetworkManager. In our case, it was called **cdc-wdm0**. Once you have the device name, you can update the `/etc/netplan/01-netcfg.yaml`. First, replace the `renderer`, which selects a program that manages the connections, with NetworkManager. -``` +```bash renderer: NetworkManager ``` Then, add the following to the end of the config, such that `modems` is aligned with `ethernets` and `wifis`: -``` +```bash modems: cdc-wdm0: apn: internet diff --git a/docs/introduction/c_to_cpp.md b/docs/introduction/c_to_cpp.md index 930e5199..0c865f6b 100644 --- a/docs/introduction/c_to_cpp.md +++ b/docs/introduction/c_to_cpp.md @@ -41,12 +41,12 @@ Many of these problems may be tackled using more focused tools in C++, significa In many cases, pointers may be avoided altogether in C++ by using references, especially when passing function parameters (see the [next section](#function-parameters)). However, references are useful in other cases as well. Consider the following scenario, where you want to transform the fifth element of the container `cont`: -``` +```cpp cont.at(102) = 10 + 3*cont.at(102) + 0.1*cont.at(102)*cont.at(102); ``` Here, the `at()` method of the `cont` object is called four times, which may be quite costly e.g. in the case of a linked-list, and is error-prone (a single typo in the index number can break this code). A cleaner version may be obtained using references: -``` +```cpp auto& cur_el = cont.at(102); cur_el = 10 + 3*cur_el + 0.1*cur_el*cur_el; ``` @@ -79,7 +79,7 @@ Note that ROS uses the [Boost implementation](https://www.boost.org/doc/libs/1_7 Luckily, the Boost shared pointer works identically to the standard library (although they cannot be converted to each other's type). When instantiating a `std::shared_ptr`, use the `std::make_shared()` function, which takes the object `T`'s constructor parameters as arguments - e.g.: -``` +```cpp class Bar { public: @@ -99,16 +99,16 @@ Similarly for `std::unique_ptr` and `std::make_unique`. The rules of thumb when defining function parameters is: 1. If you're taking a primitive type as a parameter (e.g. `int`, `float`, `bool` etc.), use a constant copy: - ``` + ```cpp bool foo(const int a, const float b); ``` 2. If you're taking a class/struct, use a constant reference: - ``` + ```cpp class Bar, Baz; Bar foo(const int a, const Baz& b); ``` 3. If you need to return multiple variables, there are several possibilities: - ``` + ```cpp std::tuple foo(const int a) { if (a > 0) @@ -123,7 +123,7 @@ The rules of thumb when defining function parameters is: const auto [c, b] = foo(a); ``` or - ``` + ```cpp bool foo(const int a, float& ret_b) { if (a > 0) @@ -143,7 +143,7 @@ The rules of thumb when defining function parameters is: const bool c = foo(a, b); ``` 4. If you want to modify a parameter passed to a function (e.g. use the function to update an object's value), use a reference, but make this clear (ideally by naming of the function and the parameters): - ``` + ```cpp void append_squared(std::vector& to, const float new_val) { to.push_back(new_val*new_val); @@ -198,7 +198,7 @@ It happens even to the best of us ☺. ### Iterating through containers Since C++11, the [range-based `for` loops](https://en.cppreference.com/w/cpp/language/range-for) syntactic sugar is available. Specifically, the following syntax is legal for any container that implements the `begin()` and `end()` methods according to the standard (e.g. `std::vector`, [`std::forward_list`](https://en.cppreference.com/w/cpp/container/forward_list), `pcl::PointCloud`, `cv::Mat` etc.): -``` +```cpp for (const auto& element : container) { // do stuff with element @@ -207,7 +207,7 @@ for (const auto& element : container) } ``` If you want to modify the elements, just drop the `const` keyword: -``` +```cpp for (auto& element : container) { // do stuff with element @@ -220,15 +220,15 @@ I recommend using this syntax whenever applicable as it's more expressive and le **A rule of thumb:** * If you do not need to know the iterator inside the `for` loop and only need to access/modify the elements, use a range-based `for` loop: - ``` + ```cpp for (const auto& element : container) ``` * If you need to use the iterator inside the loop body, use an iterator-based `for` loop: - ``` + ```cpp for (size_t it = 0; it < container.size(); it++) ``` or - ``` + ```cpp // if you need to modify the elements, use std::begin() and std::end() instead for (auto it = std::cbegin(container); it != std::cend(container); it++) ``` @@ -294,7 +294,7 @@ The [`auto` keyword](https://en.cppreference.com/w/cpp/language/auto) exists for `auto` loosely translates to "dear Mr. compiler, please substitute this word with the appropriate deduced type during compilation". For example, instead of writing the whole type of a `std::vector` iterator such as -``` +```cpp const std::vector cont = init_container(); for (std::vector::const_iterator it = std::cbegin(cont); it != std::cend(cont); it++) { @@ -302,7 +302,7 @@ for (std::vector::const_iterator it = std::cbegin(cont); it != std::cend( } ``` you can simplify this code without loosing expressivity to -``` +```cpp const std::vector cont = init_container(); for (auto it = std::cbegin(cont); it != std::cend(cont); it++) { diff --git a/docs/software/gdb.md b/docs/software/gdb.md index 01d2045d..d8bf9ca6 100644 --- a/docs/software/gdb.md +++ b/docs/software/gdb.md @@ -71,11 +71,11 @@ Typically, this is useful when you encounter a deadlock in your program or anoth To do this, first you need to know the PID (Program IDentifier) of the program that you want to attach GDB to. You can find that using `htop`, `pidof`, `pgrep` or any other command. For example, to find the PID of the process in which the `ControlManager` nodelet is running, you can use the command -``` +```bash pgrep -fia controlmanager ``` When you know the PID of the process you want to attach to, use the command -``` +```bash sudo gdb -p PID ``` to do that (it has to be done using superuser privileges - if a normal user could do this, that would be quite a security concern). @@ -87,23 +87,23 @@ To detach gdb from the program, use the `detach` command. If the deadlock ocurred when no debugger is attached to the program, you can attach to a running program using the method described above. When you have gdb prompt available, a good way to start debugging the deadlock is to list all threads using -``` +```bash info threads ``` and finding threads that are waiting on a mutex. These will typically list their current callframe function as `__lll_lock_wait ()` or something similar. A command to list the complete backtrace of all threads that you may also find useful is -``` +```bash thread apply all bt ``` When you find a thread that is waiting on a mutex, switch to its context using -``` +```bash thread ``` Then, you can print details of the mutex that the thread is waiting for (you may need to change the current callframe using the `up`, `down` or `frame` commands). Specifically, you're looking for the current owner of the mutex. Typically, you need to change the frame up until you hit the frame with the lock and then print the dereferenced mutex pointer using a command like -``` +```bash p *mutex ``` In the output, you should see several pieces of information, but most importantly the PID of the owning thread. @@ -114,23 +114,23 @@ This way, you should be able to find the cause of the deadlock. You can even debug a program that crashed and was not launched with an attached debugger. However, you have to make sure that coredumping is actually enabled by running -``` +```bash ulimit -a | grep core ``` If the configured core file size is zero, no coredump will be created. To enable coredump, run (*will change settings for the current terminal only!*) -``` +```bash ulimit -c unlimited ``` Now, when a program crashes, its core will be automatically saved a file named `core` in the current path (this is the default behaviour). If you need to differentiate between coredumps from different programs, enable coredumping with PID: -``` +```bash echo 1 | sudo tee /proc/sys/kernel/core_uses_pid ``` Now, the coredump will be named `core.`, so a new crash will not overwrite an old coredump. Finally, after your program crashes, you can debug it using simply the command -``` +```bash gdb ``` Note that for ROS nodelets, `` should typically be something like `~/workspace/devel/lib/libYourNodelet.so` and `` is by default `/var/lib/apport/coredump/core.....` in Ubuntu 20.04 when using `apport`. @@ -140,7 +140,7 @@ Other possible locations of the coredump are the current path and `~/.ros/ ``` which is used to pass the path to the custom config. diff --git a/docs/system/motor_thrust_model.md b/docs/system/motor_thrust_model.md index c683e898..9bd7f011 100644 --- a/docs/system/motor_thrust_model.md +++ b/docs/system/motor_thrust_model.md @@ -22,7 +22,7 @@ There are several ways of measuring the relationship between throttle and thrust We take our UAV with no additional payload, measure its mass and fly it manually. While it is hovering high enough above ground (to avoid ground effect), we read out its current throttle value. This can be done either through QGroundControl mavlink inspector, through Mavros or by checking the flight log on the SD card after the flight. Note that throttle is often called "thrust" in the mavlink messages, it is a value between 0 and 1. We then proceed to attach some payload to the UAV, measure the total UAV mass and fly it again. We then compile our test data into a yaml file, which looks like this: -``` +```bash # num_motors - How many motors were used in this test? num_motors: 4 @@ -43,7 +43,7 @@ throttle: [ This file can be then passed to a python script in the [mrs_uav_deployment](https://github.com/ctu-mrs/mrs_uav_deployment/tree/master/miscellaneous/motor_model) repository like this: -``` +```bash python3 thrust_curve.py example_uav.yaml ``` @@ -61,7 +61,7 @@ If the values looks appropriate, you can proceed. If not, check that your input The script will produce file named output.yaml, which looks like this: -``` +```bash motor_params: a: 0.282796 b: -0.180959 diff --git a/docs/system/trajectories.md b/docs/system/trajectories.md index 99c51432..9fbc3f17 100644 --- a/docs/system/trajectories.md +++ b/docs/system/trajectories.md @@ -32,7 +32,7 @@ nav_order: 4 The [`mrs-ctu/trajectory_loader`](https://github.com/ctu-mrs/trajectory_loader) package contains all information you need for loading a trajectory from a file: [documentation](https://github.com/ctu-mrs/trajectory_loader), [example trajectories](https://github.com/ctu-mrs/trajectory_loader/tree/master/sample_trajectories), and [launch files](https://github.com/ctu-mrs/trajectory_loader/tree/master/launch). It expects trajectory sampled with period of T = 0.2 s (can be modified in the message), in line-format `x,y,z,heading`, e.g.,: -``` +```bash 0.0,0.0,1.0,0.0 0.2,0.2,1.2,0.1 0.3,0.1,1.4,0.15