Skip to content

Commit

Permalink
Logging refactored. Use the LOG_TAG() macro to specify a filename tag…
Browse files Browse the repository at this point in the history
…. Additional in simulation the Serial uses by default the Terminal stream. Use -s to enable the Socket stream! This is easier for users, who struggle at the beginning why they can't see any log message on the console. The README contains further explanations and small fixes to be consistent with the current state.

#37
  • Loading branch information
BlueAndi committed Nov 25, 2023
1 parent 847d3b9 commit e47063f
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 171 deletions.
44 changes: 36 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Several kind of exclusive applications are available:
* [Build](#build)
* [Preparation](#preparation)
* [Running the robot on track](#running-the-robot-on-track)
* [Communicate with the DroidControlShip](#communicate-with-the-droidcontrolship)
* [The target](#the-target)
* [Build and flash procedure](#build-and-flash-procedure)
* [Documentation](#documentation)
* [Used Libraries](#used-libraries)
* [Issues, Ideas And Bugs](#issues-ideas-and-bugs)
Expand Down Expand Up @@ -63,34 +66,59 @@ To adapt the HAL to the simulation, some sourcecode files from Webots are necess
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> --> Build

Platformio project tasks --> WebotsSim --> Build
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/LineFollower_track.wbt```.
3. Select ```./webots/worlds/LineFollowerTrack.wbt```.
4. The loaded world should now look like this: ![webots_world](./doc/webots_world.jpg)
5. Open a command line (shell) and change to the folder with the built executable in ```.pio/build/native```. This folder contains all necessary shared libraries as well.
5. 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.
6. Start the executable and the simulated display should show the name of the team and etc.

## Running the robot on track

1. Click in simulation on the display to focus the simulation.
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
For the communication with the DroidControlShip a socket server needs to be enabled, which is disabled by default.

Use the -s flag to enable it with default port 65432. Note, this will disable the standard logging, because the serial communication will automatically be routed over the socket. The SerialMuxProt protocol is used to exchange data in both directions.
```bash
$ program.exe -s
```

The port can be changed via command line parameters, please use -? to get more details.
```bash
$ program.exe -?
```

# The target

## Build and flash procedure
1. PlatformIO project tasks --> <APP-NAME> --> 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> --> Upload
4. Ready.

# Documentation

* [SW Architecture](./doc/architecture/README.md)
* [SW Configuration](./doc/configuration/README.md)

# Used Libraries

| Library | Description | License |
| - | - | - |
| [Zumo32U4 library](https://github.com/pololu/zumo-32u4-arduino-library) | Provides access to the Zumo32U4 hardware. | MIT |
| [SerialMuxProt](https://github.com/gabryelreyes/SerialMuxProt) | Multiplexing Communication Protocol | MIT |
| Library | Description | License |
| ----------------------------------------------------------------------- | ----------------------------------------- | ------- |
| [Zumo32U4 library](https://github.com/pololu/zumo-32u4-arduino-library) | Provides access to the Zumo32U4 hardware. | MIT |
| [SerialMuxProt](https://github.com/gabryelreyes/SerialMuxProt) | Multiplexing Communication Protocol | MIT |

# Issues, Ideas And Bugs
If you have further ideas or you found some bugs, great! Create a [issue](https://github.com/BlueAndi/RadonUlzer/issues) or if you are able and willing to fix it by yourself, clone the repository and create a pull request.
Expand Down
2 changes: 2 additions & 0 deletions lib/APPConvoyLeader/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <DifferentialDrive.h>
#include <Odometry.h>
#include <Util.h>
#include <Logging.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -69,6 +70,7 @@ static void App_motorSpeedSetpointsChannelCallback(const uint8_t* payload, const
void App::setup()
{
Serial.begin(SERIAL_BAUDRATE);
Logging::disable();
Board::getInstance().init();
m_systemStateMachine.setState(&StartupState::getInstance());
m_controlInterval.start(DIFFERENTIAL_DRIVE_CONTROL_PERIOD);
Expand Down
6 changes: 3 additions & 3 deletions lib/APPConvoyLeader/MotorSpeedCalibrationState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
/**
* Logging source.
*/
static const char* TAG = "MSCState";
LOG_TAG("MSCState");

/******************************************************************************
* Public Methods
Expand Down Expand Up @@ -215,8 +215,8 @@ void MotorSpeedCalibrationState::finishCalibration(StateMachine& sm)
}
else
{
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (steps/s): ", maxSpeed);
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);
LOG_INFO_VAL("Calibrated max. speed (steps/s): ", maxSpeed);
LOG_INFO_VAL("Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);

sm.setState(&ReadyState::getInstance());
}
Expand Down
6 changes: 3 additions & 3 deletions lib/APPLineFollower/MotorSpeedCalibrationState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
/**
* Logging source.
*/
static const char* TAG = "MSCState";
LOG_TAG("MSCState");

/******************************************************************************
* Public Methods
Expand Down Expand Up @@ -215,8 +215,8 @@ void MotorSpeedCalibrationState::finishCalibration(StateMachine& sm)
}
else
{
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (steps/s): ", maxSpeed);
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);
LOG_INFO_VAL("Calibrated max. speed (steps/s): ", maxSpeed);
LOG_INFO_VAL("Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);

sm.setState(&LineSensorsCalibrationState::getInstance());
}
Expand Down
10 changes: 5 additions & 5 deletions lib/APPLineFollower/ReadyState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
/**
* Logging source.
*/
static const char* TAG = "RState";
LOG_TAG("RState");

/******************************************************************************
* Public Methods
Expand Down Expand Up @@ -103,9 +103,9 @@ void ReadyState::process(StateMachine& sm)
uint8_t index = 0;
int16_t position = lineSensors.readLine();
const uint16_t* sensorValues = lineSensors.getSensorValues();
char valueStr[10];
char valueStr[10];

LOG_DEBUG_HEAD(TAG);
LOG_DEBUG_HEAD();

/* Print line sensor value on console for debug purposes. */
for (index = 0; index < lineSensors.getNumLineSensors(); ++index)
Expand All @@ -116,12 +116,12 @@ void ReadyState::process(StateMachine& sm)
}

Util::uintToStr(valueStr, sizeof(valueStr), sensorValues[index]);

LOG_DEBUG_MSG(valueStr);
}

LOG_DEBUG_MSG(" -> ");

Util::intToStr(valueStr, sizeof(valueStr), position);
LOG_DEBUG_MSG(valueStr);

Expand Down
3 changes: 3 additions & 0 deletions lib/APPRemoteControl/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <Odometry.h>
#include <Board.h>
#include <Util.h>
#include <Logging.h>

/******************************************************************************
* Compiler Switches
Expand Down Expand Up @@ -74,6 +75,8 @@ static bool gIsRemoteCtrlActive = false;

void App::setup()
{
Serial.begin(SERIAL_BAUDRATE);
Logging::disable();
Board::getInstance().init();

m_systemStateMachine.setState(&StartupState::getInstance());
Expand Down
3 changes: 3 additions & 0 deletions lib/APPRemoteControl/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class App
void loop();

private:
/** Baudrate for Serial Communication */
static const uint32_t SERIAL_BAUDRATE = 115200U;

/** Differential drive control period in ms. */
static const uint32_t DIFFERENTIAL_DRIVE_CONTROL_PERIOD = 5;

Expand Down
6 changes: 3 additions & 3 deletions lib/APPRemoteControl/MotorSpeedCalibrationState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
/**
* Logging source.
*/
static const char* TAG = "MSCState";
LOG_TAG("MSCState");

/******************************************************************************
* Public Methods
Expand Down Expand Up @@ -215,8 +215,8 @@ void MotorSpeedCalibrationState::finishCalibration(StateMachine& sm)
}
else
{
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (steps/s): ", maxSpeed);
LOG_DEBUG_VAL(TAG, "Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);
LOG_INFO_VAL("Calibrated max. speed (steps/s): ", maxSpeed);
LOG_INFO_VAL("Calibrated max. speed (mm/s): ", maxSpeed / RobotConstants::ENCODER_STEPS_PER_MM);

sm.setState(&RemoteCtrlState::getInstance());
}
Expand Down
76 changes: 46 additions & 30 deletions lib/ArduinoNative/Arduino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
* Includes
*****************************************************************************/
#include <Arduino.h>
#include "Terminal.h"

#ifdef UNIT_TEST

#include <time.h>
#include "Terminal.h"

#else

Expand All @@ -46,6 +46,7 @@
#include <Keyboard.h>
#include "SocketServer.h"
#include <getopt.h>
#include <Logging.h>

#endif

Expand All @@ -66,9 +67,11 @@
/** This type defines the possible program arguments. */
typedef struct
{
const char* socketServerPort; /**< Socket server port */
const char* robotName; /**< Robot name */
bool verbose; /**< Show verbose information */
const char* socketServerPort; /**< Socket server port */
const char* robotName; /**< Robot name */
bool isSerialOverSocket; /**< Is serial communication over socket? */
bool verbose; /**< Show verbose information */

} PrgArguments;

#endif
Expand All @@ -91,21 +94,13 @@ static void showPrgArguments(const PrgArguments& prgArgs);
* Local Variables
*****************************************************************************/

#ifdef UNIT_TEST

/** Terminal/Console stream. */
static Terminal gTerminalStream;

/** Serial driver, used by Arduino applications. */
Serial_ Serial(gTerminalStream);

#else /* UNIT_TEST */

/** SocketServer stream. */
static SocketServer gSocketStream;

/** Serial driver, used by Arduino applications. */
Serial_ Serial(gSocketStream);
#ifndef UNIT_TEST

/**
* The maximum duration a simulated time step can have.
Expand All @@ -127,6 +122,9 @@ static const char* PRG_ARG_SOCKET_SERVER_PORT_DEFAULT = "65432";
/** Program argument default value of the verbose flag. */
static bool PRG_ARG_VERBOSE_DEFAULT = false;

/** Program argument default value of the serial over socket flag. */
static bool PRG_ARG_IS_SERIAL_OVER_SOCKET_DEFAULT = false;

/**
* Maximum number of socket connections.
*/
Expand Down Expand Up @@ -184,6 +182,7 @@ extern int main(int argc, char** argv)
int status = 0;
Keyboard& keyboard = Board::getInstance().getKeyboard();
PrgArguments prgArguments;
SocketServer socketStream;

printf("\n*** Radon Ulzer ***\n");

Expand All @@ -201,19 +200,28 @@ extern int main(int argc, char** argv)
showPrgArguments(prgArguments);
}

/* Initialize the socket server. */
if (false == gSocketStream.init(prgArguments.socketServerPort, SOCKET_SERVER_MAX_CONNECTIONS))
/* Enable socket server? */
if (true == prgArguments.isSerialOverSocket)
{
printf("Error initializing SocketServer.\n");
status = -1;
}
else
{
if (true == prgArguments.verbose)
if (false == socketStream.init(prgArguments.socketServerPort, SOCKET_SERVER_MAX_CONNECTIONS))
{
printf("Error initializing SocketServer.\n");
status = -1;
}
else
{
printf("SocketServer ready on port %s.\n", prgArguments.socketServerPort);
if (true == prgArguments.verbose)
{
printf("SocketServer ready on port %s.\n", prgArguments.socketServerPort);
}

Serial.setStream(socketStream);
Logging::disable();
}
}

if (0 == status)
{
/* Get simulation time handler. It will be used by millis() and delay(). */
gSimTime = &Board::getInstance().getSimTime();
}
Expand Down Expand Up @@ -257,7 +265,7 @@ extern int main(int argc, char** argv)
{
keyboard.getPressedButtons();
loop();
gSocketStream.process();
socketStream.process();
}
}
}
Expand Down Expand Up @@ -300,14 +308,15 @@ extern void delay(unsigned long ms)
static int handleCommandLineArguments(PrgArguments& prgArguments, int argc, char** argv)
{
int status = 0;
const char* availableOptions = "p:n:h";
const char* availableOptions = "p:n:hs";
const char* programName = argv[0];
int option = getopt(argc, argv, availableOptions);

/* Set default values */
prgArguments.socketServerPort = PRG_ARG_SOCKET_SERVER_PORT_DEFAULT;
prgArguments.robotName = PRG_ARG_ROBOT_NAME_DEFAULT;
prgArguments.verbose = PRG_ARG_VERBOSE_DEFAULT;
prgArguments.socketServerPort = PRG_ARG_SOCKET_SERVER_PORT_DEFAULT;
prgArguments.robotName = PRG_ARG_ROBOT_NAME_DEFAULT;
prgArguments.verbose = PRG_ARG_VERBOSE_DEFAULT;
prgArguments.isSerialOverSocket = PRG_ARG_IS_SERIAL_OVER_SOCKET_DEFAULT;

while ((-1 != option) && (0 == status))
{
Expand All @@ -321,6 +330,10 @@ static int handleCommandLineArguments(PrgArguments& prgArguments, int argc, char
prgArguments.socketServerPort = optarg;
break;

case 's': /* Is serial over socket? */
prgArguments.isSerialOverSocket = true;
break;

case 'v': /* Verbose */
prgArguments.verbose = true;
break;
Expand All @@ -346,7 +359,9 @@ static int handleCommandLineArguments(PrgArguments& prgArguments, int argc, char
printf("\t-h\t\t\tShow this help message.\n"); /* Help */
printf("\t-n <NAME>\t\tSet robot name.\n"); /* Robot Name */
printf("\t-p <PORT NUMBER>\tSet SocketServer port."); /* SocketServer Port */
printf(" Default: %s\n", PRG_ARG_SOCKET_SERVER_PORT_DEFAULT); /* SocketServer port default value*/
printf(" Default: %s\n", PRG_ARG_SOCKET_SERVER_PORT_DEFAULT); /* SocketServer port default value */
printf("\t-s\t\t\tEnable serial over socket.\n"); /* Flag */
printf("\t-v\t\t\tVerbose mode.\n"); /* Flag */
}

return status;
Expand All @@ -359,8 +374,9 @@ static int handleCommandLineArguments(PrgArguments& prgArguments, int argc, char
*/
static void showPrgArguments(const PrgArguments& prgArgs)
{
printf("Robot name : %s\n", prgArgs.robotName);
printf("SocketServer Port: %s\n", prgArgs.socketServerPort);
printf("Robot name : %s\n", prgArgs.robotName);
printf("SocketServer Port : %s\n", prgArgs.socketServerPort);
printf("Serial over socket: %s\n", (false == prgArgs.isSerialOverSocket) ? "disabled" : "enabled");
/* Skip verbose flag. */
}

Expand Down
Loading

0 comments on commit e47063f

Please sign in to comment.