Merge remote-tracking branch 'upstream/master' into ros

This commit is contained in:
Thomas Gubler
2015-01-09 08:07:00 +01:00
11 changed files with 150 additions and 33 deletions
+1 -1
Submodule NuttX updated: 255dc96065...dbcccb2455
@@ -0,0 +1,31 @@
#!nsh
#
# HobbyKing SK450 DeadCat modification
#
# Anton Matosov <anton.matosov@gmail.com>
#
sh /etc/init.d/rc.mc_defaults
if [ $AUTOCNF == yes ]
then
param set MC_ROLL_P 6.0
param set MC_ROLLRATE_P 0.04
param set MC_ROLLRATE_I 0.1
param set MC_ROLLRATE_D 0.0015
param set MC_PITCH_P 6.0
param set MC_PITCHRATE_P 0.08
param set MC_PITCHRATE_I 0.2
param set MC_PITCHRATE_D 0.0015
param set MC_YAW_P 2.8
param set MC_YAWRATE_P 0.1
param set MC_YAWRATE_I 0.07
param set MC_YAWRATE_D 0.0
fi
set MIXER sk450_deadcat
set PWM_OUT 1234
set PWM_MIN 1050
+5
View File
@@ -226,6 +226,11 @@ then
sh /etc/init.d/10018_tbs_endurance sh /etc/init.d/10018_tbs_endurance
fi fi
if param compare SYS_AUTOSTART 10019
then
sh /etc/init.d/10019_sk450_deadcat
fi
# #
# Hexa Coaxial # Hexa Coaxial
# #
+3 -1
View File
@@ -164,6 +164,7 @@ then
else else
sh /etc/init.d/rc.autostart sh /etc/init.d/rc.autostart
fi fi
unset MODE
# #
# Override parameters from user configuration file # Override parameters from user configuration file
@@ -185,6 +186,7 @@ then
param set SYS_AUTOCONFIG 0 param set SYS_AUTOCONFIG 0
param save param save
fi fi
unset AUTOCNF
set IO_PRESENT no set IO_PRESENT no
@@ -524,7 +526,7 @@ then
then then
set MAV_TYPE 2 set MAV_TYPE 2
fi fi
if [ $MIXER == quad_w ] if [ $MIXER == quad_w -o $MIXER == sk450_deadcat ]
then then
set MAV_TYPE 2 set MAV_TYPE 2
fi fi
@@ -0,0 +1,25 @@
Multirotor mixer for PX4FMU
===========================
This file defines a single mixer for a quadrotor in SK450 DeadCat configuration. All controls are mixed 100%.
R: 4dc 10000 10000 10000 0
Gimbal / payload mixer for last four channels
-----------------------------------------------------
M: 1
O: 10000 10000 0 -10000 10000
S: 0 4 10000 10000 0 -10000 10000
M: 1
O: 10000 10000 0 -10000 10000
S: 0 5 10000 10000 0 -10000 10000
M: 1
O: 10000 10000 0 -10000 10000
S: 0 6 10000 10000 0 -10000 10000
M: 1
O: 10000 10000 0 -10000 10000
S: 0 7 10000 10000 0 -10000 10000
+53 -20
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
############################################################################ ############################################################################
# #
# Copyright (C) 2012, 2013 PX4 Development Team. All rights reserved. # Copyright (C) 2012-2015 PX4 Development Team. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions
@@ -227,16 +227,21 @@ class uploader(object):
+ uploader.EOC) + uploader.EOC)
self.__getSync() self.__getSync()
# def __trySync(self): def __trySync(self):
# c = self.__recv() try:
# if (c != self.INSYNC): self.port.flush()
# #print("unexpected 0x%x instead of INSYNC" % ord(c)) if (self.__recv() != self.INSYNC):
# return False; #print("unexpected 0x%x instead of INSYNC" % ord(c))
# c = self.__recv() return False;
# if (c != self.OK):
# #print("unexpected 0x%x instead of OK" % ord(c)) if (self.__recv() != self.OK):
# return False #print("unexpected 0x%x instead of OK" % ord(c))
# return True return False
return True
except RuntimeError:
#timeout, no response yet
return False
# send the GET_DEVICE command and wait for an info parameter # send the GET_DEVICE command and wait for an info parameter
def __getInfo(self, param): def __getInfo(self, param):
@@ -261,19 +266,37 @@ class uploader(object):
self.__getSync() self.__getSync()
return value return value
def __drawProgressBar(self, progress, maxVal):
if maxVal < progress:
progress = maxVal
percent = (float(progress) / float(maxVal)) * 100.0
sys.stdout.write("\rprogress:[%-20s] %.2f%%" % ('='*int(percent/5.0), percent))
sys.stdout.flush()
# send the CHIP_ERASE command and wait for the bootloader to become ready # send the CHIP_ERASE command and wait for the bootloader to become ready
def __erase(self): def __erase(self):
self.__send(uploader.CHIP_ERASE self.__send(uploader.CHIP_ERASE
+ uploader.EOC) + uploader.EOC)
# erase is very slow, give it 20s # erase is very slow, give it 20s
deadline = time.time() + 20 deadline = time.time() + 20.0
while time.time() < deadline: while time.time() < deadline:
try:
self.__getSync() #Draw progress bar (erase usually takes about 9 seconds to complete)
return estimatedTimeRemaining = deadline-time.time()
except RuntimeError: if estimatedTimeRemaining > 0:
# we timed out, that's OK self.__drawProgressBar(20.0-estimatedTimeRemaining, 9.0)
continue else:
self.__drawProgressBar(10.0, 10.0)
sys.stdout.write(" (timeout: %d seconds) " % int(time.time()-deadline) )
if self.__trySync():
self.__drawProgressBar(10.0, 10.0)
sys.stdout.write("\nerase complete!\n")
return;
raise RuntimeError("timed out waiting for erase") raise RuntimeError("timed out waiting for erase")
@@ -329,9 +352,18 @@ class uploader(object):
def __program(self, fw): def __program(self, fw):
code = fw.image code = fw.image
groups = self.__split_len(code, uploader.PROG_MULTI_MAX) groups = self.__split_len(code, uploader.PROG_MULTI_MAX)
uploadProgress = 0
for bytes in groups: for bytes in groups:
self.__program_multi(bytes) self.__program_multi(bytes)
#Print upload progress (throttled, so it does not delay upload progress)
uploadProgress += 1
if uploadProgress % 256 == 0:
self.__drawProgressBar(uploadProgress, len(groups))
self.__drawProgressBar(100, 100)
print("\nprogram complete!")
# verify code # verify code
def __verify_v2(self, fw): def __verify_v2(self, fw):
self.__send(uploader.CHIP_VERIFY self.__send(uploader.CHIP_VERIFY
@@ -436,7 +468,6 @@ class uploader(object):
return return
# Detect python version # Detect python version
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
runningPython3 = False runningPython3 = False
@@ -511,8 +542,10 @@ while True:
print("attempting reboot on %s..." % port) print("attempting reboot on %s..." % port)
print("if the board does not respond, unplug and re-plug the USB connector.") print("if the board does not respond, unplug and re-plug the USB connector.")
up.send_reboot() up.send_reboot()
# wait for the reboot, without we might run into Serial I/O Error 5 # wait for the reboot, without we might run into Serial I/O Error 5
time.sleep(0.5) time.sleep(0.5)
# always close the port # always close the port
up.close() up.close()
continue continue
@@ -524,7 +557,7 @@ while True:
except RuntimeError as ex: except RuntimeError as ex:
# print the error # print the error
print("ERROR: %s" % ex.args) print("\nERROR: %s" % ex.args)
finally: finally:
# always close the port # always close the port
+3 -3
View File
@@ -32,9 +32,9 @@ MODULES += drivers/ll40ls
# MODULES += drivers/trone # MODULES += drivers/trone
MODULES += drivers/gps MODULES += drivers/gps
MODULES += drivers/hil MODULES += drivers/hil
MODULES += drivers/hott # MODULES += drivers/hott
MODULES += drivers/hott/hott_telemetry # MODULES += drivers/hott/hott_telemetry
MODULES += drivers/hott/hott_sensors # MODULES += drivers/hott/hott_sensors
# MODULES += drivers/blinkm # MODULES += drivers/blinkm
MODULES += drivers/airspeed MODULES += drivers/airspeed
MODULES += drivers/ets_airspeed MODULES += drivers/ets_airspeed
+1 -1
View File
@@ -389,7 +389,7 @@ CONFIG_ARCH_BOARD=""
# #
CONFIG_NSH_MMCSDMINOR=0 CONFIG_NSH_MMCSDMINOR=0
CONFIG_NSH_MMCSDSLOTNO=0 CONFIG_NSH_MMCSDSLOTNO=0
CONFIG_MMCSD_HAVE_SDIOWAIT_WRCOMPLETE=y
# #
# Board-Specific Options # Board-Specific Options
# #
+2 -1
View File
@@ -441,7 +441,6 @@ private:
SimpleMixer operator=(const SimpleMixer&); SimpleMixer operator=(const SimpleMixer&);
}; };
/** /**
* Supported multirotor geometries. * Supported multirotor geometries.
* *
@@ -460,12 +459,14 @@ class __EXPORT MultirotorMixer : public Mixer
{ {
public: public:
/** /**
* Precalculated rotor mix. * Precalculated rotor mix.
*/ */
struct Rotor { struct Rotor {
float roll_scale; /**< scales roll for this rotor */ float roll_scale; /**< scales roll for this rotor */
float pitch_scale; /**< scales pitch for this rotor */ float pitch_scale; /**< scales pitch for this rotor */
float yaw_scale; /**< scales yaw for this rotor */ float yaw_scale; /**< scales yaw for this rotor */
float out_scale; /**< scales total out for this rotor */
}; };
/** /**
@@ -75,7 +75,8 @@ float constrain(float val, float min, float max)
{ {
return (val < min) ? min : ((val > max) ? max : val); return (val < min) ? min : ((val > max) ? max : val);
} }
}
} // anonymous namespace
MultirotorMixer::MultirotorMixer(ControlCallback control_cb, MultirotorMixer::MultirotorMixer(ControlCallback control_cb,
uintptr_t cb_handle, uintptr_t cb_handle,
@@ -89,6 +90,7 @@ MultirotorMixer::MultirotorMixer(ControlCallback control_cb,
_pitch_scale(pitch_scale), _pitch_scale(pitch_scale),
_yaw_scale(yaw_scale), _yaw_scale(yaw_scale),
_idle_speed(-1.0f + idle_speed * 2.0f), /* shift to output range here to avoid runtime calculation */ _idle_speed(-1.0f + idle_speed * 2.0f), /* shift to output range here to avoid runtime calculation */
_limits_pub(),
_rotor_count(_config_rotor_count[(MultirotorGeometryUnderlyingType)geometry]), _rotor_count(_config_rotor_count[(MultirotorGeometryUnderlyingType)geometry]),
_rotors(_config_index[(MultirotorGeometryUnderlyingType)geometry]) _rotors(_config_index[(MultirotorGeometryUnderlyingType)geometry])
{ {
@@ -152,6 +154,9 @@ MultirotorMixer::from_text(Mixer::ControlCallback control_cb, uintptr_t cb_handl
} else if (!strcmp(geomname, "4w")) { } else if (!strcmp(geomname, "4w")) {
geometry = MultirotorGeometry::QUAD_WIDE; geometry = MultirotorGeometry::QUAD_WIDE;
} else if (!strcmp(geomname, "4dc")) {
geometry = MultirotorGeometry::QUAD_DEADCAT;
} else if (!strcmp(geomname, "6+")) { } else if (!strcmp(geomname, "6+")) {
geometry = MultirotorGeometry::HEX_PLUS; geometry = MultirotorGeometry::HEX_PLUS;
@@ -212,6 +217,8 @@ MultirotorMixer::mix(float *outputs, unsigned space)
pitch * _rotors[i].pitch_scale + pitch * _rotors[i].pitch_scale +
thrust; thrust;
out *= _rotors[i].out_scale;
/* limit yaw if it causes outputs clipping */ /* limit yaw if it causes outputs clipping */
if (out >= 0.0f && out < -yaw * _rotors[i].yaw_scale) { if (out >= 0.0f && out < -yaw * _rotors[i].yaw_scale) {
yaw = -out / _rotors[i].yaw_scale; yaw = -out / _rotors[i].yaw_scale;
+17 -4
View File
@@ -69,6 +69,13 @@ quad_plus = [
[ 180, CW], [ 180, CW],
] ]
quad_deadcat = [
[ 63, CCW, 1.0],
[-135, CCW, 0.964],
[ -63, CW, 1.0],
[ 135, CW, 0.964],
]
quad_v = [ quad_v = [
[ 18.8, 0.4242], [ 18.8, 0.4242],
[ -18.8, 1.0], [ -18.8, 1.0],
@@ -148,13 +155,18 @@ twin_engine = [
[-90, 0.0], [-90, 0.0],
] ]
tables = [quad_x, quad_plus, quad_v, quad_wide, quad_deadcat, hex_x, hex_plus, hex_cox, octa_x, octa_plus, octa_cox, twin_engine]
def variableName(variable): def variableName(variable):
for variableName, value in list(globals().items()): for variableName, value in list(globals().items()):
if value is variable: if value is variable:
return variableName return variableName
tables = [quad_x, quad_plus, quad_v, quad_wide, hex_x, hex_plus, hex_cox, octa_x, octa_plus, octa_cox, twin_engine] def unpackScales(scalesList):
if len(scalesList) == 2:
scalesList += [1.0] #Add thrust scale
return scalesList
def printEnum(): def printEnum():
print("enum class MultirotorGeometry : MultirotorGeometryUnderlyingType {") print("enum class MultirotorGeometry : MultirotorGeometryUnderlyingType {")
@@ -167,10 +179,11 @@ def printEnum():
def printScaleTables(): def printScaleTables():
for table in tables: for table in tables:
print("const MultirotorMixer::Rotor _config_{}[] = {{".format(variableName(table))) print("const MultirotorMixer::Rotor _config_{}[] = {{".format(variableName(table)))
for (angle, yawScale) in table: for row in table:
angle, yawScale, thrustScale = unpackScales(row)
rollScale = rcos(angle + 90) rollScale = rcos(angle + 90)
pitchScale = rcos(angle) pitchScale = rcos(angle)
print("\t{{ {:9f}, {:9f}, {:9f} }},".format(rollScale, pitchScale, yawScale)) print("\t{{ {:9f}, {:9f}, {:9f}, {:9f} }},".format(rollScale, pitchScale, yawScale, thrustScale))
print("};\n") print("};\n")
def printScaleTablesIndex(): def printScaleTablesIndex():