Accessing the RadioController inputs

Firmware/software/electronics/mechanics
thasu
Member
Posts: 31
Joined: Wed Oct 18, 2017 7:16 am

Accessing the RadioController inputs

Post by thasu »

What are the variables used to pass the input of the controller to the CF? I'm trying to generate some control inputs by a code file and pass it to the CF so that we can fly it without using the controller. Basically I need to know the variables that are used to hold the values for thrust, yaw, pitch and roll inputs?
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Accessing the RadioController inputs

Post by arnaud »

Do you want to send the control from the radio, using the python lib, or do you want to generate the control values in the Crazyflie to have a fully autonomous Crazyflie without radio control?
thasu
Member
Posts: 31
Joined: Wed Oct 18, 2017 7:16 am

Re: Accessing the RadioController inputs

Post by thasu »

I want to generate control values without using the radio.
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Accessing the RadioController inputs

Post by arnaud »

OK. For a demo here I just made some autonomous code that makes the Crazyflie fly itself using the flow deck. I made that as a deck driver (since it is currently the easiest way to get your code to run in the Crazyflie).

One warning first: This code bypasses all safety like the radio watchdog so your crazyflie can and will fly away when controlled in that manner. For my test since I use the Kalman filter, we have a protection that cuts the motors when the Crazyflie is up-side-down. It did limit the problems during development.

So now for the code. I have this file in src/deck/driver/src/sequence.c:

Code: Select all

#include "deck.h"
#include "system.h"
#include "commander.h"

#include "FreeRTOS.h"
#include "task.h"

#include "debug.h"

#define DEBUG_MODULE "SEQ"

static void setHoverSetpoint(setpoint_t *setpoint, float vx, float vy, float z, float yawrate)
{
  setpoint->mode.z = modeAbs;
  setpoint->position.z = z;


  setpoint->mode.yaw = modeVelocity;
  setpoint->attitudeRate.yaw = yawrate;


  setpoint->mode.x = modeVelocity;
  setpoint->mode.y = modeVelocity;
  setpoint->velocity.x = vx;
  setpoint->velocity.y = vy;

  setpoint->velocity_body = true;
}

static void sequenceTask()
{
  static setpoint_t setpoint;
  int i = 0;

  systemWaitStart();

  vTaskDelay(M2T(3000));
  DEBUG_PRINT("Starting sequence ...\n");

  for (i=0; i<20; i++) {
    setHoverSetpoint(&setpoint, 0, 0, 0.2, 0);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }

  for (i=0; i<20; i++) {
    setHoverSetpoint(&setpoint, 0, 0, 0.4, 0);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }

  for (i=0; i<50; i++) {
    setHoverSetpoint(&setpoint, 0.5, 0, 0.4, 72);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }

  for (i=0; i<50; i++) {
    setHoverSetpoint(&setpoint, 0.5, 0, 0.4, -72);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }

  for (i=0; i<30; i++) {
    setHoverSetpoint(&setpoint, 0, 0, 0.4, 0);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }

  for (i=0; i<30; i++) {
    setHoverSetpoint(&setpoint, 0, 0, 0.2, 0);
    commanderSetSetpoint(&setpoint, 3);
    vTaskDelay(M2T(100));
  }
  
  while(1) {
    vTaskDelay(1000);
  }
}

static void sequenceInit()
{
  xTaskCreate(sequenceTask, "sequence", 2*configMINIMAL_STACK_SIZE, NULL,
              /*priority*/3, NULL);
}

static bool sequenceTest()
{
  return true;
}

const DeckDriver sequence_deck = {
  .vid = 0,
  .pid = 0,
  .name = "bcSequence",

  .usedGpio = 0,  // FIXME: set the used pins

  .init = sequenceInit,
  .test = sequenceTest,
};

DECK_DRIVER(sequence_deck);
I add it to Makefile (after all the decks):

Code: Select all

PROJ_OBJ_CF2 += sequence.o
Finally I force the deck driver to have it initialized by adding to my tools/make/config.mk:

Code: Select all

CFLAGS += -DDECK_FORCE=bcSequence
I flash the firmware and now, 3 seconds after startup, the Crazyflie starts to fly according to the sequence. This is the same sequence as in the flow sequence python example: https://github.com/bitcraze/crazyflie-l ... nceSync.py.

I hope this helps. The key here is the function "commanderSetSetpoint()" that allows you to set the current setpoint. The setpoint should be set often (there is a timeout at 0.5 seconds).
thasu
Member
Posts: 31
Joined: Wed Oct 18, 2017 7:16 am

Re: Accessing the RadioController inputs

Post by thasu »

Thank you for the reply. That is very helpful. Further, I need to know how to send commands same as the radio without using the radio. As an example, I would send 60% throttle for 2 seconds and hover command after that. Where can I enter this code part?
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Accessing the RadioController inputs

Post by arnaud »

The radio packets arrive in crtp_commander_rpy.c and crtp_commander_generic.c. I took part of the code from the hover decoder in crtp_commander_generic. What you need to do is to set the setpoint_structure with the correct control values and set the setpoint.

I am still a bit confused about your wording or "sending" commands without the radio, where are the command generated? Can you maybe explain your use-case in a bit higher level terms, ie. what do you want to achieve?
thasu
Member
Posts: 31
Joined: Wed Oct 18, 2017 7:16 am

Re: Accessing the RadioController inputs

Post by thasu »

The commands are generated inside the code as in the figure 8 code. But there we can just give only Vx,Vy,Z and yaw rate and we use the flow deck for that. My point is if we use another sensor system for CF and develop an algorithm to generate commands onboard, how can we input them to the system? As an example our algorithm decides to keep the throttle at 60% for 2 seconds and then go to the hovering mode.

Basically, I need to disable the watchdog and generate the commands inside the algorithm to CF to think like still the radio is connected and giving commands.
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Accessing the RadioController inputs

Post by arnaud »

As I said earlier (in bold :-)), the code I copied in my message is bypassing the radio watchdog by sending setpoint at regular interval using the internal API.

So the code I sent, do disables the watchdog and generates the commands inside the Crazyflie. It looks like that: https://photos.app.goo.gl/ZUD1hXtTZlDIiCNw2, in this video I just switched ON the Crazyflie and there was no radio connection with the Crazyflie, everything is standalone.

If you want to control the crazyflie with different kind of setpoint, all you have to do is fill-up the setpoint structure with the correct data according to your control type. You can look at the setpoint structure definition and its usage in the different commander radio functions, they give examples on how to fill up the structure. For instance if you want to set a thrust in percent, you will have to disable the Z and VZ control and set the thrust in the structure, this is done in crtp_commander_rpy.py for example.
thasu
Member
Posts: 31
Joined: Wed Oct 18, 2017 7:16 am

Re: Accessing the RadioController inputs

Post by thasu »

I got your point. Can you tell me what code part should I include for the "sequence.c" to go to the hover mode when it's needed, because it's more stable than just setting the altitude from the setpoint command.
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Accessing the RadioController inputs

Post by arnaud »

I do not understand your question since I think you should already have the answer in the code I sent.

Just to recap a bit how things work in the Crazyflie:
- You prepare a setpoint by filling up the setpoint structure, this structure contains the required instruction to tell the controller in what mode it should operate
- You set this setpoint using the setSetpoint function
- If the setSetpoint function is not called often enough (more than twice a second), the motors are cut.

To fill up the setpoint structure in the file I send earlier, I copy-pasted the code from the hover mode packet decoder: https://github.com/bitcraze/crazyflie-f ... #L264-L293.

So, sequence.c is essentially already going in hover mode.
Post Reply