firmware to emulate controller

Firmware/software/electronics/mechanics
Post Reply
almaz_1c
Member
Posts: 43
Joined: Tue Dec 09, 2014 12:58 pm

firmware to emulate controller

Post by almaz_1c »

Hello! I have crazyflie quadcopter but don't have any controller like Xbox 360 or Playstation 3.
But i want to switch on balancing of PID controllers.
My i idea - i place the motors M1 and M3 sholders on any handhold and make to balancing M2 and M4 shoulders in air.
So is someone can point me how to modify firmware to switch on PID controlled balancing? Emulate RX commands or any other way to do it.
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: firmware to emulate controller

Post by arnaud »

Hi,
You can see and modify the PID parameters from the PC client in the parameter tabs. To modify the firmware in itself you will need to download the source-code from github, modify it and flash your modified version (this can be done with the radio bootloader).

The easiest to get started is to use the virtualmachine: http://wiki.bitcraze.se/projects:virtualmachine:index

The code you are looking for is in/around stabilizer.c: https://github.com/bitcraze/crazyflie-f ... zer.c#L240
This task is responsible for running the PIDs and controlling the motors.
almaz_1c
Member
Posts: 43
Joined: Tue Dec 09, 2014 12:58 pm

Re: firmware to emulate controller

Post by almaz_1c »

Thank you arnaud! You right!
It is very easy - i modify stabilizerTask as you said and now my quadcopter balancing after power on!

Code: Select all

static void stabilizerTask(void* param)
{
  uint32_t attitudeCounter = 0;
  uint32_t altHoldCounter = 0;
  uint32_t lastWakeTime;

  vTaskSetApplicationTaskTag(0, (void*)TASK_STABILIZER_ID_NBR);

  motorsSetRatio(0, 10000);
  motorsSetRatio(1, 10000);
  motorsSetRatio(2, 10000);
  motorsSetRatio(3, 10000);
  //Wait for the system to be fully started to start stabilization loop
  systemWaitStart();

  lastWakeTime = xTaskGetTickCount ();

  int al_counter = 0;
  float al_x, al_y, al_z;
  while(1)
  {
    vTaskDelayUntil(&lastWakeTime, F2T(IMU_UPDATE_FREQ)); // 500Hz
	al_counter++;

    // Magnetometer not yet used more then for logging.
    imu9Read(&gyro, &acc, &mag);

    if (imu6IsCalibrated())
    {
//       commanderGetRPY(&eulerRollDesired, &eulerPitchDesired, &eulerYawDesired);
      eulerRollDesired = 0.0;
	  eulerPitchDesired = 0,0;
	  eulerYawDesired = 0.0;
      commanderGetRPYType(&rollType, &pitchType, &yawType);

      // 250HZ
      if (++attitudeCounter >= ATTITUDE_UPDATE_RATE_DIVIDER)
      {
        sensfusion6UpdateQ(gyro.x, gyro.y, gyro.z, acc.x, acc.y, acc.z, FUSION_UPDATE_DT);
        sensfusion6GetEulerRPY(&eulerRollActual, &eulerPitchActual, &eulerYawActual);

// 		gyro_angle_count( gyro.x, gyro.y, gyro.z, FUSION_UPDATE_DT);
// 		al_x = gyro_angle_X_get();
// 		al_y = gyro_angle_Y_get();
// 		al_z = gyro_angle_Z_get();
// 		DEBUG_PRINT("%d, %f, %f\n", al_counter,
// 										eulerRollActual,
// 										al_x
// 				);
        accWZ = sensfusion6GetAccZWithoutGravity(acc.x, acc.y, acc.z);
        accMAG = (acc.x*acc.x) + (acc.y*acc.y) + (acc.z*acc.z);
        // Estimate speed from acc (drifts)
        vSpeed += deadband(accWZ, vAccDeadband) * FUSION_UPDATE_DT;

        controllerCorrectAttitudePID(eulerRollActual, eulerPitchActual, eulerYawActual,
                                     eulerRollDesired, eulerPitchDesired, -eulerYawDesired,
                                     &rollRateDesired, &pitchRateDesired, &yawRateDesired);
        attitudeCounter = 0;
      }

      // 100HZ
      if (imuHasBarometer() && (++altHoldCounter >= ALTHOLD_UPDATE_RATE_DIVIDER))
      {
        stabilizerAltHoldUpdate();
        altHoldCounter = 0;
      }

      if (rollType == RATE)
      {
        rollRateDesired = eulerRollDesired;
      }
      if (pitchType == RATE)
      {
        pitchRateDesired = eulerPitchDesired;
      }
      if (yawType == RATE)
      {
        yawRateDesired = -eulerYawDesired;
      }

      // TODO: Investigate possibility to subtract gyro drift.
      controllerCorrectRatePID(gyro.x, -gyro.y, gyro.z,
                               rollRateDesired, pitchRateDesired, yawRateDesired);

      controllerGetActuatorOutput(&actuatorRoll, &actuatorPitch, &actuatorYaw);

      if (!altHold || !imuHasBarometer())
      {
        // Use thrust from controller if not in altitude hold mode
//         commanderGetThrust(&actuatorThrust);
			actuatorThrust = 10000;
      }
      else
      {
        // Added so thrust can be set to 0 while in altitude hold mode after disconnect
        commanderWatchdog();
      }

      if (actuatorThrust > 0)
      {
#if defined(TUNE_ROLL)
        distributePower(actuatorThrust, actuatorRoll, 0, 0);
#elif defined(TUNE_PITCH)
        distributePower(actuatorThrust, 0, actuatorPitch, 0);
#elif defined(TUNE_YAW)
        distributePower(actuatorThrust, 0, 0, -actuatorYaw);
#else
        distributePower(actuatorThrust, actuatorRoll, actuatorPitch, -actuatorYaw);
#endif
      }
      else
      {
        distributePower(0, 0, 0, 0);
        controllerResetAllPID();
      }
    }
  }
}
Post Reply