roll and pitch Trim

Firmware/software/electronics/mechanics
Post Reply
milou55
Beginner
Posts: 1
Joined: Wed Nov 18, 2015 1:38 pm

roll and pitch Trim

Post by milou55 »

Hi,

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"
At first, the copter was moving to the left and forward, so I modified the roll and pitch trim and now it stays almost still.
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.
Post Reply