I have a few questions about Roll and Pitch Trim.
I'm trying to fly my CF2. I modified the example program "ramp.py" to just take off and stabilize in the air:
Code: Select all
# -*- coding: utf-8 -*-
#
#
"""Tabulation = 4"""
#
# || ____ _ __
# +------+ / __ )(_) /_______________ _____ ___
# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
#
# Copyright (C) 2014 Bitcraze AB
#
# Crazyflie Nano Quadcopter Client
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
"""
Simple example that connects to the first Crazyflie found, ramps up/down
the motors and disconnects.
"""
import time, sys, os, select
from threading import Thread
#FIXME: Has to be launched from within the example folder
sys.path.append("../lib")
import cflib
from cflib.crazyflie import Crazyflie
import cflib.crtp # noqa
from cfclient.utils.logconfigreader import LogConfig # noqa
import logging
from threading import Timer
logging.basicConfig(level=logging.ERROR)
class MotorRampExample:
"""Example that connects to a Crazyflie and ramps the motors up/down and
the disconnects"""
def __init__(self, link_uri):
""" Initialize and run the example with the specified link_uri """
self._cf = Crazyflie()
self._cf.connected.add_callback(self._connected)
self._cf.disconnected.add_callback(self._disconnected)
self._cf.connection_failed.add_callback(self._connection_failed)
self._cf.connection_lost.add_callback(self._connection_lost)
self._cf.open_link(link_uri)
print "Connecting to %s" % link_uri
def _connected(self, link_uri):
""" This callback is called form the Crazyflie API when a Crazyflie
has been connected and the TOCs have been downloaded."""
# The definition of the logconfig can be made before connecting
self._lg_stab = LogConfig(name="Stabilizer", period_in_ms=1000)
self._lg_stab.add_variable("stabilizer.roll", "float")
self._lg_stab.add_variable("stabilizer.pitch", "float")
self._lg_stab.add_variable("stabilizer.yaw", "float")
# Log Barometer
self._lg_baro = LogConfig(name="Barometer", period_in_ms=1000)
self._lg_baro.add_variable("baro.temp", "float")
self._lg_baro.add_variable("baro.asl", "float")
self._lg_baro.add_variable("baro.pressure", "float")
# Start a separate thread to do the motor test.
# Do not hijack the calling thread!
Thread(target=self._ramp_motors).start()
Thread(target=self._logging).start()
def _connection_failed(self, link_uri, msg):
"""Callback when connection initial connection fails (i.e no Crazyflie
at the specified address)"""
print "Connection to %s failed: %s" % (link_uri, msg)
def _connection_lost(self, link_uri, msg):
"""Callback when disconnected after a connection has been made (i.e
Crazyflie moves out of range)"""
print "Connection to %s lost: %s" % (link_uri, msg)
def _disconnected(self, link_uri):
"""Callback when the Crazyflie is disconnected (called in all cases)"""
print "Disconnected from %s" % link_uri
def _logging(self):
try:
self._cf.log.add_config(self._lg_stab)
self._lg_stab.data_received_cb.add_callback(self._log_data)
self._lg_stab.error_cb.add_callback(self._log_error)
self._cf.log.add_config(self._lg_baro)
self._lg_baro.data_received_cb.add_callback(self._log_data)
self._lg_baro.error_cb.add_callback(self._log_error)
print("start logging")
self._lg_stab.start()
self._lg_baro.start()
except KeyError as e:
print("Could not start log configuration,"
"{} not found in TOC".format(str(e)))
except AttributeError:
print("Could not add log config, bad configuration.")
def _ramp_motors(self):
thrust_mult = 1
thrust_step = 500
#thrust = 10000
thrust = 38000
pitch = 0
roll = 0
yawrate = 0
hold=0
#Unlock startup thrust protection
self._cf.commander.send_setpoint(0, 0, 0, 0)
#os.system('cls' if os.name == 'nt' else 'clear')
print("Press enter to stop")
while 1:
self._cf.commander.send_setpoint(roll, pitch, yawrate, thrust)
time.sleep(0.1)
if hold==0:
thrust += thrust_step * thrust_mult
#if thrust >= 12000:
if thrust >= 40500:
hold = 1
if hold==1:
#thrust = 10000
thrust = 32767
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
line = raw_input()
break
self._cf.commander.send_setpoint(0, 0, 0, 0)
# Make sure that the last packet leaves before the link is closed
# since the message queue is not flushed before closing
time.sleep(0.1)
self._cf.close_link()
def _log_error(self, logconf, msg):
"""Callback from the log API when an error occurs"""
print("Error when logging %s: %s" % (logconf.name, msg))
def _log_data(self, timestamp, data, logconf):
"""Callback froma the log API when data arrives"""
print("[%d][%s]: %s" % (timestamp, logconf.name, data))
if __name__ == '__main__':
# Initialize the low-level drivers (don't list the debug drivers)
cflib.crtp.init_drivers(enable_debug_driver=False)
# Scan for Crazyflies and use the first one found
print "Scanning interfaces for Crazyflies..."
available = cflib.crtp.scan_interfaces()
print "Crazyflies found:"
for i in available:
print i[0]
if len(available) > 0:
le = MotorRampExample(available[0][0])
else:
print "No Crazyflies found, cannot run example"
But I'm wondering why I need to adjust the trim. What does the trim really change ? Is it because the accelerometer isn't well calibrated ? Can we re-calibrate ?
If I use an other Crazyflie, I need to set other trim values because it's specific to each copter. Is there a way to auto-adjust the trim with a self calibration test or something ? Because right now I just change the trim, try if it works better, and do it until it works fine. It's okay because I only have 2 copters, but if I need to set the trim for 50 copters, it becomes difficult, I need to set a different trim for each one and it takes a lot of time.
One more question: I looked inside the firmware code, but I didn't find where the trim is used.
thanks in advance for your answer.