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 12 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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +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

* [The robot](#the-robot)
Expand Down Expand Up @@ -158,6 +158,8 @@ 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 |
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
| Test | Only for testing purposes on native environment. | Yes | No | N/A |

# Documentation
Expand Down
36 changes: 18 additions & 18 deletions lib/APPReinforcementLearning/src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*******************************************************************************/
/**
* @brief LineFollower application with Reinforcement Learning
* @author Akram Bziouech
* @author Akram Bziouech
*/

/******************************************************************************
Expand Down Expand Up @@ -55,7 +55,6 @@
* Types and classes
*****************************************************************************/


/******************************************************************************
* Prototypes
*****************************************************************************/
Expand All @@ -75,15 +74,15 @@ void App::setup()
{
Serial.begin(SERIAL_BAUDRATE);
/* Initialize HAL */
Board::getInstance().init();
Board::getInstance().init();
Logging::disable();

if (false == setupSerialMuxProt())
{
ErrorState::getInstance().setErrorMsg("SMP=0");
m_systemStateMachine.setState(&ErrorState::getInstance());
}
else
else
{
m_statusTimer.start(SEND_STATUS_TIMER_INTERVAL);
m_sendLineSensorsDataInterval.start(SEND_LINE_SENSORS_DATA_PERIOD);
Expand Down Expand Up @@ -113,8 +112,9 @@ void App::loop()

m_controlInterval.restart();
}

if ((true == m_statusTimer.isTimeout()) && (true == m_smpServer.isSynced())&& (&DrivingState::getInstance() == m_systemStateMachine.getState()))

if ((true == m_statusTimer.isTimeout()) && (true == m_smpServer.isSynced()) &&
(&DrivingState::getInstance() == m_systemStateMachine.getState()))
{
Status payload = {SMPChannelPayload::Status::NOT_DONE};

Expand All @@ -128,9 +128,10 @@ void App::loop()

m_statusTimer.restart();
}

/* Send periodically line sensor data. */
if (true == m_sendLineSensorsDataInterval.isTimeout() && (&DrivingState::getInstance() == m_systemStateMachine.getState()) )
if (true == m_sendLineSensorsDataInterval.isTimeout() &&
(&DrivingState::getInstance() == m_systemStateMachine.getState()))
{
sendLineSensorsData();

Expand All @@ -139,12 +140,13 @@ void App::loop()

/* Send Mode selected to The Supervisor. */
if (&ReadyState::getInstance() == m_systemStateMachine.getState() && (!m_modeSelectionSent))
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
{
{
uint8_t mode_options = ReadyState::getInstance().setSelectedMode();

if(mode_options > 0)
if (mode_options > 0)
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
{
SMPChannelPayload::Mode payload = (mode_options == 1) ? SMPChannelPayload::Mode::DRIVING_MODE : SMPChannelPayload::Mode::TRAINING_MODE;
SMPChannelPayload::Mode payload =
(mode_options == 1) ? SMPChannelPayload::Mode::DRIVING_MODE : SMPChannelPayload::Mode::TRAINING_MODE;
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved

/* Ignoring return value, as error handling is not available. */
(void)m_smpServer.sendData(m_serialMuxProtChannelIdMode, &payload, sizeof(payload));
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -153,7 +155,6 @@ void App::loop()
}
}


m_smpServer.process(millis());

m_systemStateMachine.process();
Expand Down Expand Up @@ -215,16 +216,15 @@ bool App::setupSerialMuxProt()

/* Channel subscription. */
m_smpServer.subscribeToChannel(SPEED_SETPOINT_CHANNEL_NAME, App_motorSpeedSetpointsChannelCallback);
m_smpServer.subscribeToChannel(COMMAND_CHANNEL_NAME,App_cmdChannelCallback);
m_smpServer.subscribeToChannel(COMMAND_CHANNEL_NAME, App_cmdChannelCallback);

/* Channel creation. */
m_serialMuxProtChannelIdStatus = m_smpServer.createChannel(STATUS_CHANNEL_NAME, STATUS_CHANNEL_DLC);
m_serialMuxProtChannelIdLineSensors =
m_smpServer.createChannel(LINE_SENSOR_CHANNEL_NAME, LINE_SENSOR_CHANNEL_DLC);
m_serialMuxProtChannelIdMode = m_smpServer.createChannel(MODE_CHANNEL_NAME, MODE_CHANNEL_DLC);
m_serialMuxProtChannelIdStatus = m_smpServer.createChannel(STATUS_CHANNEL_NAME, STATUS_CHANNEL_DLC);
m_serialMuxProtChannelIdLineSensors = m_smpServer.createChannel(LINE_SENSOR_CHANNEL_NAME, LINE_SENSOR_CHANNEL_DLC);
m_serialMuxProtChannelIdMode = m_smpServer.createChannel(MODE_CHANNEL_NAME, MODE_CHANNEL_DLC);

/* Channels succesfully created? */
if ((0U != m_serialMuxProtChannelIdStatus) && (0U != m_serialMuxProtChannelIdLineSensors) &&
if ((0U != m_serialMuxProtChannelIdStatus) && (0U != m_serialMuxProtChannelIdLineSensors) &&
(0U != m_serialMuxProtChannelIdMode))
{
isSuccessful = true;
Expand Down
14 changes: 7 additions & 7 deletions lib/APPReinforcementLearning/src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@
* Types and Classes
*****************************************************************************/

/** The line follower application. */
/** The line follower with reinforcement learning application. */
class App
{
public:
/**
* Construct the line follower application.
* Construct the line follower with reinforcement learning application.
*/
App() :
App() :
m_systemStateMachine(),
m_controlInterval(),
m_serialMuxProtChannelIdStatus(0U),
Expand All @@ -78,7 +78,7 @@ class App
}

/**
* Destroy the line follower application.
* Destroy the line follower with reinforcement learning application.
*/
~App()
{
Expand Down Expand Up @@ -138,16 +138,16 @@ class App
/** SerialMuxProt Server Instance. */
SMPServer m_smpServer;

/* Ensue that the mode is only sent once*/
bool m_modeSelectionSent;
/** Ensue that the mode is only sent once */
bool m_modeSelectionSent;

/**
* Setup the SerialMuxProt channels.
*
* @return If successful returns true, otherwise false.
*/
bool setupSerialMuxProt();

/**
* Send line sensors data via SerialMuxProt.
*/
Expand Down
2 changes: 1 addition & 1 deletion lib/APPReinforcementLearning/src/DrivingState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*******************************************************************************/
/**
* @brief Driving state
* @author Akram Bziouech
* @author Akram Bziouech
*/

/******************************************************************************
Expand Down
6 changes: 3 additions & 3 deletions lib/APPReinforcementLearning/src/DrivingState.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*******************************************************************************/
/**
* @brief Driving state
* @author @author Akram Bziouech
* @author Akram Bziouech
*
* @addtogroup Application
*
Expand Down Expand Up @@ -102,14 +102,14 @@ class DrivingState : public IState
* Check the abort conditions while driving the challenge.
*
* @return If abort is required, it will return true otherwise false.
*/
*/
bool isAbortRequired();

protected:
private:
/** Observation duration in ms. This is the max. time within the robot must be finished its drive. */
static const uint32_t OBSERVATION_DURATION = 3000000;
gabryelreyes marked this conversation as resolved.
Show resolved Hide resolved

SimpleTimer m_observationTimer; /**< Observation timer to observe the max. time per challenge. */

/**
Expand Down
7 changes: 4 additions & 3 deletions lib/APPReinforcementLearning/src/ErrorState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@

void ErrorState::entry()
{
IDisplay& display = Board::getInstance().getDisplay();

IBoard& board = Board::getInstance();
IDisplay& display = board.getDisplay();

/* Stop the motors in any case! */
DifferentialDrive::getInstance().disable();

display.clear();
Expand All @@ -81,7 +83,6 @@ void ErrorState::entry()
{
display.print(m_errorMsg);
}

}

void ErrorState::process(StateMachine& sm)
Expand Down
11 changes: 4 additions & 7 deletions lib/APPReinforcementLearning/src/IBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
/**
* @brief Board interface, which abstracts the physical board
* @author Andreas Merkle <[email protected]>
*
*
* @addtogroup HALInterfaces
*
* @{
Expand Down Expand Up @@ -71,7 +71,6 @@
class IBoard
{
public:

/**
* Destroys the board interface.
*/
Expand Down Expand Up @@ -121,7 +120,7 @@ class IBoard

/**
* Get encoders driver.
*
*
* @return Encoders driver.
*/
virtual IEncoders& getEncoders() = 0;
Expand Down Expand Up @@ -163,7 +162,7 @@ class IBoard

/**
* Get the settings.
*
*
* @return Settings
*/
virtual ISettings& getSettings() = 0;
Expand All @@ -183,9 +182,8 @@ class IBoard
* Process actuators and sensors.
*/
virtual void process() = 0;

protected:

protected:
/**
* Constructs the board interface.
*/
Expand All @@ -194,7 +192,6 @@ class IBoard
}

private:

};

/******************************************************************************
Expand Down
35 changes: 17 additions & 18 deletions lib/APPReinforcementLearning/src/ReadyState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*******************************************************************************/
/**
* @brief Ready state
* @author Akram Bziouech
* @author Akram Bziouech
*/

/******************************************************************************
Expand Down Expand Up @@ -72,7 +72,7 @@ const uint8_t ReadyState::SENSOR_ID_MOST_RIGHT = Board::getInstance().getLineSen

void ReadyState::entry()
{
IDisplay& display = Board::getInstance().getDisplay();
IDisplay& display = Board::getInstance().getDisplay();
display.clear();
display.print("A: TMD");
display.gotoXY(0, 1);
Expand All @@ -82,17 +82,16 @@ void ReadyState::entry()
diffDrive.setLinearSpeed(0, 0);

if (true == m_isLapTimeAvailable)
{
{
display.gotoXY(0, 2);
display.print(m_lapTime);
display.print("ms");
}
m_modeTimeoutTimer.start(mode_selected_period);
m_mode = IDLE;
m_mode = IDLE;
m_isLastStartStopLineDetected = false;
m_isButtonAPressed = false;
m_isButtonBPressed = false;

m_isButtonAPressed = false;
m_isButtonBPressed = false;
}

void ReadyState::process(StateMachine& sm)
Expand All @@ -108,12 +107,12 @@ void ReadyState::process(StateMachine& sm)
/* Shall the driving mode be released? */
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
m_mode = DRIVING_MODE;
m_mode = DRIVING_MODE;
}
/* Shall the Training mode be released? */
else if (true == Util::isButtonTriggered(buttonB, m_isButtonBPressed))
{
m_mode = TRAINING_MODE;
{
m_mode = TRAINING_MODE;
}
else if (true == m_modeTimeoutTimer.isTimeout() && (m_mode == IDLE))
akrambzeo marked this conversation as resolved.
Show resolved Hide resolved
{
Expand Down Expand Up @@ -163,24 +162,24 @@ uint8_t ReadyState::setSelectedMode()
* Private Methods
*****************************************************************************/

ReadyState::ReadyState() :
m_isLapTimeAvailable(false),
ReadyState::ReadyState() :
m_isLapTimeAvailable(false),
m_isButtonAPressed(false),
m_isButtonBPressed(false),
m_modeTimeoutTimer(),
m_lapTime(0),
m_isLastStartStopLineDetected(false),
m_mode(IDLE)
m_mode(IDLE)
{
}

/**Drive forward until START LINE is crossed */
void ReadyState :: DriveUntilStartLineisCrossed()
void ReadyState ::DriveUntilStartLineisCrossed()
{
DifferentialDrive& diffDrive = DifferentialDrive::getInstance();
int16_t top_speed = 2000; /* Set a top speed of 2000 */
int16_t leftMotor = top_speed / 2U; /* Drive at half speed */
int16_t rightMotor = top_speed / 2U; /* Drive at half speed */
DifferentialDrive& diffDrive = DifferentialDrive::getInstance();
int16_t top_speed = 2000; /* Set a top speed of 2000 */
int16_t leftMotor = top_speed / 2U; /* Drive at half speed */
int16_t rightMotor = top_speed / 2U; /* Drive at half speed */
diffDrive.setLinearSpeed(leftMotor, rightMotor);
}

Expand Down
Loading
Loading