micro-ROS / micro-ROS_crazyflie_demo

Provides a demo of micro-ROS based on a Crazyflie.
Apache License 2.0
18 stars 6 forks source link

Problems to run the example without docker #13

Closed matheus-ps closed 3 years ago

matheus-ps commented 3 years ago

Hello!

I'm trying to run this demo with Foxy natively, but I'm having some problems to understand which are the steps to do it. I build and flashed the Crazyflie with the crazyflie_position_publisher app. I have all the Bitcraze libraries installed and working well (cflib and cfclient). I want only to see the odometry and attitude data of the Crazyflie in my terminal (Using the micro-ROS agent). What should i configure inside the uros_cf_bridge_no_joystick? I saw the lines 66 and 67

serial_dev = '/dev/ttyS11' serial_dev_agent = '/dev/ttyS10'

but I get some errors about permission to access this port.

Can you guys give me some light about it?

pablogs9 commented 3 years ago

Hello, in this case, the connection between the micro-ROS client and agent is a bit tricky.

You have to launch a script that uses the cflibraries and creates a virtual serial port: check here

This will connect to the drone and tell you a serial port number: Check here

Finally, you should open a micro-ROS agent in this serial port, like here

Let me know if this clarifies something.

matheus-ps commented 3 years ago

Hi Pablo! Thank you for your help! I followed your steps, and I had to run the python script with Sudo and the agent as root for not getting any errors (Permission denied and run as superuser). Unfortunately, there are no data printed in the agent terminal, as my prints below show.

Captura de tela de 2021-01-19 10-58-12

I only changed this line to the full address of the Crazyflie link_uri = "radio://0/30/2M/E7E7E7E7E3", so the radio could connect to the drone (both LEDs are blinking)

Do you have any idea what this problem can be?

pablogs9 commented 3 years ago

It seems that the drone is not being connected to the bridge... Can you debug this Python application in order to check if it is receiving something from the drone radio?

Does the bridge work in the same way if you disconnect the Crazyradio?

matheus-ps commented 3 years ago

The drone is connected and CRTPs packages are been received here. One strange thing is the port number of the pk.port is always 15. It is not supposed to be 10?

If I disconnect the crazyradio, the python script returns an error (Could not find the Dongle)

pablogs9 commented 3 years ago

if the port is 15, the drone is not sending micro-ROS packages. Check the drone micro-ROS transport here.

It should be using port 9 as you can see here. Can you test it?

Do you have a way to debug the drone code and check if it is reaching the micro-ROS transport?

matheus-ps commented 3 years ago

Hi Pablo! Thanks again for your help! I do not have a debugger, so I start to debug in the old way (with console prints). I found that the app.c script does not get off this line. The RCCHECK(fn) prints that -> "Failed status on line 67: 1. Aborting.", but there is nothing on line 67 of the init.c file.

This 67 means something else?

pablogs9 commented 3 years ago

This means that the micro-ROS client is not reaching the micro-ROS agent and it is not able to create the session.

You should be aware that micro-ROS only tries to connect to the agent for a while defined here, so, you should have ready the bridge and the agent in the moment that the drone is turned on.

I don't have right now a drone here, but next week I'll be able to test this. Let me know if you achieve something meanwhile.

matheus-ps commented 3 years ago

Ok Pablo, I tried to run as you have specified, but I keep getting the same results (Sometimes the FreeRTOS of the Crazyflie crashes -> M1 Red LED always on). I will keep trying to see what is happening, but could you say which version of the nRF51822 firmware are you guys using? Thank you!

pablogs9 commented 3 years ago

I'm not sure, but probably we have updated to the last version. Is there any way of checking it?

matheus-ps commented 3 years ago

Hi Pablo! I update the Firmware of the NRF51 to this version. I got now two new notifications in the agent terminal as you can see below

Captura de tela de 2021-01-21 20-40-32

There are these sessions established and re-established but no odometry or attitude data, unfortunately. I checked the packages in the bridge script and there are packages with port numbers 15 (log data?) and 9 (micro-ROS). Do you have any idea of what I could be missing?

pablogs9 commented 3 years ago

If the client is creating a session in the agent and nothing else, usually it is that the way client->agent is ok and the way agent->client is not working.

The client does not continue creating entities because never receives the confirmation of the created session.

matheus-ps commented 3 years ago

Ok, thank you! Do you think this is a problem related with the fact that I am running the agent as root and the rest as my normal user? Do you have any suggestions of how I can debug the agent to fix that?

pablogs9 commented 3 years ago

Have you tried to create the ports with the correct permissions to avoid needing root? Maybe something related with: https://github.com/micro-ROS/micro-ROS_crazyflie_demo/blob/7e76dc2f968d1802dac463a34713503191d6b91e/dockerfile/client/uros_cf_bridge_joystick.py#L86

matheus-ps commented 3 years ago

Hello again Pablo! I was capable to allow my computer to open the ports without root, but I still cannot see any data in the agent terminal. The crazyflie still can not get-off this line now with messages

Failed status on line 113: 1. Continuing.
Failed status on line 111: 1. Continuing.

Could you get a drone to test this behaviour on your computer this week?

pablogs9 commented 3 years ago

Yes, I have it in my TODO list. Tomorrow I will test it.

pablogs9 commented 3 years ago

Hello again, sorry for the delay. I have achieved something:

image

These are my steps:

  1. I have updated the micro-ROS application, check here: https://github.com/micro-ROS/freertos_apps/pull/52 as you can see, with the new Crazyflie transport you need to specify the channel, in this case, the 65. In the case that you don't set this, it will try to use a channel that maybe is memory trash (uninitialized), check here.
  2. Then the "brigde" that I'm using copied below.
  3. And finally I'm just running a micro-ROS Agent in the port that the brigde opens with:
    docker run -it --rm -v /dev:/dev --privileged --net=host microros/micro-ros-agent:foxy serial --dev [YOUR PORT] -v6

So my execution order is:

  1. Open de brigde
  2. Open the micro-ROS Agent
  3. Power the drone

Bridge:

"""
Headless client for the Crazyflie.
"""
import logging
import os
import signal
import sys
import serial
import threading
import time
import subprocess
import math

import cflib.crtp
from cflib.crtp.crtpstack import CRTPPacket
from cflib.crazyflie import Crazyflie

os.environ["SDL_VIDEODRIVER"] = "dummy"

CRTP_PORT_MICROROS = 9

class CrazyradioBridge():

    def __init__(self, link_uri, serialport):
        """Initialize the headless client and libraries"""
        self._serial = serialport

        self.link = cflib.crtp.get_link_driver(link_uri, None, None)
        self.link._radio_manager._radios[0].radio.set_power(0)

        self.is_connected = True

        self._q = []

        self.serialthread = threading.Thread(target=self._serial_listener)
        self.serialthread.start()

        self.cfthread = threading.Thread(target=self._cf_listener)
        self.cfthread.start()

    def _link_quality(self,q):
        self._q.append(q)
        if len(self._q) > 10:
            print("{:0.3f}".format((1/10)*math.sqrt(sum([x**2 for x in self._q])/len(self._q))), end="\r")
            self._q = []

    def _serial_listener(self):
        while self.is_connected:
            data = self._serial.read(size=29)
            if(data):
                pk = CRTPPacket()
                pk.port = CRTP_PORT_MICROROS
                pk.data = data
                self.link.send_packet(pk)

    def _cf_listener(self):
        while self.is_connected:
            pk = self.link.receive_packet(1)
            if pk is None or pk.port != CRTP_PORT_MICROROS:
                continue
            print(pk)
            self._serial.write(pk.data)
            self._serial.flush()

def main():
    # Creating a socat bridge
    serial_dev = '/dev/ttyS11'
    serial_dev_agent = '/dev/ttyS10'
    socat_process = subprocess.Popen(["socat", "PTY,link=/dev/ttyS10", "PTY,link=" + serial_dev])
    time.sleep(1)
    print("Use " + serial_dev_agent + " for micro-ROS agent connection")

    # Set logging level
    logging.basicConfig(level=logging.INFO)

    # Open serial port
    serialport = serial.Serial(serial_dev, baudrate=115200, timeout=0.2)

    # Configure radio link
    cflib.crtp.radiodriver.set_retries_before_disconnect(-1)
    cflib.crtp.radiodriver.set_retries(1)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    link_uri = "radio://0/65/2M"

    try:
        while True:
            cf = CrazyradioBridge(link_uri, serialport)
            while cf.is_connected:
                time.sleep(0.1)
            print("Disconected from: " + str(link_uri))
    except KeyboardInterrupt:
        pass

    os.killpg(os.getpgid(socat_process.pid), signal.SIGTERM)

if __name__ == "__main__":
    main()
matheus-ps commented 3 years ago

Hi Pablo! I acomplished to run the example as you specified, and I'm thankful for that! Is there some way to run without the docker container? I tried with the commands that we were talking in the past, but as I told you, the connection is established, but no data appears in the agent terminal.

pablogs9 commented 3 years ago

Without which docker? The agent one?

matheus-ps commented 3 years ago

Yes! The agent! Maybe this is not so critical, as my goal is to send flight commands to the crazyflie with the micro-ROS communication. But if I do not depend on docker, it will be better.

pablogs9 commented 3 years ago

Of course, you can install the micro-ROS Agent in a common ROS2 workspace with this package or even you have it available as a snap package.

If you don't mind I'm closing this, please do not hesitate to reopen if you have any other doubts.