Git Product home page Git Product logo

radonulzer's Introduction

Radon Ulzer - Firmware for Zumo32U4

License Repo Status Release Build Status

A robot as fast as the famous pod racer driven by Anakin Skywalker with the powerful engines from Radon Ulzer. :-)

Several kind of exclusive applications are available:

  • Calib - Application used for motor speed calibration.
  • Convoy Leader - A line follower, providing information to the DroidControlShip in a convoy leader role.
  • Line Follower - Just a line follower, using a PID controller.
  • Remote Control - The robot is remote controlled by e.g. the DroidControlShip in a convoy follower role.
  • Sensor Fusion - The robot provides odometry and inertial data to the DroidControlShip, which calculates the sensor fusion based location information.

Table of content

The robot

The main target of the firmware is the Pololu Zumo32U4 robot (see https://www.pololu.com/category/129/zumo-robots-and-accessories) from Pololu.

deployment

The simulation

The simulation is based on the open source robot simulator Webots. The application and the services are equal to the target firmware. Only the HAL is different in the simulation.

Installation

  1. Install Webots.
  2. Setup for external controllers:
    1. Set environment variable WEBOTS_HOME to installation directory of Webots.
    2. Add to path:
      • Linux: ${WEBOTS_HOME}/lib/controller
      • Windows: %WEBOTS_HOME%\lib\controller
  3. Install the native compiler toolchain:
    • Linux: Install the gcc toolchain, depended on your distribution.
    • Windows
      • Install the MSYS2 toolchain.
      • Open MSYS2 shell.
        • Update package database: pacman -Sy pacman
        • Install GCC: pacman -Sy mingw-w64-ucrt-x86_64-gcc
  4. Ensure a current (>=3.9) Python3 version is installed on your machine.

The Webots library

To adapt the HAL to the simulation, some sourcecode files from Webots are necessary. Currently there is no Webots library in the platformio registry available. Therefore a local library is created during the build. Ensure that that Webots is already installed, before you try to build it!

The library creation is handled in the ./scripts/create_webots_library.py script and runs automatically after building for the WebotsSim environment.

Build

  1. Start VSCode.
  2. PlatformIO project tasks --> <APP-NAME> --> General --> Build
    Example for LineFollowerSim application:
    Example

For the simulation use only the applications with "Sim" as postfix, e.g. LineFollowerSim.

Preparation

The preparation is shown with the line follower application as example. It expects that the LineFollowerSim is already built.

  1. Start the Webots simulation.
  2. File --> Open World
  3. Select ./webots/worlds/LineFollowerTrack.wbt.
  4. The loaded world should now look like this: webots_world
  5. The simulation waits now for the external controller, like the RadonUlzer.

Run

There are 3 ways how to run now the application. Choose according to your needs.

Run without Webots launcher

This can be choosen in case the simulation waits just for one robot.

PlatformIO project tasks --> <APP-NAME> --> General --> Upload

Example for LineFollowerSim application:

Example

Run with Webots launcher

Choose this one in case the simulation waits for more than one robot. Adapt the robot name in the platformio.ini.

See (Single Simulation and Multiple Local Extern Robot Controllers)[https://cyberbotics.com/doc/guide/running-extern-robot-controllers?tab-os=windows#single-simulation-and-multiple-local-extern-robot-controllers] for details.

PlatformIO project tasks --> <APP-NAME> --> Custom --> WebotsLauncher

Example for LineFollowerSim application:

Example

Run via terminal

  1. Open a command line (shell) and change to the folder with the built executable in .pio/build/LineFollowerSim. This folder contains all necessary shared libraries as well.
  2. Start the executable.

Running the robot on track

  1. Click in the simulation on the display to focus the simulation.
  2. Now the keyboard keys a, b and c can be used to control the robot according to the implemented application logic.

Communicate with the DroidControlShip

The communication with the DroidControlShip goes via a Webots serial connection, which is disabled by default.

Use the -c flag to enable it with default channels (see webots_robot_serial_rx_channel and webots_robot_serial_tx_channel in platformio.ini). Note, this will disable the standard logging, because the serial communication uses the SerialMuxProt procotol for data interchange.

$ program.exe -c

For simplicity a Platformio project task was added, which enables the Webots serial connection as well.

Example

The target

Build and flash procedure

  1. PlatformIO project tasks --> <APP-NAME> --> General --> Build
    • For the target use only the applications with "Target" as postfix, e.g. LineFollowerTarget.
  2. Start the bootloader by triggering twice the reset button. The yellow led will start blinking for 10s. Note, after 10s the target will leave the bootloader!
  3. PlatformIO project tasks --> <APP-NAME> --> General --> Upload
  4. Ready.

Example for the LineFollowerTarget application:

Example

The Applications

Application Description Standalone DroidControlShop Required Webots World
Calib Application used for motor speed calibration. Yes No ./webots/worlds/LargeTrack.wbt ./webots/worlds/LineFollowerTrack.wbt
ConvoyLeader A line follower, providing information to the DroidControlShip in a convoy leader role. No Yes ./webots/worlds/zumo_with_com_system/PlatoonTrack.wbt
ConvoyFollower Convoy follower, providing information to the DroidControlShip to drive to its target. No Yes ./webots/worlds/zumo_with_com_system/PlatoonTrack.wbt
LineFollower Just a line follower, using a PID controller with differential drive and odometry. Yes No ./webots/worlds/ETrack.wbt ./webots/worlds/LargeTrack.wbt ./webots/worlds/LineFollowerTrack.wbt
LineFollowerSimple Just a simple line follower, using a PID controller. Yes No ./webots/worlds/ETrack.wbt ./webots/worlds/LargeTrack.wbt ./webots/worlds/LineFollowerTrack.wbt
RemoteControl The robot is remote controlled by e.g. the DroidControlShip in a convoy follower role. No Yes ./webots/world/zumo_with_com_system/*
SensorFusion The robot provides odometry and inertial data to the DroidControlShip, which calculates the sensor fusion based location information. No Yes ./webots/worlds/zumo_with_com_system/LineFollowerTrack.wbt
Test Only for testing purposes on native environment. Yes No N/A

Documentation

Used Libraries

Library Description License
ArduinoNative The Arduino for native environment. MIT
SerialMuxProt Multiplexing Communication Protocol MIT
ZumoHALATmega32u4 C++ HAL for ATmega32u4 on the Pololu Zumo32u4 MIT
ZumoHALInterfaces Abstract C++ HAL interfaces MIT
ZumoHALWebots C++ HAL for Webots simulation of the Pololu Zumo32u4 MIT

Issues, Ideas And Bugs

If you have further ideas or you found some bugs, great! Create a issue or if you are able and willing to fix it by yourself, clone the repository and create a pull request.

License

The whole source code is published under the MIT license. Consider the different licenses of the used third party libraries too!

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions.

radonulzer's People

Contributors

blueandi avatar eble108 avatar gabryelreyes avatar jkerpe avatar ludubies avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

radonulzer's Issues

Change odometry orientation range

The standard convention typically used in ROS (and ROS2) for Euler angles is:

  • Roll: [-π, π] (or -180° to 180°)
  • Pitch: [-π/2, π/2] (or -90° to 90°)
  • Yaw: [-π, π] (or -180° to 180°)

In many conventions used in robotics and computer graphics, including ROS (Robot Operating System), yaw angle rotation is typically defined as positive when turning counterclockwise and negative when turning clockwise.

This convention aligns with the right-hand rule, where positive rotation is in the direction of your curled fingers when your thumb points in the positive axis direction (in this case, the positive Z-axis).

So, to clarify:

Counterclockwise rotation around the Z-axis (yaw) is positive.
Clockwise rotation around the Z-axis (yaw) is negative.

https://www.ros.org/reps/rep-0103.html#rotation-representation

Launch Script

For complex simulations with several robots and middleware (in this case, Convoy with Leader and Follower robots), it is necessary the implementation of a launch script. This program will have the mission of spawning each program's instance with the correct arguments and in the correct order.

The preliminary order that the script shall follow is:

  1. Build Leader's RadonUlzer firmware
  2. Build Leader's DroidControl firmware
  3. Build Follower's RadonUlzer firmware
  4. Build Follower's DroidControl firmware
  5. Open correct Webots scenario
  6. Define flags, names, ports, arguments, and running order for each robot instance
  7. Run respective programs, making sure the correct connections/ports are established
  8. Success...?

Points of discussion:

  • Where should this script be located? (It must has access to several Repos and programs)
  • Bash, Python, or other scripting language?

Logging

Logging tags are not always used. This is a warning in the compilation process, which is then treated as an error.
Proposed solution is to define the tag only when logging is enabled(pseudocode):

#ifdef (LOG_INFO_ENABLE || LOG_DEBUG_ENABLE)
static const char* TAG = "Odo";
#endif

Client cannot subscribe to multiple channels at the same time

The Client cannot subscribe to more than one channel without a minimum of 2 calls to the process() method in between the calls in order to process the incoming SCRB_RSP. The following snippet will fail to do what is expected:

void setup()
{
    gYapClient.subscribeToChannel("TEST1", CB1);
    gYapClient.subscribeToChannel("TEST2", CB2);
}

This client would only try to subscribe to TEST2, as the m_pendingSuscribeChannel member would be overwriten on the second call to the method.

Currently I do not have a clean solution for this issue. (Should this be converted to a Github Issue?)

The first idea to come to mind is to use an array to hold a determined number of pending channels to suscribe to. However this raises other problems such as memory usage and how to track which channels are suscribed and which are still pending, and when/where does the suscribing process takes places.

Originally posted by @gabryelreyes in #2 (comment)

Keep in mind that the response may never come.

Set angular speed

Using the following call:

/* int32_t turtleSpeedData->angular = 1500  [mrad/s] */
int16_t angularSpeed = static_cast<int16_t>(turtleSpeedData->angular);
diffDrive.setAngularSpeed(angularSpeed);

This results in a counter-clockwise rotation of aroung 270° while the expected behavior is the rotation of the Zumo clockwise around 90° in one second.

Issue has been tracked to DifferentialDrive::calculateLinearSpeedLeftRight where the result of angularSpeed32 * wheelBase32 exceeds the maximum value of int16_t and wraps over to its negative domain.

Odometry random incrementation.

After running some basic tests I've encountered an issue when calling odometry for longer periods of time.

The test involved the robot endlessly running through the course while periodically outputting X and Y coordinates. It has been done in order to map out key points/areas of the original track for other implementations:
grafik

The following values have been found with AND without clearing position after crossing the start/end line:
grafik

Conclusions:

  • Y values are somewhat consistent while X isn't at all
  • clearing position at the start/end line helps

Calibration Application

Should save the calibration values of the MotorCalibrationState to EEPROM.
This allows the removal of the state from all other applications.
Applications can then read the value from the EEPROM and directly use it.

Improve memcpy

Improve this later to get rid of the memcpy too. Because we send synchronous and the stream will copy the data again.

Originally posted by @BlueAndi in #2 (comment)

Executable packaging

In order to prevent missing files and path problems, it is proposed to pack all relevant files into an output folder. This ensures that the executable has all the relevant files in its local path.

Relevant files:

  • DLLs
  • Sounds files
  • settings.json

Improve Documentation

  • Role of Arduino and ArduinoNative in the architecture
  • PlatformIO Tasks build an Environment

Missing Keywords

The IMU components in HALSim and HALTarget are missing the final keyword on their inherited methods.

YAP Server-Client Dependency

The max. number of channels configured for the Client must be equal or greater than the max. channels of the Server. Otherwise, the subscription to a channel may fail due to the size of the m_dataChannels Array

Differ between YAP and LOG information

General question: How do we differ between YAP and LOG information?

In the simulation this has been solved by routing the print() methods to the console, and the write() method to the SocketServer; which may not be ideal in the architecture, but allows for nice debugging. In the target this is not possible, as both print and write are routed to the Serial interface.

Ideally the LOG information would be sent on its own YAP Data channel, meaning that the Logging Module should be able to write to the YAP Server somehow (only the App knows the YAP Server Instance, so it is not an ideal solution). And maybe only the INFO level Logs, not the DEBUG logs.

Other solution is turning Logs completely off on the target, and any information to be transmitted must be available for the App to read and re-route.

Originally posted by @gabryelreyes in #2 (comment)

DifferentialDrive acceleration ramp

In order to prevent sudden high accelerations, which may cause errors in some sensors, a ramp for progressive acceleration is required. It shall be processed before the DiffDrive PID controller

SpeedoMeter wrongly resets left motor when right motor direction changes.

The speedometer wrongly reseted the speed of the left motor when it detects a direction change of the "right" one.
Most likely a copy paste error as the involved variable names only differs by left/right suffix.

in Speedometer.cpp @ 97

     if (currentDrivingDirection != m_lastDirectionRight)   // <-- Right motor changed direction
       {
           resetLeft = true;   // <--ERROR Left motor is wrongly reset. Should be "resetRight = true;"
       }

Update Webots to R2023b

New version allows for use of Launcher Script for external controllers.

May bring breaking changes to the world and PROTOs

App generation script

Make a script that generates the boilerplate files and updates the configuration to include the application

Improve Supervisor

Fix and improve the Supervisor controller.
Should be able to remove the PyLint suppressions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.