Skip to content

Commit

Permalink
Merge pull request #129 from BlueAndi/feature/LineFollowerSimple
Browse files Browse the repository at this point in the history
Feature/line follower simple
  • Loading branch information
BlueAndi authored Jul 1, 2024
2 parents 906d3d8 + 90531df commit 9b59443
Show file tree
Hide file tree
Showing 45 changed files with 3,314 additions and 55 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ Example for the **LineFollowerTarget** application:
| 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](https://github.com/BlueAndi/DroidControlShip) in a convoy leader role. | No | Yes | ./webots/worlds/zumo_with_com_system/PlatoonTrack.wbt |
| ConvoyFollower | Convoy follower, providing information to the [DroidControlShip](https://github.com/BlueAndi/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. | Yes | No | ./webots/worlds/ETrack.wbt ./webots/worlds/LargeTrack.wbt ./webots/worlds/LineFollowerTrack.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](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 |
| Test | Only for testing purposes on native environment. | Yes | No | N/A |
Expand Down
4 changes: 2 additions & 2 deletions lib/APPCalib/src/ErrorState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "StartupState.h"
#include <DifferentialDrive.h>
#include <Logging.h>
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -95,9 +96,8 @@ void ErrorState::process(StateMachine& sm)
IButton& buttonA = Board::getInstance().getButtonA();

/* Restart calibration? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&StartupState::getInstance());
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/APPCalib/src/ErrorState.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ class ErrorState : public IState
static const size_t ERROR_MSG_SIZE = 20;

char m_errorMsg[ERROR_MSG_SIZE]; /**< Error message, which to show. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */

/**
* Default constructor.
*/
ErrorState() : m_errorMsg()
ErrorState() : m_errorMsg(), m_isButtonAPressed(false)
{
m_errorMsg[0] = '\0';
}
Expand Down
13 changes: 7 additions & 6 deletions lib/APPCalib/src/ReadyState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <DifferentialDrive.h>
#include <Logging.h>
#include "DrivingState.h"
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -82,30 +83,30 @@ void ReadyState::process(StateMachine& sm)
IButton& buttonC = board.getButtonC();

/* Drive forward? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
DrivingState::getInstance().setCmd(DrivingState::DRIVING_CMD_FORWARD);
buttonA.waitForRelease();

m_releaseTimer.start(RELEASE_DURATION);

LOG_INFO("Drive forward 10 cm.");
}

/* Turn left? */
if (true == buttonB.isPressed())
if (true == Util::isButtonTriggered(buttonB, m_isButtonBPressed))
{
DrivingState::getInstance().setCmd(DrivingState::DRIVING_CMD_TURN_LEFT);
buttonB.waitForRelease();

m_releaseTimer.start(RELEASE_DURATION);

LOG_INFO("Turn left 90°.");
}

/* Turn right? */
if (true == buttonC.isPressed())
if (true == Util::isButtonTriggered(buttonC, m_isButtonCPressed))
{
DrivingState::getInstance().setCmd(DrivingState::DRIVING_CMD_TURN_RIGHT);
buttonC.waitForRelease();

m_releaseTimer.start(RELEASE_DURATION);

LOG_INFO("Turn right 90°.");
Expand Down
11 changes: 10 additions & 1 deletion lib/APPCalib/src/ReadyState.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,20 @@ class ReadyState : public IState
SimpleTimer m_timer; /**< Used to show information for a certain time before changing to the next info. */
UserInfo m_userInfoState; /**< Current user info state. */
SimpleTimer m_releaseTimer; /**< Release timer */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */
bool m_isButtonBPressed; /**< Is the button B pressed (last time)? */
bool m_isButtonCPressed; /**< Is the button C pressed (last time)? */

/**
* Default constructor.
*/
ReadyState() : m_timer(), m_userInfoState(USER_INFO_DRIVE_FORWARD), m_releaseTimer()
ReadyState() :
m_timer(),
m_userInfoState(USER_INFO_DRIVE_FORWARD),
m_releaseTimer(),
m_isButtonAPressed(false),
m_isButtonBPressed(false),
m_isButtonCPressed(false)
{
}

Expand Down
9 changes: 4 additions & 5 deletions lib/APPCalib/src/StartupState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "MotorSpeedCalibrationState.h"
#include "ReadyState.h"
#include <DifferentialDrive.h>
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -97,9 +98,8 @@ void StartupState::process(StateMachine& sm)
IButton& buttonB = board.getButtonB();

/* Start max. motor speed calibration? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&MotorSpeedCalibrationState::getInstance());
}

Expand All @@ -109,10 +109,9 @@ void StartupState::process(StateMachine& sm)
if (true == m_isMaxMotorSpeedCalibAvailable)
{
/* Ready to drive? */
if (true == buttonB.isPressed())
if (true == Util::isButtonTriggered(buttonB, m_isButtonBPressed))
{
buttonB.waitForRelease();
sm.setState(&ReadyState::getInstance());
sm.setState(&MotorSpeedCalibrationState::getInstance());
}
}

Expand Down
9 changes: 8 additions & 1 deletion lib/APPCalib/src/StartupState.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,18 @@ class StartupState : public IState
bool m_isMaxMotorSpeedCalibAvailable; /**< Is max. motor speed calibration value available? */
SimpleTimer m_timer; /**< Used to show information for a certain time before changing to the next info. */
UserInfo m_userInfoState; /**< Current user info state. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */
bool m_isButtonBPressed; /**< Is the button B pressed (last time)? */

/**
* Default constructor.
*/
StartupState() : m_isMaxMotorSpeedCalibAvailable(false), m_timer(), m_userInfoState(USER_INFO_TEAM_NAME)
StartupState() :
m_isMaxMotorSpeedCalibAvailable(false),
m_timer(),
m_userInfoState(USER_INFO_TEAM_NAME),
m_isButtonAPressed(false),
m_isButtonBPressed(false)
{
}

Expand Down
4 changes: 2 additions & 2 deletions lib/APPConvoyLeader/src/ErrorState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <StateMachine.h>
#include "StartupState.h"
#include <DifferentialDrive.h>
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -78,9 +79,8 @@ void ErrorState::process(StateMachine& sm)
IButton& buttonA = Board::getInstance().getButtonA();

/* Restart calibration? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&StartupState::getInstance());
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/APPConvoyLeader/src/ErrorState.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ class ErrorState : public IState
static const size_t ERROR_MSG_SIZE = 20;

char m_errorMsg[ERROR_MSG_SIZE]; /**< Error message, which to show. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */

/**
* Default constructor.
*/
ErrorState() : m_errorMsg()
ErrorState() : m_errorMsg(), m_isButtonAPressed(false)
{
m_errorMsg[0] = '\0';
}
Expand Down
2 changes: 1 addition & 1 deletion lib/APPLineFollower/src/DrivingState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const int16_t DrivingState::POSITION_SET_POINT =

/* Initialize the required sensor IDs to be generic. */
const uint8_t DrivingState::SENSOR_ID_MOST_LEFT = 0U;
const uint8_t DrivingState::SENSOR_ID_MIDDLE = Board::getInstance().getLineSensors().getNumLineSensors() / 2U;
const uint8_t DrivingState::SENSOR_ID_MIDDLE = (Board::getInstance().getLineSensors().getNumLineSensors() - 1U) / 2U;
const uint8_t DrivingState::SENSOR_ID_MOST_RIGHT = Board::getInstance().getLineSensors().getNumLineSensors() - 1U;

/* Initialize the position values used by the algorithmic. */
Expand Down
10 changes: 6 additions & 4 deletions lib/APPLineFollower/src/ErrorState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "StartupState.h"
#include <DifferentialDrive.h>
#include <Logging.h>
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -70,8 +71,10 @@ LOG_TAG("EState");

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 @@ -95,9 +98,8 @@ void ErrorState::process(StateMachine& sm)
IButton& buttonA = Board::getInstance().getButtonA();

/* Restart calibration? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&StartupState::getInstance());
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/APPLineFollower/src/ErrorState.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ class ErrorState : public IState
static const size_t ERROR_MSG_SIZE = 20;

char m_errorMsg[ERROR_MSG_SIZE]; /**< Error message, which to show. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */

/**
* Default constructor.
*/
ErrorState() : m_errorMsg()
ErrorState() : m_errorMsg(), m_isButtonAPressed(false)
{
m_errorMsg[0] = '\0';
}
Expand Down
6 changes: 3 additions & 3 deletions lib/APPLineFollower/src/ReadyState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ void ReadyState::process(StateMachine& sm)
IButton& buttonA = Board::getInstance().getButtonA();

/* Shall track be released? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&ReleaseTrackState::getInstance());
}

/* Shall the line sensor values be printed out on console? */
else if (true == m_timer.isTimeout())
if (true == m_timer.isTimeout())
{
ILineSensors& lineSensors = Board::getInstance().getLineSensors();
uint8_t index = 0;
Expand Down
3 changes: 2 additions & 1 deletion lib/APPLineFollower/src/ReadyState.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ class ReadyState : public IState
SimpleTimer m_timer; /**< Timer used for cyclic debug output. */
bool m_isLapTimeAvailable; /**< Is set (true), if a lap time is available. */
uint32_t m_lapTime; /**< Lap time in ms of the last successful driven round. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */

/**
* Default constructor.
*/
ReadyState() : m_timer(), m_isLapTimeAvailable(false), m_lapTime(0)
ReadyState() : m_timer(), m_isLapTimeAvailable(false), m_lapTime(0), m_isButtonAPressed(false)
{
}

Expand Down
6 changes: 3 additions & 3 deletions lib/APPLineFollower/src/ReleaseTrackState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <StateMachine.h>
#include "DrivingState.h"
#include "ParameterSets.h"
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -77,13 +78,12 @@ void ReleaseTrackState::process(StateMachine& sm)
IButton& buttonA = Board::getInstance().getButtonA();

/* Change parameter set? */
if (true == buttonA.isPressed())
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
/* Choose next parameter set (round-robin) */
/* Choose next parameter set (round-robin). */
ParameterSets::getInstance().next();
showParSet();

buttonA.waitForRelease();
m_releaseTimer.restart();
}

Expand Down
5 changes: 3 additions & 2 deletions lib/APPLineFollower/src/ReleaseTrackState.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,13 @@ class ReleaseTrackState : public IState
/** Track release timer duration in ms. */
static const uint32_t TRACK_RELEASE_DURATION = 5000;

SimpleTimer m_releaseTimer; /**< Track release timer */
SimpleTimer m_releaseTimer; /**< Track release timer */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */

/**
* Default constructor.
*/
ReleaseTrackState()
ReleaseTrackState() : m_releaseTimer(), m_isButtonAPressed(false)
{
}

Expand Down
11 changes: 5 additions & 6 deletions lib/APPLineFollower/src/StartupState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "LineSensorsCalibrationState.h"
#include "Sound.h"
#include <DifferentialDrive.h>
#include <Util.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -96,11 +97,10 @@ void StartupState::process(StateMachine& sm)
Board& board = Board::getInstance();
IButton& buttonA = board.getButtonA();

/* Start max. motor speed calibration? */
if (true == buttonA.isPressed())
/* Start line sensor calibration? */
if (true == Util::isButtonTriggered(buttonA, m_isButtonAPressed))
{
buttonA.waitForRelease();
sm.setState(&MotorSpeedCalibrationState::getInstance());
sm.setState(&LineSensorsCalibrationState::getInstance());
}

/* If the max. motor speed calibration is done, it will be possible to
Expand All @@ -111,9 +111,8 @@ void StartupState::process(StateMachine& sm)
IButton& buttonB = board.getButtonB();

/* Start line sensor calibration? */
if (true == buttonB.isPressed())
if (true == Util::isButtonTriggered(buttonB, m_isButtonBPressed))
{
buttonB.waitForRelease();
sm.setState(&LineSensorsCalibrationState::getInstance());
}
}
Expand Down
9 changes: 8 additions & 1 deletion lib/APPLineFollower/src/StartupState.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,18 @@ class StartupState : public IState
bool m_isMaxMotorSpeedCalibAvailable; /**< Is max. motor speed calibration value available? */
SimpleTimer m_timer; /**< Used to show information for a certain time before changing to the next info. */
UserInfo m_userInfoState; /**< Current user info state. */
bool m_isButtonAPressed; /**< Is the button A pressed (last time)? */
bool m_isButtonBPressed; /**< Is the button B pressed (last time)? */

/**
* Default constructor.
*/
StartupState() : m_isMaxMotorSpeedCalibAvailable(false), m_timer(), m_userInfoState(USER_INFO_TEAM_NAME)
StartupState() :
m_isMaxMotorSpeedCalibAvailable(false),
m_timer(),
m_userInfoState(USER_INFO_TEAM_NAME),
m_isButtonAPressed(false),
m_isButtonBPressed(false)
{
}

Expand Down
17 changes: 17 additions & 0 deletions lib/APPLineFollowerSimple/library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "APPLineFollowerSimple",
"version": "0.1.0",
"description": "LineFollower application",
"authors": [{
"name": "Andreas Merkle",
"email": "[email protected]",
"url": "https://github.com/BlueAndi",
"maintainer": true
}],
"license": "MIT",
"dependencies": [{
"name": "Service"
}],
"frameworks": "*",
"platforms": "*"
}
Loading

0 comments on commit 9b59443

Please sign in to comment.