Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of data exchange mechanisms between robot and supervisor using Serial Webots drivers #138

Merged
merged 62 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
41df488
Diagramms RL
Jun 5, 2024
e4f8cc2
Added Serial Webots for Python
Jul 2, 2024
43f462e
Fix issues in functions of Serial_webots class
Jul 9, 2024
ef945a1
Serial Webots added to Supervisor
Jul 9, 2024
6131885
Copied error state from LineFollower APP without logging
Jul 9, 2024
f627421
Supervisor supports now serial communication over emitter/receiver.
Jul 11, 2024
0f651cc
Added SerialMuxChannels
Jul 12, 2024
0071bc4
Aded Reinforcement Learning Application, Data exchange between superv…
Jul 15, 2024
f0f254d
HALSIM added to ReinforcementLearning APP
Jul 16, 2024
602d811
Update Supervisor to receive Line Sensors Values and Selected Mode
Jul 16, 2024
fc8a048
Update import to struct and clean up print comment
Jul 16, 2024
432e90c
Update import to Struct and Clean up print Comment
Jul 16, 2024
9a724bd
Deleted the isNoLineDetected function
Jul 17, 2024
f8a7eab
Updated the Ready state: Robot now drives until the Start-Stop line i…
Jul 17, 2024
7bc2021
Updated supervisor logic: Supervisor now decides to stop motors if no…
Jul 17, 2024
1007013
Added serial RX/TX channels configuration for communication with the …
Jul 17, 2024
bac84b6
Removed duplicate declaration of Robot_Name in Supervisor.
Jul 17, 2024
80d9a5f
Created a new communication channel to handle the reinitialization of…
Jul 18, 2024
c3c6530
Remove unnecessary file
akrambzeo Jul 19, 2024
ac350e0
Added RL-LineFollower World
Jul 19, 2024
2d8fc1a
Merge branch 'base/RL' into feature/RL
akrambzeo Jul 19, 2024
e5ec72a
Create a separate supervisor for APP Reinforcement Learning, the orig…
Jul 23, 2024
86f9b2c
Remove wrong line from the code
Jul 23, 2024
745f6c2
Delet unused files
Jul 26, 2024
2afc924
Move cpp and header files to src folder / replace STATUS channel to r…
Jul 26, 2024
12cdd39
Use updated SerialMuxProt and replace status channel with CMS channe…
Jul 26, 2024
9e8a3cf
Add new track and create RL linefollower world
Jul 26, 2024
71f3fb0
Import stream into SerialWebots and rename variables
Jul 26, 2024
afd6b14
Rename variables and customize code formatting in the Supervisor class.
Jul 26, 2024
afbc8b0
Rename Track name to GaplessTrack
Jul 26, 2024
6e0dd8f
Move the cpp and header board file to the src file and delete the cpp…
Jul 26, 2024
410582d
Re-add missing license to cpp und Header APPReinforcementLearning file
Jul 26, 2024
3295a7e
Temporary renaming from Supervisor.py to temp.py
Jul 29, 2024
68d91b2
Adjustments to the supervisor with the latest update and renaming files
Jul 29, 2024
4dcb5e7
Fixed line endings of the UML diagrams
gabryelreyes Jul 29, 2024
a1de1fe
Added missing final newline
gabryelreyes Jul 29, 2024
f69babc
Keep list alphabetical
Jul 29, 2024
daf8e1e
Merge branch 'base/RL' into feature/RL
Jul 29, 2024
8b05ea9
Create Doxygen documentation via CI
gabryelreyes Jul 29, 2024
054870f
Refactored code: added and updated comments, renamed variable, remove…
Jul 29, 2024
81a0bcf
Merged updates from origin/feature/RL into feature/RL
Jul 29, 2024
f589e5c
Removing the training status from the application architecture and co…
Jul 29, 2024
c8c3094
Adding comments
Jul 29, 2024
a2c2976
Delete extra author tag and add comments
Jul 30, 2024
9f35d2c
Add SerialMuxProt as Python dependency
gabryelreyes Jul 30, 2024
cae9002
Rename RL_Supervisor.py to rl_supervisor.py in RL_Supervisor folder
Jul 30, 2024
089e186
Merge branch 'feature/RL' of https://github.com/BlueAndi/RadonUlzer i…
Jul 30, 2024
3771ed1
Correct code formatting and indentation
Jul 30, 2024
474dd12
Add the ReinforcementLearning application to the README.md.
Jul 30, 2024
27fb5a6
Rename MotorSpeedCalibrationstate to MotorSpeedCalibrationState
Jul 30, 2024
65b3c6d
Rename RL_Supervisor.py to rl_supervisor.py and refactor to class-bas…
Jul 30, 2024
e136bf7
implement new class-based architecture
Jul 30, 2024
607656e
Update RL_LineFollower world with renamed rl_supervisor
Jul 30, 2024
4b99c27
Add comments and fix formatting
Jul 30, 2024
cdba264
Rename Serial_webots.py to serial_webots.py
Jul 30, 2024
40ec7f4
Rename Serial_webots import to serial_webots in rl_supervisor
Jul 30, 2024
3154b31
Add the license to rl_supervisor and fix the license owner in serial_…
Jul 30, 2024
71a6217
Fix table formatting and add missing newline in README
Jul 30, 2024
32f576e
Added missing line, added comment, and renamed function name to Ready…
Jul 30, 2024
6fff947
Add Section separators in rl_supervisor
Jul 30, 2024
579d460
Removed unnecessary includes
Jul 30, 2024
d47c8cf
Renamed setSelectedMode to getSelectedMode in Ready state, Adjusted Y…
Jul 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ jobs:
needs: intro
strategy:
matrix:
environment: ["CalibTarget", "ConvoyFollowerTarget", "ConvoyLeaderTarget", "LineFollowerTarget", "LineFollowerSimpleTarget", "RemoteControlTarget", "SensorFusionTarget", "CalibSim", "ConvoyFollowerSim", "ConvoyLeaderSim", "LineFollowerSim", "LineFollowerSimpleSim", "RemoteControlSim", "SensorFusionSim"]
environment: ["CalibTarget", "ConvoyFollowerTarget", "ConvoyLeaderTarget", "LineFollowerTarget", "LineFollowerSimpleTarget", "RemoteControlTarget", "SensorFusionTarget", "CalibSim", "ConvoyFollowerSim", "ConvoyLeaderSim", "LineFollowerSim", "LineFollowerSimpleSim", "ReinforcementLearningSim", "RemoteControlSim", "SensorFusionSim"]

steps:
- name: Checkout repository
Expand Down Expand Up @@ -212,7 +212,7 @@ jobs:

- name: Install dependencies
run: |
pip install pylint
pip install pylint "git+https://github.com/gabryelreyes/SerialMuxProt.git#egg=SerialMuxProt&subdirectory=python/SerialMuxProt"

- name: Analysing the code with pylint
run: |
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Several kind of exclusive applications are available:
* Line Follower - Just a line follower, using a PID controller.
* Remote Control - The robot is remote controlled by e.g. the [DroidControlShip](https://github.com/BlueAndi/DroidControlShip) in a convoy follower role.
* Sensor Fusion - The robot provides odometry and inertial data to the [DroidControlShip](https://github.com/BlueAndi/DroidControlShip), which calculates the sensor fusion based location information.
* Line Follower with Reinforcement Learning - A line follower with reinforcement learning uses a learning agent that uses rewards and punishments to steer optimally in order to follow a line autonomously.
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved

## Table of content

Expand Down Expand Up @@ -158,6 +159,7 @@ Example for the **LineFollowerTarget** application:
| 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](https://github.com/BlueAndi/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](https://github.com/BlueAndi/DroidControlShip), which calculates the sensor fusion based location information. | No | Yes | ./webots/worlds/zumo_with_com_system/LineFollowerTrack.wbt |
| ReinforcementLearning | A line follower with reinforcement learning uses a learning agent that uses rewards and punishments to steer optimally in order to follow a line autonomously. | Yes | No | ./webots/worlds/RL_LineFollower.wbt |
| Test | Only for testing purposes on native environment. | Yes | No | N/A |

# Documentation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
@startuml

title Application

package "Application" as appLayer {

class App <<main>> {
+ setup() : void
+ loop() : void
}

note left of App
The program entry point.
end note

class StateMachine <<control>> {
+ setState(state : IState*) : void
+ getState() : IState*
+ process() : void
}

note left of StateMachine
The state machine executes always one
state exclusive. It is responsible to
enter/leave/process a state.
end note

interface IState {
+ {abstract} entry() : void
+ {abstract} process(sm : StateMachine&) : void
+ {abstract} exit() : void
}

note left of IState
Defines the abstract state interface,
which forces every inherited class
to realize it.
end note

class StartupState <<control>>
class MotorSpeedCalibrationState <<control>>
class LineSensorsCalibrationState <<control>>
class ErrorState <<control>>
class DrivingState <<control>>
class ReadyState <<control>>

note bottom of StartupState
The system starts up and shows
the Application name on the display.
end note

note bottom of MotorSpeedCalibrationState
The robot drives with full speed forward
and with full speed backwards to determine
the max speed in steps/s. The slowest
motor is considered!
end note

note bottom of LineSensorsCalibrationState
The robot turns several times the
line sensors over the track for
calibration.
end note

note bottom of ErrorState
Error information is shown on display.
Confirmation from operator is requested.
end note

note bottom of DrivingState
The robot follows the line.
end note

note bottom of ReadyState
The robot is stopped and waits for
operator input.
end note
}

note top of appLayer
Hint: See the application state behaviour
in the corresponding state diagram.
end note

App *--> StateMachine
StateMachine o--> "0..1" IState

IState <|.. StartupState: <<realize>>
IState <|.... MotorSpeedCalibrationState: <<realize>>
IState <|.. LineSensorsCalibrationState: <<realize>>
IState <|.... ErrorState: <<realize>>
IState <|.. ReadyState: <<realize>>
IState <|.... DrivingState: <<realize>>


@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@startuml

title Driving State

package "Application" as appLayer {

class DrivingState <<control>> {
+ {static} getInstance() : DrivingState
+ entry() : void
+ process(sm : StateMachine&) : void
+ exit() : void
}

class ReadyState <<control>>

DrivingState .r.> ReadyState: <<use>>
}

package "Service" as serviceLayer {

class SimpleTimer <<service>> {
+ start(duration : uint32_t) : void
+ restart() : void
+ stop() : void
+ isTimeout() : bool
}
class DifferentialDrive <<service>>
}

package "HAL" as hal {

package "Interfaces" as halInterfaces {
interface IDisplay {
+ {abstract} clear() : void
+ {abstract} gotoXY(xCoord : uint8_t, yCoord : uint8_t) : void
+ {abstract} print(str : const String&) : size_t
+ {abstract} print(str : const char[]) : size_t
+ {abstract} print(value : uint8_t) : size_t
+ {abstract} print(value : uint16_t) : size_t
+ {abstract} print(value : uint32_t) : size_t
+ {abstract} print(value : int8_t) : size_t
+ {abstract} print(value : int16_t) : size_t
+ {abstract} print(value : int32_t) : size_t
}

interface ILineSensors {
+ {abstract} init() : void
+ {abstract} calibrate() : void
+ {abstract} readLine() : int16_t
+ {abstract} getSensorValues() : const uint16_t*
+ {abstract} isCalibrationSuccessful() : bool
+ {abstract} getCalibErrorInfo() const : uint8_t
+ {abstract} getNumLineSensors() const : uint8_t
+ {abstract} getSensorValueMax() const : uint16_t
}

interface ILed {
+ {abstract} enable(enableIt : bool) : void
}

interface IButton {
+ {abstract} isPressed() : bool
+ {abstract} waitForRelease() : void
}

}

class Board << namespace >> {
+ getDisplay() : IDisplay&
+ getLineSensors() : ILineSensors&
+ getLedYellow() : ILed&
+ getButtonA() : IButton&
}
class WebotsSerialDrv {
+ setRxChannel(channelId: int32_t) : void
+ setTxChannel(channelId: int32_t ) : void
+ print(str: const char[]) : void
+ print(value: uint8_t ) : void
+ print(value: uint16_t ) : void
+ print(value: uint32_t ) : void
+ print(value: int8_t ) : void
+ print(value: int16_t ) : void
+ print(value: int32_t ) : void
+ println(str: const char[]) : void
+ println(value: uint8_t ) : void
+ println(value: uint16_t ) : void
+ println(value: uint32_t ) : void
+ println(value: int8_t ) : void
+ println(value: int16_t ) : void
+ println(value: int32_t ) : void
+ write( buffer: const uint8_t*, length: size_t ) : size_t
+ readBytes( buffer: uint8_t*, length: size_t ) : size_t
}
}

DrivingState *-> SimpleTimer
DrivingState ..> DifferentialDrive: <<use>>
DrivingState ...> IDisplay: <<use>>
DrivingState ...> ILineSensors: <<use>>
DrivingState ...> ILed: <<use>>
DrivingState ...> Board: <<use>>
DrivingState ...>WebotsSerialDrv: <<use>>
DrivingState ...>IButton: <<use>>
@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@startuml

title Error State

package "Application" as appLayer {

class ErrorState <<control>> {
+ {static} getInstance() : ErrorState
+ entry() : void
+ process(sm : StateMachine&) : void
+ exit() : void
+ setErrorMsg(msg : const String&) : void
}

class StartupState <<control>>

ErrorState .r.> StartupState: <<use>>
}

package "HAL" as hal {

package "Interfaces" as halInterfaces {
interface IDisplay {
+ {abstract} clear() : void
+ {abstract} gotoXY(xCoord : uint8_t, yCoord : uint8_t) : void
+ {abstract} print(str : const String&) : size_t
+ {abstract} print(str : const char[]) : size_t
+ {abstract} print(value : uint8_t) : size_t
+ {abstract} print(value : uint16_t) : size_t
+ {abstract} print(value : uint32_t) : size_t
+ {abstract} print(value : int8_t) : size_t
+ {abstract} print(value : int16_t) : size_t
+ {abstract} print(value : int32_t) : size_t
}

interface IButton {
+ {abstract} isPressed() : bool
+ {abstract} waitForRelease() : void
}
}

class Board << namespace >> {
+ getDisplay() : IDisplay&
+ getButtonA() : IButton&
}
}

ErrorState ..> Board: <<use>>
ErrorState ..> IDisplay: <<use>>
ErrorState ..> IButton: <<use>>

@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
@startuml

title Line Sensors Calibration State

package "Application" as appLayer {

class LineSensorsCalibrationState <<control>> {
+ {static} getInstance() : LineSensorsCalibrationState
+ entry() : void
+ process(sm : StateMachine&) : void
+ exit() : void
}

class ReadyState <<control>>
class ErrorState <<control>>

LineSensorsCalibrationState ..> ReadyState: <<use>>
LineSensorsCalibrationState ..> ErrorState: <<use>>
}

package "Service" as serviceLayer {

class SimpleTimer <<service>>
class RelativeEncoder <<service>>
class DifferentialDrive <<service>><<singleton>>
class Speedometer <<service>><<singleton>>

DifferentialDrive ..> Speedometer: <<use>>
}

package "HAL" as hal {

package "Interfaces" as halInterfaces {
interface IDisplay {
+ {abstract} clear() : void
+ {abstract} gotoXY(xCoord : uint8_t, yCoord : uint8_t) : void
+ {abstract} print(str : const String&) : size_t
+ {abstract} print(str : const char[]) : size_t
+ {abstract} print(value : uint8_t) : size_t
+ {abstract} print(value : uint16_t) : size_t
+ {abstract} print(value : uint32_t) : size_t
+ {abstract} print(value : int8_t) : size_t
+ {abstract} print(value : int16_t) : size_t
+ {abstract} print(value : int32_t) : size_t
}

interface IMotors {
+ {abstract} setSpeeds(leftSpeed : int16_t, rightSpeed : int16_t) : void
+ {abstract} getMaxSpeed() : int16_t
}

interface ILineSensors {
+ {abstract} init() : void
+ {abstract} calibrate() : void
+ {abstract} readLine() : int16_t
+ {abstract} getSensorValues() : const uint16_t*
+ {abstract} getNumLineSensors() const : uint8_t
+ {abstract} getSensorValueMax() const : uint16_t
}

interface IEncoders {
+ {abstract} getCountsLeft() : int16_t
+ {abstract} getCountsRight() : int16_t
+ {abstract} getCountsAndResetLeft() : int16_t
+ {abstract} getCountsAndResetRight() : int16_t
+ {abstract} getResolution() const : uint16_t
}
}

class Board << namespace >> {
+ getDisplay() : IDisplay&
+ getMotors() : IMotors&
+ getLineSensors() : ILineSensors&
}
}

appLayer -[hidden]-- serviceLayer
serviceLayer -[hidden]-- hal

LineSensorsCalibrationState ....> IDisplay: <<use>>
LineSensorsCalibrationState ....> ILineSensors: <<use>>
LineSensorsCalibrationState ....> Board: <<use>>
LineSensorsCalibrationState *--> SimpleTimer
LineSensorsCalibrationState *--> RelativeEncoder
LineSensorsCalibrationState ...> DifferentialDrive: <<use>>

DifferentialDrive ...> IMotors: <<use>>
Speedometer ..> IEncoders: <<use>>
Speedometer ..> IMotors: <<use>>

@enduml
Loading