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

Improvements on the BCB battery module #727

Merged
merged 7 commits into from
Mar 17, 2021

Conversation

S-Dafarra
Copy link
Contributor

@S-Dafarra S-Dafarra commented Mar 9, 2021

Intro

This PR attempts at improving the bcbBattery module, fixing the following issues:

  • thread_period was not found in the conf file and most probably assumed to be zero.
  • A mutex was missing in the close method causing data races on the use of the serial device.
  • The voltage and current values were not divided by 1000 (the board sends the values in mV and mA)
  • It was not properly checked if the char were read correctly or not. Most of the times, the read values were from uninitialized memory.
  • The sync mechanism seemed to have issues
  • The methods returning the battery status and temperature were always returning false, avoiding the BatteryWrapper to stream the values.
  • The print of the received buffer was not readable.

In addition, I added the following:

  • A parameter to avoid printing the messages relative to sync issues (in case it will be ever added to the robot main yarprobotinterface).
  • Improved the closing logic, aborting any while loop in the run method when closing.
  • Stop the BCB transmission when closing the device
  • Added a simple README.

How to test it on the robot head

(I will move these lines to a proper place afterward, this is just for reference)

Bluetooth setup

First, it is necessary to understand the Bluetooth ID relative to the BCB board installed on the robot. For example, in iCubGenova04 this is named RNBT-8223 (in general it should be RNBT-something) and has the address 00:06:66:E7:82:23.

First, you need to pair it. In order to do so, you can use bluetoothctl. In particular, after running bluetoothctl, you can trust the device with

scan on
trust 00:06:66:E7:82:23

and then

pair  00:06:66:E7:82:23

It may ask you to enter yes just to check that the passcode is correct.

After that, it is not possible to connect since the board is not compatible with BlueZ. In order to use it as a serial device, it is possible to use rfcomm:

sudo rfcomm -r connect 0 00:06:66:E7:82:23

This connects to the Bluetooth and creates a serial device named /dev/rfcomm0 in raw mode. The problem with rfcomm connect is that it keeps the connection with the Bluetooth board even when not necessary. Alternatively, it is possible to use

sudo rfcomm bind 0 00:06:66:E7:82:23

This connects to the Bluetooth only when the port /dev/rfcomm0 is opened. The drawback is that this interprets the serial communication as TTY. This causes the \r chars to be changed into \n, hence messing up with the communication protocol of the BCB board. This can be fixed by using

sudo stty -F /dev/rfcomm0 raw

On the robot side, whenever we connect to the BCB board, a blue LED should light up between the "Motors" and "CPU" button. .

Unfortunately, it seems that the LED to notify that a connection is done is not installed in the BCB currently on iCubGenova04. Still, there is a blue LED visible from inside the backpack. This gets constant blue when connected to the Bluetooth (i.e. when opening the file /dev/rfcomm0).

image

When nothing is connected, it blinks:

VID_20210216_173130.mp4

How to run the connection automatically at startup

The connections made via rfcomm get reset when shutting down. In order to have them working at startup, I created a system service as follows. First I created the file battery_bluetooth.service in the folder /etc/systemd/system/ as follows

battery_bluetooth.service content

[Unit]
Description=Connect to the BCB board via bluetooth using rfcomm
After=bluetooth.service

[Service]
Type=oneshot
ExecStart=/bin/bash /home/icub/battery_bluetooth.sh

[Install]
WantedBy=multi-user.target

This service runs once the battery_bluetooth.sh script once at startup after running the bluetooth service.

battery_bluetooth.sh content

#!/bin/bash

address=00:06:66:E7:82:23

connected=0
i=0

echo Started

while (( connected == 0 && i < 10 ))
do
    echo Attempt $i
    rfcomm release 0 # Close eventual previous connections
    rfcomm -r connect 0 $address > /tmp/connect_out 2>&1 & #executes rfcomm in background to check that bluetooth is working
    sleep 5
    pid=$! #stores executed process id in pid
    count=$(ps -A| grep $pid |wc -l) #check whether process is still running
    if [[ $count -eq 0 ]] #if process is already terminated, then there were issues in connecting
    then
        cat /tmp/connect_out
        echo Connect failed
        if grep -q "No route to host" /tmp/connect_out; then # There are issues with the bluetooth
            echo "There might be a problem with the bluetooth. If it persists, try running sudo service bluetooth restart"
        fi
    else
        rfcomm release 0
        echo Released connection
        sleep 1
        cat /tmp/connect_out
        if grep -q "$address" /tmp/connect_out; then # If the connection was successfull, the address should be displayed in the output
            echo Connect successfull
            rfcomm bind 0 $address > /tmp/bind_out 2>&1
            cat /tmp/bind_out
            if [[ -s /tmp/bind_out ]]; then #if bind is successfull does not print anything
                echo  Bind returned error
            else
                echo Bind successfull
                sleep 1
                echo Calling stty
                stty -F /dev/rfcomm0 raw
                stty_return=$?
                if [[ $stty_return -eq 0 ]]
                then
                    echo stty successfull
                    connected=1
                else
                    echo stty failed
                fi
            fi
        else
            echo Connect failed
        fi
    fi
    i=$((i+1))
done

The scripts first tries to connect using rfcomm connect. If it works (hence rfcomm connect is still alive), releases the connection. Then it tries running rfcomm bind and stty checking the outputs in case of errors. If there is any error, it tries again at most 10 times.

This service can be enabled at startup with

sudo systemctl enable battery_bluetooth.service

and started with

sudo systemctl enable battery_bluetooth.service

In case there were errors starting the service, it is possible to inspect the output of the script with

systemctl status battery_bluetooth.service

This script can also be run after startup in case the connection is not working, with

sudo bash ~/battery_bluetooth.sh
Running the module

In case of iCubGenova04, I already added the configuration files and they are installed. Hence, to run the module it is sufficient to run

yarprobotinterface --config battery/icub_battery.xml

otherwise, it is possible to go to the battery folder in the experimentalSetups of robots-configuration and run

yarprobotinterface

Once it is running, it is possible to visualize the battery status from anywhere in yarp network by running

yarpbatterygui --remote /icub/battery

- thread_period was not found in the conf file and most probably assumed to be zero.
- A mutex was missing in the close method.
- The voltage and current values were not divided by 1000 (the board sends the values in mV and mA)
- It was not properly checked if the char were read correctly or not
- The sync mechanism is too restrictive and seems to be not working on Linux
- The methods returning the battery status and temperature were always returning false, avoiding the BatteryWrapper to stream the values.
- The print of the received buffer was not readable.
@S-Dafarra
Copy link
Contributor Author

PR to fix the configuration files in the experimentalSetup folder: robotology/robots-configuration#245

Copy link
Member

@pattacini pattacini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks heaps @S-Dafarra for this work 👍🏻

I believe it's important that @randaz81 reviews this.

⚠ Please, don't merge the PR straight away as I will most likely squash and merge it.

@S-Dafarra
Copy link
Contributor Author

Regarding the Windows failure, that seemed to be an Action internal problem
image

@pattacini
Copy link
Member

Any news @randaz81 ?

@S-Dafarra
Copy link
Contributor Author

CCing some people I bothered during the process @maggia80 @MrAndrea @kouroshD @DanielePucci

@pattacini
Copy link
Member

Merging. Anyway, we can always modify anything needed later on.

@pattacini pattacini merged commit 7b1bd4e into robotology:devel Mar 17, 2021
S-Dafarra added a commit to S-Dafarra/documentation that referenced this pull request Apr 16, 2021
pattacini pushed a commit to icub-tech-iit/documentation that referenced this pull request Apr 16, 2021
@pattacini
Copy link
Member

@Nicogene, our Distro Manager, has started today the operations required to yield the Distro 2021.05.
Therefore, @randaz81, if you aim to make some modifications in this respect, consider this timeline that is getting quite tight.

@randaz81
Copy link
Member

@S-Dafarra can we do a test tomorrow with the robot?

@S-Dafarra
Copy link
Contributor Author

@S-Dafarra can we do a test tomorrow with the robot?

We can try with the purple if that is available. The greeny is currently busy with some experiments.

@randaz81 randaz81 mentioned this pull request May 21, 2021
pattacini pushed a commit to icub-tech-iit/documentation that referenced this pull request Jun 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants