mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-03-15 07:29:15 +01:00
Merge remote-tracking branch 'origin/next' into samguns/zh_CN_GCS
This commit is contained in:
commit
9344351665
117
Makefile
117
Makefile
@ -135,6 +135,9 @@ all_clean:
|
||||
@$(ECHO) " CLEAN $(call toprel, $(BUILD_DIR))"
|
||||
$(V1) [ ! -d "$(BUILD_DIR)" ] || $(RM) -rf "$(BUILD_DIR)"
|
||||
|
||||
.PONY: clean
|
||||
clean: all_clean
|
||||
|
||||
$(DL_DIR):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
@ -144,6 +147,12 @@ $(TOOLS_DIR):
|
||||
$(BUILD_DIR):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
$(PACKAGE_DIR):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
$(DIST_DIR):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
##############################
|
||||
#
|
||||
# UAVObjects
|
||||
@ -243,8 +252,8 @@ EF_TARGETS := $(addprefix ef_, $(EF_BOARDS))
|
||||
# When building any of the "all_*" targets, tell all sub makefiles to display
|
||||
# additional details on each line of output to describe which build and target
|
||||
# that each line applies to. The same applies also to all, opfw_resource,
|
||||
# package and clean_package targets
|
||||
ifneq ($(strip $(filter all_% all opfw_resource package clean_package,$(MAKECMDGOALS))),)
|
||||
# package targets
|
||||
ifneq ($(strip $(filter all_% all opfw_resource package,$(MAKECMDGOALS))),)
|
||||
export ENABLE_MSG_EXTRA := yes
|
||||
endif
|
||||
|
||||
@ -766,51 +775,29 @@ $(OPFW_RESOURCE): $(FW_TARGETS)
|
||||
$(V1) $(ECHO) $(QUOTE)$(OPFW_CONTENTS)$(QUOTE) > $@
|
||||
|
||||
# If opfw_resource or all firmware are requested, GCS should depend on the resource
|
||||
ifneq ($(strip $(filter opfw_resource all all_fw all_flight,$(MAKECMDGOALS))),)
|
||||
ifneq ($(strip $(filter opfw_resource all all_fw all_flight package,$(MAKECMDGOALS))),)
|
||||
$(eval openpilotgcs_qmake: $(OPFW_RESOURCE))
|
||||
endif
|
||||
|
||||
# Packaging targets: package, clean_package
|
||||
# - removes build directory (clean_package only)
|
||||
# Packaging targets: package
|
||||
# - builds all firmware, opfw_resource, gcs
|
||||
# - copies firmware into a package directory
|
||||
# - calls paltform-specific packaging script
|
||||
|
||||
# Do some checks and define some values if package is requested
|
||||
ifneq ($(strip $(filter package clean_package,$(MAKECMDGOALS))),)
|
||||
# Define some variables
|
||||
export PACKAGE_LBL := $(shell $(VERSION_INFO) --format=\$${LABEL})
|
||||
export PACKAGE_NAME := OpenPilot
|
||||
export PACKAGE_SEP := -
|
||||
|
||||
# We can only package release builds
|
||||
ifneq ($(GCS_BUILD_CONF),release)
|
||||
$(error Packaging is currently supported for release builds only)
|
||||
endif
|
||||
|
||||
# Packaged GCS should depend on opfw_resource
|
||||
ifneq ($(strip $(filter package clean_package,$(MAKECMDGOALS))),)
|
||||
$(eval openpilotgcs_qmake: $(OPFW_RESOURCE))
|
||||
endif
|
||||
|
||||
# Clean the build directory if clean_package is requested
|
||||
ifneq ($(strip $(filter clean_package,$(MAKECMDGOALS))),)
|
||||
$(info Cleaning build directory before packaging...)
|
||||
ifneq ($(shell $(MAKE) all_clean >/dev/null 2>&1 && $(ECHO) "clean"), clean)
|
||||
$(error Cannot clean build directory)
|
||||
endif
|
||||
|
||||
.PHONY: clean_package
|
||||
clean_package: package
|
||||
endif
|
||||
endif
|
||||
# Define some variables
|
||||
export PACKAGE_LBL := $(shell $(VERSION_INFO) --format=\$${LABEL})
|
||||
export PACKAGE_NAME := OpenPilot
|
||||
export PACKAGE_SEP := -
|
||||
|
||||
.PHONY: package
|
||||
package: all_fw all_ground uavobjects_matlab
|
||||
@$(ECHO) "Packaging for $(UNAME) $(ARCH) into $(call toprel, $(PACKAGE_DIR)) directory"
|
||||
$(V1) [ ! -d "$(PACKAGE_DIR)" ] || $(RM) -rf "$(PACKAGE_DIR)"
|
||||
$(V1) $(MKDIR) -p "$(PACKAGE_DIR)"
|
||||
$(MAKE) --no-print-directory -C $(ROOT_DIR)/package --file=$(UNAME).mk $@
|
||||
|
||||
include $(ROOT_DIR)/package/$(UNAME).mk
|
||||
|
||||
package: all_fw all_ground uavobjects_matlab $(PACKAGE_DIR)
|
||||
ifneq ($(GCS_BUILD_CONF),release)
|
||||
# We can only package release builds
|
||||
$(error Packaging is currently supported for release builds only)
|
||||
endif
|
||||
|
||||
##############################
|
||||
#
|
||||
@ -893,60 +880,23 @@ build-info:
|
||||
#
|
||||
##############################
|
||||
|
||||
DIST_VER_INFO := $(DIST_DIR)/version-info.json
|
||||
|
||||
.PHONY: $(DIST_VER_INFO) # Because to many deps to list
|
||||
$(DIST_VER_INFO): $(DIST_DIR)
|
||||
$(V1) $(VERSION_INFO) --jsonpath="$(DIST_DIR)"
|
||||
|
||||
.PHONY: dist
|
||||
dist:
|
||||
dist: $(DIST_DIR) $(DIST_VER_INFO)
|
||||
@$(ECHO) " SOURCE FOR DISTRIBUTION $(call toprel, $(DIST_DIR))"
|
||||
$(V1) $(MKDIR) -p "$(DIST_DIR)"
|
||||
$(V1) $(VERSION_INFO) \
|
||||
--jsonpath="$(DIST_DIR)"
|
||||
$(eval DIST_NAME := $(call toprel, "$(DIST_DIR)/OpenPilot-$(shell git describe).tar"))
|
||||
$(V1) git archive --prefix="OpenPilot/" -o "$(DIST_NAME)" HEAD
|
||||
$(V1) tar --append --file="$(DIST_NAME)" \
|
||||
--transform='s,.*version-info.json,OpenPilot/version-info.json,' \
|
||||
$(call toprel, "$(DIST_DIR)/version-info.json")
|
||||
$(call toprel, "$(DIST_VER_INFO)")
|
||||
$(V1) gzip -f "$(DIST_NAME)"
|
||||
|
||||
|
||||
|
||||
##############################
|
||||
#
|
||||
# Install OpenPilot
|
||||
#
|
||||
##############################
|
||||
prefix := /usr/local
|
||||
bindir := $(prefix)/bin
|
||||
libdir := $(prefix)/lib
|
||||
datadir := $(prefix)/share
|
||||
|
||||
INSTALL = cp -a --no-preserve=ownership
|
||||
LN = ln
|
||||
LN_S = ln -s
|
||||
|
||||
ifeq ($(MAKECMDGOALS), install)
|
||||
ifneq ($(UNAME), Linux)
|
||||
$(error install only supported for Linux)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
@$(ECHO) " INSTALLING GCS TO $(DESTDIR)/)"
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(bindir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(libdir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/applications
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/pixmaps
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(udevdir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/bin/openpilotgcs $(DESTDIR)$(bindir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/bin/udp_test $(DESTDIR)$(bindir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/lib/openpilotgcs $(DESTDIR)$(libdir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/share/openpilotgcs $(DESTDIR)$(datadir)
|
||||
$(V1) $(INSTALL) $(ROOT_DIR)/package/linux/openpilot.desktop $(DESTDIR)$(datadir)/applications
|
||||
$(V1) $(INSTALL) $(ROOT_DIR)/package/linux/openpilot.png $(DESTDIR)$(datadir)/pixmaps
|
||||
$(V1) rm $(DESTDIR)/$(datadir)/openpilotgcs/translations/Makefile
|
||||
|
||||
|
||||
##############################
|
||||
#
|
||||
# Help message, the default Makefile goal
|
||||
@ -1079,7 +1029,6 @@ help:
|
||||
@$(ECHO) " Supported groups are ($(UAVOBJ_TARGETS))"
|
||||
@$(ECHO)
|
||||
@$(ECHO) " [Packaging]"
|
||||
@$(ECHO) " clean_package - Clean, build and package the OpenPilot platform-dependent package"
|
||||
@$(ECHO) " package - Build and package the OpenPilot platform-dependent package (no clean)"
|
||||
@$(ECHO) " opfw_resource - Generate resources to embed firmware binaries into the GCS"
|
||||
@$(ECHO) " dist - Generate source archive for distribution"
|
||||
|
BIN
artwork/3D Model/multi/blackout/BlackoutMiniHQuad.3DS
Executable file
BIN
artwork/3D Model/multi/blackout/BlackoutMiniHQuad.3DS
Executable file
Binary file not shown.
BIN
artwork/3D Model/multi/blackout/BlackoutMiniHQuad.jpg
Executable file
BIN
artwork/3D Model/multi/blackout/BlackoutMiniHQuad.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
artwork/3D Model/multi/blackout/TEXTURE.PNG
Executable file
BIN
artwork/3D Model/multi/blackout/TEXTURE.PNG
Executable file
Binary file not shown.
After Width: | Height: | Size: 949 KiB |
@ -32,6 +32,9 @@
|
||||
|
||||
#include <systemalarms.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utlist.h>
|
||||
|
||||
typedef enum {
|
||||
FRAME_TYPE_MULTIROTOR,
|
||||
FRAME_TYPE_HELI,
|
||||
@ -40,6 +43,8 @@ typedef enum {
|
||||
FRAME_TYPE_CUSTOM,
|
||||
} FrameType_t;
|
||||
|
||||
typedef SystemAlarmsExtendedAlarmStatusOptions (SANITYCHECK_CustomHook_function)();
|
||||
|
||||
#define SANITYCHECK_STATUS_ERROR_NONE SYSTEMALARMS_EXTENDEDALARMSTATUS_NONE
|
||||
#define SANITYCHECK_STATUS_ERROR_FLIGHTMODE SYSTEMALARMS_EXTENDEDALARMSTATUS_FLIGHTMODE
|
||||
|
||||
@ -55,4 +60,16 @@ extern int32_t configuration_check();
|
||||
|
||||
extern FrameType_t GetCurrentFrameType();
|
||||
|
||||
/**
|
||||
* Attach a custom hook to the sanity check process
|
||||
* @param hook a custom hook function
|
||||
*/
|
||||
extern void SANITYCHECK_AttachHook(SANITYCHECK_CustomHook_function *hook);
|
||||
|
||||
/**
|
||||
* Detach a custom hook to the sanity check process
|
||||
* @param hook a custom hook function
|
||||
*/
|
||||
extern void SANITYCHECK_DetachHook(SANITYCHECK_CustomHook_function *hook);
|
||||
|
||||
#endif /* SANITYCHECK_H */
|
||||
|
37
flight/libraries/inc/sha1.h
Normal file
37
flight/libraries/inc/sha1.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* $NetBSD: sha1.h,v 1.14 2009/11/06 20:31:19 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* SHA-1 in C
|
||||
* By Steve Reid <steve@edmweb.com>
|
||||
* 100% Public Domain
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SHA1_H_
|
||||
#define _SYS_SHA1_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define SHA1_DIGEST_LENGTH 20
|
||||
#define SHA1_DIGEST_STRING_LENGTH 41
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[5];
|
||||
uint32_t count[2];
|
||||
uint8_t buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
__BEGIN_DECLS
|
||||
void SHA1Transform(uint32_t[5], const uint8_t[64]);
|
||||
void SHA1Init(SHA1_CTX *);
|
||||
void SHA1Update(SHA1_CTX *, const uint8_t *, unsigned int);
|
||||
void SHA1Final(uint8_t[SHA1_DIGEST_LENGTH], SHA1_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA1End(SHA1_CTX *, char *);
|
||||
char *SHA1FileChunk(const char *, char *, off_t, off_t);
|
||||
char *SHA1File(const char *, char *);
|
||||
char *SHA1Data(const uint8_t *, size_t, char *);
|
||||
#endif /* _KERNEL */
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _SYS_SHA1_H_ */
|
@ -45,10 +45,18 @@
|
||||
// a number of useful macros
|
||||
#define ADDSEVERITY(check) severity = (severity != SYSTEMALARMS_ALARM_OK ? severity : ((check) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_CRITICAL))
|
||||
|
||||
// private types
|
||||
typedef struct SANITYCHECK_CustomHookInstance {
|
||||
SANITYCHECK_CustomHook_function *hook;
|
||||
struct SANITYCHECK_CustomHookInstance *next;
|
||||
bool enabled;
|
||||
} SANITYCHECK_CustomHookInstance;
|
||||
|
||||
// ! Check a stabilization mode switch position for safety
|
||||
static bool check_stabilization_settings(int index, bool multirotor, bool coptercontrol, bool gpsassisted);
|
||||
|
||||
SANITYCHECK_CustomHookInstance *hooks = 0;
|
||||
|
||||
/**
|
||||
* Run a preflight check over the hardware configuration
|
||||
* and currently active modules
|
||||
@ -176,6 +184,20 @@ int32_t configuration_check()
|
||||
severity = SYSTEMALARMS_ALARM_WARNING;
|
||||
}
|
||||
|
||||
// query sanity check hooks
|
||||
if (severity == SYSTEMALARMS_ALARM_OK) {
|
||||
SANITYCHECK_CustomHookInstance *instance = NULL;
|
||||
LL_FOREACH(hooks, instance) {
|
||||
if (instance->enabled) {
|
||||
alarmstatus = instance->hook();
|
||||
if (alarmstatus != SYSTEMALARMS_EXTENDEDALARMSTATUS_NONE) {
|
||||
severity = SYSTEMALARMS_ALARM_WARNING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (severity != SYSTEMALARMS_ALARM_OK) {
|
||||
ExtendedAlarmsSet(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION, severity, alarmstatus, alarmsubstatus);
|
||||
} else {
|
||||
@ -270,6 +292,7 @@ static bool check_stabilization_settings(int index, bool multirotor, bool copter
|
||||
// and is the same for STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL
|
||||
// (this is checked at compile time by static constraint manualcontrol.h)
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -314,3 +337,39 @@ FrameType_t GetCurrentFrameType()
|
||||
// anyway it should not reach here
|
||||
return FRAME_TYPE_CUSTOM;
|
||||
}
|
||||
|
||||
void SANITYCHECK_AttachHook(SANITYCHECK_CustomHook_function *hook)
|
||||
{
|
||||
PIOS_Assert(hook);
|
||||
SANITYCHECK_CustomHookInstance *instance = NULL;
|
||||
|
||||
// Check whether there is an existing instance and enable it
|
||||
LL_FOREACH(hooks, instance) {
|
||||
if (instance->hook == hook) {
|
||||
instance->enabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No existing instance found, attach this new one
|
||||
instance = (SANITYCHECK_CustomHookInstance *)pios_malloc(sizeof(SANITYCHECK_CustomHookInstance));
|
||||
PIOS_Assert(instance);
|
||||
instance->hook = hook;
|
||||
instance->next = NULL;
|
||||
instance->enabled = true;
|
||||
LL_APPEND(hooks, instance);
|
||||
}
|
||||
|
||||
void SANITYCHECK_DetachHook(SANITYCHECK_CustomHook_function *hook)
|
||||
{
|
||||
if (!hooks) {
|
||||
return;
|
||||
}
|
||||
SANITYCHECK_CustomHookInstance *instance = NULL;
|
||||
LL_FOREACH(hooks, instance) {
|
||||
if (instance->hook == hook) {
|
||||
instance->enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
279
flight/libraries/sha1.c
Normal file
279
flight/libraries/sha1.c
Normal file
@ -0,0 +1,279 @@
|
||||
/* $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ */
|
||||
/* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */
|
||||
|
||||
/*
|
||||
* SHA-1 in C
|
||||
* By Steve Reid <steve@edmweb.com>
|
||||
* 100% Public Domain
|
||||
*
|
||||
* Test Vectors (from FIPS PUB 180-1)
|
||||
* "abc"
|
||||
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
* A million repetitions of "a"
|
||||
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#define SHA1HANDSOFF /* Copies data before messing with it. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if defined(_KERNEL) || defined(_STANDALONE)
|
||||
__KERNEL_RCSID(0, "$NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $");
|
||||
|
||||
#include <lib/libkern/libkern.h>
|
||||
|
||||
#else
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
// #include "namespace.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sha1.h>
|
||||
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#if !HAVE_SHA1_H
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
/*
|
||||
* blk0() and blk() perform the initial expand.
|
||||
* I got the idea of expanding during the round function from SSLeay
|
||||
*/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define blk0(i) \
|
||||
(block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \
|
||||
| (rol(block->l[i], 8) & 0x00FF00FF))
|
||||
#else
|
||||
# define blk0(i) block->l[i]
|
||||
#endif
|
||||
#define blk(i) \
|
||||
(block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] \
|
||||
^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
|
||||
|
||||
/*
|
||||
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
|
||||
*/
|
||||
#define R0(v, w, x, y, z, i) z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30);
|
||||
#define R1(v, w, x, y, z, i) z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30);
|
||||
#define R2(v, w, x, y, z, i) z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
|
||||
#define R3(v, w, x, y, z, i) z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30);
|
||||
#define R4(v, w, x, y, z, i) z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); w = rol(w, 30);
|
||||
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#if defined(__weak_alias)
|
||||
__weak_alias(SHA1Transform, _SHA1Transform)
|
||||
__weak_alias(SHA1Init, _SHA1Init)
|
||||
__weak_alias(SHA1Update, _SHA1Update)
|
||||
__weak_alias(SHA1Final, _SHA1Final)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint8_t c[64];
|
||||
uint32_t l[16];
|
||||
} CHAR64LONG16;
|
||||
|
||||
/* old sparc64 gcc could not compile this */
|
||||
#undef SPARC64_GCC_WORKAROUND
|
||||
#if defined(__sparc64__) && defined(__GNUC__) && __GNUC__ < 3
|
||||
#define SPARC64_GCC_WORKAROUND
|
||||
#endif
|
||||
|
||||
#ifdef SPARC64_GCC_WORKAROUND
|
||||
void do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
|
||||
void do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
|
||||
void do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
|
||||
void do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
|
||||
|
||||
#define nR0(v, w, x, y, z, i) R0(*v, *w, *x, *y, *z, i)
|
||||
#define nR1(v, w, x, y, z, i) R1(*v, *w, *x, *y, *z, i)
|
||||
#define nR2(v, w, x, y, z, i) R2(*v, *w, *x, *y, *z, i)
|
||||
#define nR3(v, w, x, y, z, i) R3(*v, *w, *x, *y, *z, i)
|
||||
#define nR4(v, w, x, y, z, i) R4(*v, *w, *x, *y, *z, i)
|
||||
|
||||
void do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
|
||||
{
|
||||
nR0(a, b, c, d, e, 0); nR0(e, a, b, c, d, 1); nR0(d, e, a, b, c, 2); nR0(c, d, e, a, b, 3);
|
||||
nR0(b, c, d, e, a, 4); nR0(a, b, c, d, e, 5); nR0(e, a, b, c, d, 6); nR0(d, e, a, b, c, 7);
|
||||
nR0(c, d, e, a, b, 8); nR0(b, c, d, e, a, 9); nR0(a, b, c, d, e, 10); nR0(e, a, b, c, d, 11);
|
||||
nR0(d, e, a, b, c, 12); nR0(c, d, e, a, b, 13); nR0(b, c, d, e, a, 14); nR0(a, b, c, d, e, 15);
|
||||
nR1(e, a, b, c, d, 16); nR1(d, e, a, b, c, 17); nR1(c, d, e, a, b, 18); nR1(b, c, d, e, a, 19);
|
||||
}
|
||||
|
||||
void do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
|
||||
{
|
||||
nR2(a, b, c, d, e, 20); nR2(e, a, b, c, d, 21); nR2(d, e, a, b, c, 22); nR2(c, d, e, a, b, 23);
|
||||
nR2(b, c, d, e, a, 24); nR2(a, b, c, d, e, 25); nR2(e, a, b, c, d, 26); nR2(d, e, a, b, c, 27);
|
||||
nR2(c, d, e, a, b, 28); nR2(b, c, d, e, a, 29); nR2(a, b, c, d, e, 30); nR2(e, a, b, c, d, 31);
|
||||
nR2(d, e, a, b, c, 32); nR2(c, d, e, a, b, 33); nR2(b, c, d, e, a, 34); nR2(a, b, c, d, e, 35);
|
||||
nR2(e, a, b, c, d, 36); nR2(d, e, a, b, c, 37); nR2(c, d, e, a, b, 38); nR2(b, c, d, e, a, 39);
|
||||
}
|
||||
|
||||
void do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
|
||||
{
|
||||
nR3(a, b, c, d, e, 40); nR3(e, a, b, c, d, 41); nR3(d, e, a, b, c, 42); nR3(c, d, e, a, b, 43);
|
||||
nR3(b, c, d, e, a, 44); nR3(a, b, c, d, e, 45); nR3(e, a, b, c, d, 46); nR3(d, e, a, b, c, 47);
|
||||
nR3(c, d, e, a, b, 48); nR3(b, c, d, e, a, 49); nR3(a, b, c, d, e, 50); nR3(e, a, b, c, d, 51);
|
||||
nR3(d, e, a, b, c, 52); nR3(c, d, e, a, b, 53); nR3(b, c, d, e, a, 54); nR3(a, b, c, d, e, 55);
|
||||
nR3(e, a, b, c, d, 56); nR3(d, e, a, b, c, 57); nR3(c, d, e, a, b, 58); nR3(b, c, d, e, a, 59);
|
||||
}
|
||||
|
||||
void do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
|
||||
{
|
||||
nR4(a, b, c, d, e, 60); nR4(e, a, b, c, d, 61); nR4(d, e, a, b, c, 62); nR4(c, d, e, a, b, 63);
|
||||
nR4(b, c, d, e, a, 64); nR4(a, b, c, d, e, 65); nR4(e, a, b, c, d, 66); nR4(d, e, a, b, c, 67);
|
||||
nR4(c, d, e, a, b, 68); nR4(b, c, d, e, a, 69); nR4(a, b, c, d, e, 70); nR4(e, a, b, c, d, 71);
|
||||
nR4(d, e, a, b, c, 72); nR4(c, d, e, a, b, 73); nR4(b, c, d, e, a, 74); nR4(a, b, c, d, e, 75);
|
||||
nR4(e, a, b, c, d, 76); nR4(d, e, a, b, c, 77); nR4(c, d, e, a, b, 78); nR4(b, c, d, e, a, 79);
|
||||
}
|
||||
#endif /* ifdef SPARC64_GCC_WORKAROUND */
|
||||
|
||||
/*
|
||||
* Hash a single 512-bit block. This is the core of the algorithm.
|
||||
*/
|
||||
void SHA1Transform(uint32_t state[5], const uint8_t buffer[64])
|
||||
{
|
||||
uint32_t a, b, c, d, e;
|
||||
CHAR64LONG16 *block;
|
||||
|
||||
#ifdef SHA1HANDSOFF
|
||||
CHAR64LONG16 workspace;
|
||||
#endif
|
||||
|
||||
#ifdef SHA1HANDSOFF
|
||||
block = &workspace;
|
||||
(void)memcpy(block, buffer, 64);
|
||||
#else
|
||||
block = (CHAR64LONG16 *)(void *)buffer;
|
||||
#endif
|
||||
|
||||
/* Copy context->state[] to working vars */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
|
||||
#ifdef SPARC64_GCC_WORKAROUND
|
||||
do_R01(&a, &b, &c, &d, &e, block);
|
||||
do_R2(&a, &b, &c, &d, &e, block);
|
||||
do_R3(&a, &b, &c, &d, &e, block);
|
||||
do_R4(&a, &b, &c, &d, &e, block);
|
||||
#else
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1); R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3);
|
||||
R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5); R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7);
|
||||
R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9); R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11);
|
||||
R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13); R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15);
|
||||
R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17); R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19);
|
||||
R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21); R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23);
|
||||
R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25); R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27);
|
||||
R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29); R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31);
|
||||
R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33); R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35);
|
||||
R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37); R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39);
|
||||
R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41); R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43);
|
||||
R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45); R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47);
|
||||
R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49); R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51);
|
||||
R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53); R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55);
|
||||
R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57); R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59);
|
||||
R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61); R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63);
|
||||
R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65); R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67);
|
||||
R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69); R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71);
|
||||
R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73); R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75);
|
||||
R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77); R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79);
|
||||
#endif /* ifdef SPARC64_GCC_WORKAROUND */
|
||||
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA1Init - Initialize new context
|
||||
*/
|
||||
void SHA1Init(SHA1_CTX *context)
|
||||
{
|
||||
/* SHA1 initialization constants */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xC3D2E1F0;
|
||||
context->count[0] = context->count[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run your data through this.
|
||||
*/
|
||||
void SHA1Update(SHA1_CTX *context, const uint8_t *data, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
j = context->count[0];
|
||||
if ((context->count[0] += len << 3) < j) {
|
||||
context->count[1] += (len >> 29) + 1;
|
||||
}
|
||||
j = (j >> 3) & 63;
|
||||
if ((j + len) > 63) {
|
||||
(void)memcpy(&context->buffer[j], data, (i = 64 - j));
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
for (; i + 63 < len; i += 64) {
|
||||
SHA1Transform(context->state, &data[i]);
|
||||
}
|
||||
j = 0;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
(void)memcpy(&context->buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add padding and return the message digest.
|
||||
*/
|
||||
void SHA1Final(uint8_t digest[20], SHA1_CTX *context)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]
|
||||
>> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
|
||||
}
|
||||
SHA1Update(context, (const uint8_t *)"\200", 1);
|
||||
while ((context->count[0] & 504) != 448) {
|
||||
SHA1Update(context, (const uint8_t *)"\0", 1);
|
||||
}
|
||||
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
|
||||
if (digest) {
|
||||
for (i = 0; i < 20; i++) {
|
||||
digest[i] = (uint8_t)
|
||||
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_SHA1_H */
|
@ -53,20 +53,23 @@ static int8_t counter;
|
||||
#endif
|
||||
|
||||
// Private constants
|
||||
#define MAX_QUEUE_SIZE 2
|
||||
#define MAX_QUEUE_SIZE 2
|
||||
|
||||
#if defined(PIOS_ACTUATOR_STACK_SIZE)
|
||||
#define STACK_SIZE_BYTES PIOS_ACTUATOR_STACK_SIZE
|
||||
#define STACK_SIZE_BYTES PIOS_ACTUATOR_STACK_SIZE
|
||||
#else
|
||||
#define STACK_SIZE_BYTES 1312
|
||||
#define STACK_SIZE_BYTES 1312
|
||||
#endif
|
||||
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 4) // device driver
|
||||
#define FAILSAFE_TIMEOUT_MS 100
|
||||
#define MAX_MIX_ACTUATORS ACTUATORCOMMAND_CHANNEL_NUMELEM
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 4) // device driver
|
||||
#define FAILSAFE_TIMEOUT_MS 100
|
||||
#define MAX_MIX_ACTUATORS ACTUATORCOMMAND_CHANNEL_NUMELEM
|
||||
|
||||
#define CAMERA_BOOT_DELAY_MS 7000
|
||||
#define CAMERA_BOOT_DELAY_MS 7000
|
||||
|
||||
#define ACTUATOR_ONESHOT125_CLOCK 2000000
|
||||
#define ACTUATOR_ONESHOT125_PULSE_SCALE 4
|
||||
#define ACTUATOR_PWM_CLOCK 1000000
|
||||
// Private types
|
||||
|
||||
|
||||
@ -74,8 +77,9 @@ static int8_t counter;
|
||||
static xQueueHandle queue;
|
||||
static xTaskHandle taskHandle;
|
||||
|
||||
static float lastResult[MAX_MIX_ACTUATORS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static float filterAccumulator[MAX_MIX_ACTUATORS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static float lastResult[MAX_MIX_ACTUATORS] = { 0 };
|
||||
static float filterAccumulator[MAX_MIX_ACTUATORS] = { 0 };
|
||||
static uint8_t pinsMode[MAX_MIX_ACTUATORS];
|
||||
// used to inform the actuator thread that actuator update rate is changed
|
||||
static volatile bool actuator_settings_updated;
|
||||
// used to inform the actuator thread that mixer settings are changed
|
||||
@ -436,7 +440,6 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
|
||||
if (command.UpdateTime > command.MaxUpdateTime) {
|
||||
command.MaxUpdateTime = command.UpdateTime;
|
||||
}
|
||||
|
||||
// Update output object
|
||||
ActuatorCommandSet(&command);
|
||||
// Update in case read only (eg. during servo configuration)
|
||||
@ -454,6 +457,8 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
|
||||
success &= set_channel(n, command.Channel[n], &actuatorSettings);
|
||||
}
|
||||
|
||||
PIOS_Servo_Update();
|
||||
|
||||
if (!success) {
|
||||
command.NumFailedUpdates++;
|
||||
ActuatorCommandSet(&command);
|
||||
@ -476,11 +481,11 @@ float ProcessMixer(const int index, const float curve1, const float curve2,
|
||||
const Mixer_t *mixers = (Mixer_t *)&mixerSettings->Mixer1Type; // pointer to array of mixers in UAVObjects
|
||||
const Mixer_t *mixer = &mixers[index];
|
||||
|
||||
float result = (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE1] / 128.0f) * curve1) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2] / 128.0f) * curve2) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL] / 128.0f) * desired->Roll) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH] / 128.0f) * desired->Pitch) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW] / 128.0f) * desired->Yaw);
|
||||
float result = ((((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE1]) * curve1) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2]) * curve2) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL]) * desired->Roll) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH]) * desired->Pitch) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW]) * desired->Yaw)) / 128.0f;
|
||||
|
||||
// note: no feedforward for reversable motors yet for safety reasons
|
||||
if (mixer->type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
|
||||
@ -615,6 +620,8 @@ static void setFailsafe(const ActuatorSettingsData *actuatorSettings, const Mixe
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n) {
|
||||
set_channel(n, Channel[n], actuatorSettings);
|
||||
}
|
||||
// Send the updated command
|
||||
PIOS_Servo_Update();
|
||||
|
||||
// Update output object's parts that we changed
|
||||
ActuatorCommandChannelSet(Channel);
|
||||
@ -730,8 +737,19 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSet
|
||||
return true;
|
||||
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_PWM:
|
||||
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value);
|
||||
{
|
||||
uint8_t mode = pinsMode[actuatorSettings->ChannelAddr[mixer_channel]];
|
||||
switch (mode) {
|
||||
case ACTUATORSETTINGS_BANKMODE_ONESHOT125:
|
||||
// Remap 1000-2000 range to 125-250
|
||||
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value / ACTUATOR_ONESHOT125_PULSE_SCALE);
|
||||
break;
|
||||
default:
|
||||
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C_ESC)
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_MK:
|
||||
@ -754,18 +772,57 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSet
|
||||
*/
|
||||
static void actuator_update_rate_if_changed(const ActuatorSettingsData *actuatorSettings, bool force_update)
|
||||
{
|
||||
static uint16_t prevChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
|
||||
static uint16_t prevBankUpdateFreq[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM];
|
||||
static uint8_t prevBankMode[ACTUATORSETTINGS_BANKMODE_NUMELEM];
|
||||
|
||||
// check if the any rate setting is changed
|
||||
if (force_update ||
|
||||
memcmp(prevChannelUpdateFreq,
|
||||
actuatorSettings->ChannelUpdateFreq,
|
||||
sizeof(prevChannelUpdateFreq)) != 0) {
|
||||
(memcmp(prevBankUpdateFreq,
|
||||
actuatorSettings->BankUpdateFreq,
|
||||
sizeof(prevBankUpdateFreq)) != 0) ||
|
||||
(memcmp(prevBankUpdateFreq,
|
||||
actuatorSettings->BankMode,
|
||||
sizeof(prevBankMode)) != 0)
|
||||
) {
|
||||
/* Something has changed, apply the settings to HW */
|
||||
memcpy(prevChannelUpdateFreq,
|
||||
actuatorSettings->ChannelUpdateFreq,
|
||||
sizeof(prevChannelUpdateFreq));
|
||||
PIOS_Servo_SetHz(actuatorSettings->ChannelUpdateFreq, ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
|
||||
memcpy(prevBankUpdateFreq,
|
||||
actuatorSettings->BankUpdateFreq,
|
||||
sizeof(prevBankUpdateFreq));
|
||||
memcpy(prevBankMode,
|
||||
actuatorSettings->BankMode,
|
||||
sizeof(prevBankMode));
|
||||
|
||||
uint16_t freq[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM];
|
||||
uint32_t clock[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM] = { 0 };
|
||||
for (uint8_t i = 0; i < ACTUATORSETTINGS_BANKMODE_NUMELEM; i++) {
|
||||
PIOS_Servo_SetBankMode(i,
|
||||
actuatorSettings->BankMode[i] ==
|
||||
ACTUATORSETTINGS_BANKMODE_PWM ?
|
||||
PIOS_SERVO_BANK_MODE_PWM :
|
||||
PIOS_SERVO_BANK_MODE_SINGLE_PULSE
|
||||
);
|
||||
switch (actuatorSettings->BankMode[i]) {
|
||||
case ACTUATORSETTINGS_BANKMODE_ONESHOT125:
|
||||
freq[i] = 100; // Value must be small enough so CCr isn't update until the PIOS_Servo_Update is triggered
|
||||
clock[i] = ACTUATOR_ONESHOT125_CLOCK; // Setup an 8MHz timer clock
|
||||
break;
|
||||
case ACTUATORSETTINGS_BANKMODE_ONESHOT:
|
||||
freq[i] = 100;
|
||||
clock[i] = ACTUATOR_PWM_CLOCK;
|
||||
break;
|
||||
default: // PWM
|
||||
freq[i] = actuatorSettings->BankUpdateFreq[i];
|
||||
clock[i] = ACTUATOR_PWM_CLOCK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PIOS_Servo_SetHz(freq, clock, ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM);
|
||||
|
||||
// retrieve mode from related bank
|
||||
for (uint8_t i = 0; i < MAX_MIX_ACTUATORS; i++) {
|
||||
uint8_t bank = PIOS_Servo_GetPinBank(i);
|
||||
pinsMode[i] = actuatorSettings->BankMode[bank];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,6 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
oplinkStatus.RxMissed = radio_stats.rx_missed;
|
||||
oplinkStatus.RxFailure = radio_stats.rx_failure;
|
||||
oplinkStatus.TxDropped = radio_stats.tx_dropped;
|
||||
oplinkStatus.TxResent = radio_stats.tx_resent;
|
||||
oplinkStatus.TxFailure = radio_stats.tx_failure;
|
||||
oplinkStatus.Resets = radio_stats.resets;
|
||||
oplinkStatus.Timeouts = radio_stats.timeouts;
|
||||
|
@ -267,7 +267,6 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
oplinkStatus.RxMissed = radio_stats.rx_missed;
|
||||
oplinkStatus.RxFailure = radio_stats.rx_failure;
|
||||
oplinkStatus.TxDropped = radio_stats.tx_dropped;
|
||||
oplinkStatus.TxResent = radio_stats.tx_resent;
|
||||
oplinkStatus.TxFailure = radio_stats.tx_failure;
|
||||
oplinkStatus.Resets = radio_stats.resets;
|
||||
oplinkStatus.Timeouts = radio_stats.timeouts;
|
||||
|
@ -47,8 +47,8 @@
|
||||
// 6-byte (32-bit) preamble .. alternating 0's & 1's
|
||||
// 4-byte (32-bit) sync
|
||||
// 1-byte packet length (number of data bytes to follow)
|
||||
// 1 byte valid bitmask
|
||||
// 8 PPM values (0-255)
|
||||
// 1 byte PPM values LSB (bit 0)
|
||||
// 8 bytes PPM values MSBs (bit 8:1)
|
||||
// 1 byte CRC
|
||||
//
|
||||
// *****************************************************************
|
||||
@ -61,6 +61,7 @@
|
||||
#include <pios_rfm22b_priv.h>
|
||||
#include <pios_ppm_out.h>
|
||||
#include <ecc.h>
|
||||
#include <sha1.h>
|
||||
|
||||
/* Local Defines */
|
||||
#define STACK_SIZE_BYTES 200
|
||||
@ -73,9 +74,16 @@
|
||||
#define RFM22B_LINK_QUALITY_THRESHOLD 20
|
||||
#define RFM22B_DEFAULT_MIN_CHANNEL 0
|
||||
#define RFM22B_DEFAULT_MAX_CHANNEL 250
|
||||
#define RFM22B_DEFAULT_CHANNEL_SET 24
|
||||
#define RFM22B_PPM_ONLY_DATARATE RFM22_datarate_9600
|
||||
|
||||
// PPM encoding limits
|
||||
#define RFM22B_PPM_MIN 1
|
||||
#define RFM22B_PPM_MAX 511
|
||||
#define RFM22B_PPM_INVALID 0
|
||||
#define RFM22B_PPM_SCALE 2
|
||||
#define RFM22B_PPM_MIN_US 990
|
||||
#define RFM22B_PPM_MAX_US (RFM22B_PPM_MIN_US + (RFM22B_PPM_MAX - RFM22B_PPM_MIN) * RFM22B_PPM_SCALE)
|
||||
|
||||
// The maximum amount of time without activity before initiating a reset.
|
||||
#define PIOS_RFM22B_SUPERVISOR_TIMEOUT 150 // ms
|
||||
|
||||
@ -116,6 +124,9 @@
|
||||
#define USB_LED_OFF
|
||||
#endif
|
||||
|
||||
#define CONNECTED_TIMEOUT (250 / portTICK_RATE_MS) /* ms */
|
||||
#define MAX_CHANNELS 32
|
||||
|
||||
/* Local type definitions */
|
||||
|
||||
struct pios_rfm22b_transition {
|
||||
@ -155,21 +166,6 @@ static const uint8_t OUT_FF[64] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
// The randomized channel list.
|
||||
static const uint8_t channel_list[] = {
|
||||
68, 34, 2, 184, 166, 94, 204, 18, 47, 118, 239, 176, 5, 213, 218, 186, 104, 160, 199, 209, 231, 197, 92,
|
||||
191, 88, 129, 40, 19, 93, 200, 156, 14, 247, 182, 193, 194, 208, 210, 248, 76, 244, 48, 179, 105, 25, 74,
|
||||
155, 203, 39, 97, 195, 81, 83, 180, 134, 172, 235, 132, 198, 119, 207, 154, 0, 61, 140, 171, 245, 26, 95,
|
||||
3, 22, 62, 169, 55, 127, 144, 45, 33, 170, 91, 158, 167, 63, 201, 41, 21, 190, 51, 103, 49, 189, 205,
|
||||
240, 89, 181, 149, 6, 157, 249, 230, 115, 72, 163, 17, 29, 99, 28, 117, 219, 73, 78, 53, 69, 216, 161,
|
||||
124, 110, 242, 214, 145, 13, 11, 220, 113, 138, 58, 54, 162, 237, 37, 152, 187, 232, 77, 126, 85, 38, 238,
|
||||
173, 23, 188, 100, 131, 226, 31, 9, 114, 106, 221, 42, 233, 139, 4, 241, 96, 211, 8, 98, 121, 147, 24,
|
||||
217, 27, 87, 122, 125, 135, 148, 178, 71, 206, 57, 141, 35, 30, 246, 159, 16, 32, 15, 229, 20, 12, 223,
|
||||
150, 101, 79, 56, 102, 111, 174, 236, 137, 143, 52, 225, 64, 224, 112, 168, 243, 130, 108, 202, 123, 146, 228,
|
||||
75, 46, 153, 7, 192, 175, 151, 222, 59, 82, 90, 1, 65, 109, 44, 165, 84, 43, 36, 128, 196, 67, 80,
|
||||
136, 86, 70, 234, 66, 185, 10, 164, 177, 116, 50, 107, 183, 215, 212, 60, 227, 133, 120, 14
|
||||
};
|
||||
|
||||
/* Local function forwared declarations */
|
||||
static void pios_rfm22_task(void *parameters);
|
||||
static bool pios_rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
@ -207,6 +203,10 @@ static void rfm22_clearLEDs();
|
||||
// Utility functions.
|
||||
static uint32_t pios_rfm22_time_difference_ms(portTickType start_time, portTickType end_time);
|
||||
static struct pios_rfm22b_dev *pios_rfm22_alloc(void);
|
||||
static void rfm22_hmac_sha1(const uint8_t *data, size_t len, uint8_t key[SHA1_DIGEST_LENGTH],
|
||||
uint8_t digest[SHA1_DIGEST_LENGTH]);
|
||||
static bool rfm22_gen_channels(uint32_t coordid, enum rfm22b_datarate datarate, uint8_t min,
|
||||
uint8_t max, uint8_t channels[MAX_CHANNELS], uint8_t *clen);
|
||||
|
||||
// SPI read/write functions
|
||||
static void rfm22_assertCs(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
@ -331,6 +331,18 @@ static const uint32_t data_rate[] = {
|
||||
256000, // 256 kbps, 433 MHz, 150 khz freq dev
|
||||
};
|
||||
|
||||
static const uint8_t channel_spacing[] = {
|
||||
1, /* 9.6kbps */
|
||||
2, /* 19.2kps */
|
||||
2, /* 32kps */
|
||||
2, /* 57.6kps */
|
||||
2, /* 64kps */
|
||||
3, /* 100kps */
|
||||
4, /* 128kps */
|
||||
4, /* 192kps */
|
||||
4 /* 256kps */
|
||||
};
|
||||
|
||||
static const uint8_t reg_1C[] = { 0x01, 0x05, 0x06, 0x95, 0x95, 0x81, 0x88, 0x8B, 0x8D }; // rfm22_if_filter_bandwidth
|
||||
|
||||
static const uint8_t reg_1D[] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; // rfm22_afc_loop_gearshift_override
|
||||
@ -358,7 +370,7 @@ static const uint8_t reg_72[] = { 0x30, 0x48, 0x48, 0x48, 0x48, 0x60, 0x90, 0xCD
|
||||
|
||||
static const uint8_t packet_time[] = { 80, 40, 25, 15, 13, 10, 8, 6, 5 };
|
||||
static const uint8_t packet_time_ppm[] = { 26, 25, 25, 15, 13, 10, 8, 6, 5 };
|
||||
static const uint8_t num_channels[] = { 4, 4, 4, 6, 8, 8, 10, 12, 16 };
|
||||
static const uint8_t num_channels[] = { 32, 32, 32, 32, 32, 32, 32, 32, 32 };
|
||||
|
||||
static struct pios_rfm22b_dev *g_rfm22b_dev = NULL;
|
||||
|
||||
@ -412,7 +424,6 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
rfm22b_dev->stats.rx_error = 0;
|
||||
rfm22b_dev->stats.rx_missed = 0;
|
||||
rfm22b_dev->stats.tx_dropped = 0;
|
||||
rfm22b_dev->stats.tx_resent = 0;
|
||||
rfm22b_dev->stats.resets = 0;
|
||||
rfm22b_dev->stats.timeouts = 0;
|
||||
rfm22b_dev->stats.link_quality = 0;
|
||||
@ -423,7 +434,7 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
|
||||
// Initialize the channels.
|
||||
PIOS_RFM22B_SetChannelConfig(*rfm22b_id, RFM22B_DEFAULT_RX_DATARATE, RFM22B_DEFAULT_MIN_CHANNEL,
|
||||
RFM22B_DEFAULT_MAX_CHANNEL, RFM22B_DEFAULT_CHANNEL_SET, false, false, false, false);
|
||||
RFM22B_DEFAULT_MAX_CHANNEL, false, false, false, false);
|
||||
|
||||
// Create the event queue
|
||||
rfm22b_dev->eventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(enum pios_radio_event));
|
||||
@ -566,12 +577,12 @@ void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr)
|
||||
* @param[in] datarate The desired datarate.
|
||||
* @param[in] min_chan The minimum channel.
|
||||
* @param[in] max_chan The maximum channel.
|
||||
* @param[in] chan_set The "seed" for selecting a channel sequence.
|
||||
* @param[in] coordinator Is this modem an coordinator.
|
||||
* @param[in] ppm_mode Should this modem send/receive ppm packets?
|
||||
* @param[in] oneway Only the coordinator can send packets if true.
|
||||
* @param[in] ppm_only Should this modem run in ppm only mode?
|
||||
*/
|
||||
void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datarate, uint8_t min_chan, uint8_t max_chan, uint8_t chan_set, bool coordinator, bool oneway, bool ppm_mode, bool ppm_only)
|
||||
void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datarate, uint8_t min_chan, uint8_t max_chan, bool coordinator, bool oneway, bool ppm_mode, bool ppm_only)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
|
||||
@ -596,15 +607,11 @@ void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datar
|
||||
}
|
||||
rfm22b_dev->packet_time = (ppm_mode ? packet_time_ppm[datarate] : packet_time[datarate]);
|
||||
|
||||
// Find the first N channels that meet the min/max criteria out of the random channel list.
|
||||
uint8_t num_found = 0;
|
||||
for (uint16_t i = 0; (i < RFM22B_NUM_CHANNELS) && (num_found < num_channels[datarate]); ++i) {
|
||||
uint8_t idx = (i + chan_set) % RFM22B_NUM_CHANNELS;
|
||||
uint8_t chan = channel_list[idx];
|
||||
if ((chan >= min_chan) && (chan <= max_chan)) {
|
||||
rfm22b_dev->channels[num_found++] = chan;
|
||||
}
|
||||
}
|
||||
rfm22_gen_channels(rfm22_destinationID(rfm22b_dev), datarate, min_chan, max_chan,
|
||||
rfm22b_dev->channels, &num_found);
|
||||
|
||||
rfm22b_dev->num_channels = num_found;
|
||||
|
||||
// Calculate the maximum packet length from the datarate.
|
||||
float bytes_per_period = (float)data_rate[datarate] * (float)(rfm22b_dev->packet_time - 2) / 9000;
|
||||
@ -1354,7 +1361,7 @@ static enum pios_radio_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
rfm22b_dev->tx_complete_ticks = 0;
|
||||
rfm22b_dev->rfm22b_state = RFM22B_STATE_INITIALIZING;
|
||||
rfm22b_dev->on_sync_channel = false;
|
||||
rfm22b_dev->last_contact = 0;
|
||||
|
||||
// software reset the RF chip .. following procedure according to Si4x3x Errata (rev. B)
|
||||
rfm22_write_claim(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
@ -1725,7 +1732,7 @@ static bool pios_rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
*/
|
||||
static void rfm22_rxFailure(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22b_dev->stats.rx_failure++;
|
||||
rfm22b_add_rx_status(rfm22b_dev, RADIO_FAILURE_RX_PACKET);
|
||||
rfm22b_dev->rx_buffer_wr = 0;
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
rfm22b_dev->rfm22b_state = RFM22B_STATE_TRANSITION;
|
||||
@ -1767,18 +1774,31 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev)
|
||||
return RADIO_EVENT_RX_MODE;
|
||||
}
|
||||
|
||||
// The first byte is a bitmask of valid channels.
|
||||
// The first byte stores the LSB of each channel
|
||||
p[0] = 0;
|
||||
|
||||
// Read the PPM input.
|
||||
for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) {
|
||||
int32_t val = radio_dev->ppm[i];
|
||||
|
||||
// Clamp and translate value, or transmit as reserved "invalid" constant
|
||||
if ((val == PIOS_RCVR_INVALID) || (val == PIOS_RCVR_TIMEOUT)) {
|
||||
p[i + 1] = 0;
|
||||
val = RFM22B_PPM_INVALID;
|
||||
} else if (val > RFM22B_PPM_MAX_US) {
|
||||
val = RFM22B_PPM_MAX;
|
||||
} else if (val < RFM22B_PPM_MIN_US) {
|
||||
val = RFM22B_PPM_MIN;
|
||||
} else {
|
||||
p[0] |= 1 << i;
|
||||
p[i + 1] = (val < 1000) ? 0 : ((val >= 1900) ? 255 : (uint8_t)(256 * (val - 1000) / 900));
|
||||
val = (val - RFM22B_PPM_MIN_US) / RFM22B_PPM_SCALE + RFM22B_PPM_MIN;
|
||||
}
|
||||
|
||||
// Store LSB
|
||||
if (val & 1) {
|
||||
p[0] |= (1 << i);
|
||||
}
|
||||
|
||||
// Store upper 8 bits in array
|
||||
p[i + 1] = val >> 1;
|
||||
}
|
||||
|
||||
// The last byte is a CRC.
|
||||
@ -1798,8 +1818,8 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev)
|
||||
len += (radio_dev->tx_out_cb)(radio_dev->tx_out_context, p + len, max_data_len - len, NULL, &need_yield);
|
||||
}
|
||||
|
||||
// Always send a packet on the sync channel if this modem is a coordinator.
|
||||
if ((len == 0) && ((radio_dev->channel_index != 0) || !rfm22_isCoordinator(radio_dev))) {
|
||||
// Always send a packet if this modem is a coordinator.
|
||||
if ((len == 0) && !rfm22_isCoordinator(radio_dev)) {
|
||||
return RADIO_EVENT_RX_MODE;
|
||||
}
|
||||
|
||||
@ -1921,10 +1941,11 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d
|
||||
|
||||
if (good_packet || corrected_packet) {
|
||||
for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) {
|
||||
// Calculate 9-bit value taking the LSB from byte 0
|
||||
uint32_t val = (p[i + 1] << 1) + ((p[0] >> i) & 1);
|
||||
// Is this a valid channel?
|
||||
if (p[0] & (1 << i)) {
|
||||
uint32_t val = p[i + 1];
|
||||
radio_dev->ppm[i] = (uint16_t)(1000 + val * 900 / 256);
|
||||
if (val != RFM22B_PPM_INVALID) {
|
||||
radio_dev->ppm[i] = (uint16_t)(RFM22B_PPM_MIN_US + (val - RFM22B_PPM_MIN) * RFM22B_PPM_SCALE);
|
||||
} else {
|
||||
radio_dev->ppm[i] = PIOS_RCVR_INVALID;
|
||||
}
|
||||
@ -1959,12 +1980,16 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d
|
||||
(radio_dev->rx_in_cb)(radio_dev->rx_in_context, p, data_len, NULL, &rx_need_yield);
|
||||
}
|
||||
|
||||
// We only synchronize the clock on packets from our coordinator on the sync channel.
|
||||
if (!rfm22_isCoordinator(radio_dev) && (radio_dev->rx_destination_id == rfm22_destinationID(radio_dev)) && (radio_dev->channel_index == 0)) {
|
||||
/*
|
||||
* If the packet is valid and destined for us we synchronize the clock.
|
||||
*/
|
||||
if (!rfm22_isCoordinator(radio_dev) &&
|
||||
radio_dev->rx_destination_id == rfm22_destinationID(radio_dev)) {
|
||||
rfm22_synchronizeClock(radio_dev);
|
||||
radio_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
radio_dev->on_sync_channel = false;
|
||||
}
|
||||
|
||||
radio_dev->last_contact = xTaskGetTickCount();
|
||||
} else {
|
||||
ret_event = RADIO_EVENT_RX_COMPLETE;
|
||||
}
|
||||
@ -2069,7 +2094,7 @@ static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->stats.rx_good = 0;
|
||||
rfm22b_dev->stats.rx_corrected = 0;
|
||||
rfm22b_dev->stats.rx_error = 0;
|
||||
rfm22b_dev->stats.tx_resent = 0;
|
||||
rfm22b_dev->stats.rx_failure = 0;
|
||||
for (uint8_t i = 0; i < RFM22B_RX_PACKET_STATS_LEN; ++i) {
|
||||
uint32_t val = rfm22b_dev->rx_packet_stats[i];
|
||||
for (uint8_t j = 0; j < 16; ++j) {
|
||||
@ -2083,8 +2108,8 @@ static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
case RADIO_ERROR_RX_PACKET:
|
||||
rfm22b_dev->stats.rx_error++;
|
||||
break;
|
||||
case RADIO_RESENT_TX_PACKET:
|
||||
rfm22b_dev->stats.tx_resent++;
|
||||
case RADIO_FAILURE_RX_PACKET:
|
||||
rfm22b_dev->stats.rx_failure++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2094,7 +2119,7 @@ static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// Note: This assumes that the number of packets sampled for the stats is 64.
|
||||
// Using this equation, error and resent packets are counted as -2, and corrected packets are counted as -1.
|
||||
// The range is 0 (all error or resent packets) to 128 (all good packets).
|
||||
rfm22b_dev->stats.link_quality = 64 + rfm22b_dev->stats.rx_good - rfm22b_dev->stats.rx_error - rfm22b_dev->stats.tx_resent;
|
||||
rfm22b_dev->stats.link_quality = 64 + rfm22b_dev->stats.rx_good - rfm22b_dev->stats.rx_error - rfm22b_dev->stats.rx_failure;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2160,14 +2185,14 @@ static void rfm22_synchronizeClock(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
portTickType start_time = rfm22b_dev->packet_start_ticks;
|
||||
|
||||
// This packet was transmitted on channel 0, calculate the time delta that will force us to transmit on channel 0 at the time this packet started.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint16_t frequency_hop_cycle_time = rfm22b_dev->packet_time * num_chan;
|
||||
uint16_t frequency_hop_cycle_time = rfm22b_dev->packet_time * rfm22b_dev->num_channels;
|
||||
uint16_t time_delta = start_time % frequency_hop_cycle_time;
|
||||
|
||||
// Calculate the adjustment for the preamble
|
||||
uint8_t offset = (uint8_t)ceil(35000.0F / data_rate[rfm22b_dev->datarate]);
|
||||
|
||||
rfm22b_dev->time_delta = frequency_hop_cycle_time - time_delta + offset;
|
||||
rfm22b_dev->time_delta = frequency_hop_cycle_time - time_delta + offset +
|
||||
rfm22b_dev->packet_time * rfm22b_dev->channel_index;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2222,15 +2247,13 @@ static bool rfm22_timeToSend(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
static uint8_t rfm22_calcChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t index)
|
||||
{
|
||||
// Make sure we don't index outside of the range.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint8_t idx = index % num_chan;
|
||||
uint8_t idx = index % rfm22b_dev->num_channels;
|
||||
|
||||
// Are we switching to a new channel?
|
||||
if (idx != rfm22b_dev->channel_index) {
|
||||
// If the on_sync_channel flag is set, it means that we were on the sync channel, but no packet was received, so transition to a non-connected state.
|
||||
if (!rfm22_isCoordinator(rfm22b_dev) && (rfm22b_dev->channel_index == 0) && rfm22b_dev->on_sync_channel) {
|
||||
rfm22b_dev->on_sync_channel = false;
|
||||
|
||||
if (!rfm22_isCoordinator(rfm22b_dev) &&
|
||||
pios_rfm22_time_difference_ms(rfm22b_dev->last_contact, xTaskGetTickCount()) >=
|
||||
CONNECTED_TIMEOUT) {
|
||||
// Set the link state to disconnected.
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED) {
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_DISCONNECTED;
|
||||
@ -2240,11 +2263,8 @@ static uint8_t rfm22_calcChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t ind
|
||||
}
|
||||
}
|
||||
|
||||
// Stay on the sync channel.
|
||||
// Stay on first channel.
|
||||
idx = 0;
|
||||
} else if (idx == 0) {
|
||||
// If we're switching to the sync channel, set a flag that can be used to detect if a packet was received.
|
||||
rfm22b_dev->on_sync_channel = true;
|
||||
}
|
||||
|
||||
rfm22b_dev->channel_index = idx;
|
||||
@ -2263,8 +2283,7 @@ static uint8_t rfm22_calcChannelFromClock(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
portTickType time = rfm22_coordinatorTime(rfm22b_dev, xTaskGetTickCount());
|
||||
// Divide time into 8ms blocks. Coordinator sends in first 2 ms, and remote send in 5th and 6th ms.
|
||||
// Channel changes occur in the last 2 ms.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint8_t n = (time / rfm22b_dev->packet_time) % num_chan;
|
||||
uint8_t n = (time / rfm22b_dev->packet_time) % rfm22b_dev->num_channels;
|
||||
|
||||
return rfm22_calcChannel(rfm22b_dev, n);
|
||||
}
|
||||
@ -2553,6 +2572,86 @@ static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
return in[1];
|
||||
}
|
||||
|
||||
|
||||
static void rfm22_hmac_sha1(const uint8_t *data, size_t len,
|
||||
uint8_t key[SHA1_DIGEST_LENGTH],
|
||||
uint8_t digest[SHA1_DIGEST_LENGTH])
|
||||
{
|
||||
uint8_t ipad[64] = { 0 };
|
||||
uint8_t opad[64] = { 0 };
|
||||
static SHA1_CTX *ctx;
|
||||
|
||||
ctx = pios_malloc(sizeof(SHA1_CTX));
|
||||
|
||||
memcpy(ipad, key, SHA1_DIGEST_LENGTH);
|
||||
memcpy(opad, key, SHA1_DIGEST_LENGTH);
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
ipad[i] ^= 0x36;
|
||||
opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
SHA1Init(ctx);
|
||||
SHA1Update(ctx, ipad, sizeof(ipad));
|
||||
SHA1Update(ctx, data, len);
|
||||
SHA1Final(digest, ctx);
|
||||
|
||||
SHA1Init(ctx);
|
||||
SHA1Update(ctx, opad, sizeof(opad));
|
||||
SHA1Update(ctx, digest, SHA1_DIGEST_LENGTH);
|
||||
SHA1Final(digest, ctx);
|
||||
|
||||
pios_free(ctx);
|
||||
}
|
||||
|
||||
static bool rfm22_gen_channels(uint32_t coordid, enum rfm22b_datarate rate, uint8_t min,
|
||||
uint8_t max, uint8_t channels[MAX_CHANNELS], uint8_t *clen)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint8_t cpos = 0;
|
||||
uint8_t chan_range = (max / channel_spacing[rate] - min / channel_spacing[rate]) + 1;
|
||||
uint8_t key[SHA1_DIGEST_LENGTH] = { 0 };
|
||||
uint8_t digest[SHA1_DIGEST_LENGTH];
|
||||
uint8_t *all_channels;
|
||||
|
||||
all_channels = pios_malloc(RFM22B_NUM_CHANNELS);
|
||||
|
||||
memcpy(key, &coordid, sizeof(coordid));
|
||||
|
||||
for (int i = 0; i < chan_range; i++) {
|
||||
all_channels[i] = min / channel_spacing[rate] + i;
|
||||
}
|
||||
|
||||
int j = SHA1_DIGEST_LENGTH;
|
||||
for (int i = 0; i < chan_range && i < MAX_CHANNELS; i++) {
|
||||
uint8_t rnd;
|
||||
uint8_t r;
|
||||
uint8_t tmp;
|
||||
|
||||
if (j == SHA1_DIGEST_LENGTH) {
|
||||
rfm22_hmac_sha1((uint8_t *)&data, sizeof(data), key, digest);
|
||||
j = 0;
|
||||
data++;
|
||||
}
|
||||
rnd = digest[j];
|
||||
j++;
|
||||
r = rnd % (chan_range - i) + i;
|
||||
tmp = all_channels[i];
|
||||
all_channels[i] = all_channels[r];
|
||||
all_channels[r] = tmp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < chan_range && cpos < MAX_CHANNELS; i++, cpos++) {
|
||||
channels[cpos] = all_channels[i] * channel_spacing[rate];
|
||||
}
|
||||
|
||||
*clen = cpos & 0xfe;
|
||||
|
||||
pios_free(all_channels);
|
||||
|
||||
return *clen > 0;
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_RFM22B */
|
||||
|
||||
/**
|
||||
|
@ -30,4 +30,6 @@
|
||||
#ifndef PIOS_PWM_H
|
||||
#define PIOS_PWM_H
|
||||
|
||||
#define PIOS_PWM_VALID_RANGE_MAX 2250
|
||||
#define PIOS_PWM_VALID_RANGE_MIN 750
|
||||
#endif /* PIOS_PWM_H */
|
||||
|
@ -90,7 +90,6 @@ struct rfm22b_stats {
|
||||
uint8_t rx_missed;
|
||||
uint8_t rx_failure;
|
||||
uint8_t tx_dropped;
|
||||
uint8_t tx_resent;
|
||||
uint8_t tx_failure;
|
||||
uint8_t resets;
|
||||
uint8_t timeouts;
|
||||
@ -104,7 +103,7 @@ struct rfm22b_stats {
|
||||
extern int32_t PIOS_RFM22B_Init(uint32_t *rfb22b_id, uint32_t spi_id, uint32_t slave_num, const struct pios_rfm22b_cfg *cfg);
|
||||
extern void PIOS_RFM22B_Reinit(uint32_t rfb22b_id);
|
||||
extern void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr);
|
||||
extern void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datarate, uint8_t min_chan, uint8_t max_chan, uint8_t chan_set, bool coordinator, bool oneway, bool ppm_mode, bool ppm_only);
|
||||
extern void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datarate, uint8_t min_chan, uint8_t max_chan, bool coordinator, bool oneway, bool ppm_mode, bool ppm_only);
|
||||
extern void PIOS_RFM22B_SetCoordinatorID(uint32_t rfm22b_id, uint32_t coord_id);
|
||||
extern uint32_t PIOS_RFM22B_DeviceID(uint32_t rfb22b_id);
|
||||
extern void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats);
|
||||
|
@ -40,7 +40,7 @@
|
||||
// ************************************
|
||||
|
||||
#define RFM22B_MAX_PACKET_LEN 64
|
||||
#define RFM22B_NUM_CHANNELS 250
|
||||
#define RFM22B_NUM_CHANNELS 251
|
||||
|
||||
// ************************************
|
||||
|
||||
@ -578,7 +578,7 @@ enum pios_rfm22b_rx_packet_status {
|
||||
RADIO_GOOD_RX_PACKET = 0x00,
|
||||
RADIO_CORRECTED_RX_PACKET = 0x01,
|
||||
RADIO_ERROR_RX_PACKET = 0x2,
|
||||
RADIO_RESENT_TX_PACKET = 0x3
|
||||
RADIO_FAILURE_RX_PACKET = 0x3
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -780,7 +780,7 @@ struct pios_rfm22b_dev {
|
||||
portTickType packet_start_ticks;
|
||||
portTickType tx_complete_ticks;
|
||||
portTickType time_delta;
|
||||
bool on_sync_channel;
|
||||
portTickType last_contact;
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,9 +30,17 @@
|
||||
#ifndef PIOS_SERVO_H
|
||||
#define PIOS_SERVO_H
|
||||
|
||||
/* Global types */
|
||||
enum pios_servo_bank_mode {
|
||||
PIOS_SERVO_BANK_MODE_PWM = 0,
|
||||
PIOS_SERVO_BANK_MODE_SINGLE_PULSE = 1
|
||||
};
|
||||
/* Public Functions */
|
||||
extern void PIOS_Servo_SetHz(const uint16_t *update_rates, uint8_t banks);
|
||||
extern void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks);
|
||||
extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position);
|
||||
extern void PIOS_Servo_Update();
|
||||
extern void PIOS_Servo_SetBankMode(uint8_t bank, uint8_t mode);
|
||||
extern uint8_t PIOS_Servo_GetPinBank(uint8_t pin);
|
||||
|
||||
#endif /* PIOS_SERVO_H */
|
||||
|
||||
|
@ -43,13 +43,13 @@ static volatile uint16_t ServoPosition[PIOS_SERVO_NUM_TIMERS];
|
||||
*/
|
||||
void PIOS_Servo_Init(void)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Set the servo update rate (Max 500Hz)
|
||||
* \param[in] onetofour Rate for outputs 1 to 4 (Hz)
|
||||
* \param[in] fivetoeight Rate for outputs 5 to 8 (Hz)
|
||||
* \param[in] array of rates in Hz
|
||||
* \param[in] array of timer clocks in Hz
|
||||
* \param[in] maximum number of banks
|
||||
*/
|
||||
void PIOS_Servo_SetHz(const uint16_t *banks, uint8_t num_banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +209,9 @@ static void PIOS_PWM_tim_overflow_cb(__attribute__((unused)) uint32_t tim_id, ui
|
||||
/* Channel out of range */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pwm_dev->CaptureState[channel]) {
|
||||
return;
|
||||
}
|
||||
pwm_dev->us_since_update[channel] += count;
|
||||
if (pwm_dev->us_since_update[channel] >= PWM_SUPERVISOR_TIMEOUT) {
|
||||
pwm_dev->CaptureState[channel] = 0;
|
||||
@ -256,16 +258,19 @@ static void PIOS_PWM_tim_edge_cb(__attribute__((unused)) uint32_t tim_id, uint32
|
||||
TIM_ICInitStructure.TIM_Channel = chan->timer_chan;
|
||||
TIM_ICInit(chan->timer, &TIM_ICInitStructure);
|
||||
} else {
|
||||
uint32_t value = 0;
|
||||
/* Capture computation */
|
||||
if (pwm_dev->FallValue[chan_idx] > pwm_dev->RiseValue[chan_idx]) {
|
||||
pwm_dev->CaptureValue[chan_idx] = (pwm_dev->FallValue[chan_idx] - pwm_dev->RiseValue[chan_idx]);
|
||||
} else {
|
||||
pwm_dev->CaptureValue[chan_idx] = ((chan->timer->ARR - pwm_dev->RiseValue[chan_idx]) + pwm_dev->FallValue[chan_idx]);
|
||||
value = pwm_dev->us_since_update[chan_idx] + (pwm_dev->FallValue[chan_idx] - pwm_dev->RiseValue[chan_idx]);
|
||||
|
||||
// From time to time glitches happens. Most of the observed case are related to missing or spurious overflows
|
||||
// happening when they are triggered very close each other.
|
||||
// The following workaround prevents them to cause troubles by filtering unacceptable values
|
||||
if (PIOS_PWM_VALID_RANGE_MAX > value && PIOS_PWM_VALID_RANGE_MIN < value) {
|
||||
pwm_dev->CaptureValue[chan_idx] = value;
|
||||
}
|
||||
|
||||
/* Switch states */
|
||||
pwm_dev->CaptureState[chan_idx] = 0;
|
||||
|
||||
pwm_dev->CaptureState[chan_idx] = 0;
|
||||
pwm_dev->us_since_update[chan_idx] = 0;
|
||||
/* Increase supervisor counter */
|
||||
pwm_dev->CapCounter[chan_idx]++;
|
||||
|
||||
|
@ -39,6 +39,17 @@
|
||||
|
||||
static const struct pios_servo_cfg *servo_cfg;
|
||||
|
||||
// determine if the related timer will work in synchronous (or OneShot/OneShot125) One Pulse mode.
|
||||
// static uint8_t pios_servo_bank_mode[PIOS_SERVO_BANKS] = { 0 };
|
||||
|
||||
// timer associated to each bank
|
||||
static TIM_TypeDef *pios_servo_bank_timer[PIOS_SERVO_BANKS] = { 0 };
|
||||
|
||||
// index of bank used for each pin
|
||||
static uint8_t *pios_servo_pin_bank;
|
||||
|
||||
#define PIOS_SERVO_TIMER_CLOCK 1000000
|
||||
|
||||
/**
|
||||
* Initialise Servos
|
||||
*/
|
||||
@ -52,10 +63,36 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
|
||||
|
||||
/* Store away the requested configuration */
|
||||
servo_cfg = cfg;
|
||||
pios_servo_pin_bank = pios_malloc(sizeof(uint8_t) * cfg->num_channels);
|
||||
|
||||
uint8_t bank = 0;
|
||||
/* Configure the channels to be in output compare mode */
|
||||
for (uint8_t i = 0; i < cfg->num_channels; i++) {
|
||||
const struct pios_tim_channel *chan = &cfg->channels[i];
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
bool new = true;
|
||||
/* See if any previous channels use that same timer */
|
||||
for (uint8_t j = 0; (j < i) && new; j++) {
|
||||
new &= chan->timer != servo_cfg->channels[j].timer;
|
||||
}
|
||||
|
||||
if (new) {
|
||||
PIOS_Assert(bank < PIOS_SERVO_BANKS);
|
||||
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
|
||||
if (servo_cfg->channels[j].timer == chan->timer) {
|
||||
pios_servo_pin_bank[j] = bank;
|
||||
}
|
||||
}
|
||||
pios_servo_bank_timer[bank] = chan->timer;
|
||||
|
||||
PIOS_Assert(bank < PIOS_SERVO_BANKS);
|
||||
|
||||
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
|
||||
if (servo_cfg->channels[j].timer == chan->timer) {
|
||||
pios_servo_pin_bank[j] = bank;
|
||||
}
|
||||
}
|
||||
bank++;
|
||||
}
|
||||
|
||||
/* Set up for output compare function */
|
||||
switch (chan->timer_chan) {
|
||||
@ -88,10 +125,12 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
|
||||
/**
|
||||
* Set the servo update rate (Max 500Hz)
|
||||
* \param[in] array of rates in Hz
|
||||
* \param[in] array of timer clocks in Hz
|
||||
* \param[in] maximum number of banks
|
||||
*/
|
||||
void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
|
||||
{
|
||||
PIOS_Assert(banks <= PIOS_SERVO_BANKS);
|
||||
if (!servo_cfg) {
|
||||
return;
|
||||
}
|
||||
@ -99,23 +138,18 @@ void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init;
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1;
|
||||
|
||||
uint8_t set = 0;
|
||||
for (uint8_t i = 0; i < banks && i < PIOS_SERVO_BANKS; i++) {
|
||||
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
|
||||
if (timer) {
|
||||
uint32_t new_clock = PIOS_SERVO_TIMER_CLOCK;
|
||||
if (clock[i]) {
|
||||
new_clock = clock[i];
|
||||
}
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / new_clock) - 1;
|
||||
TIM_TimeBaseStructure.TIM_Period = ((new_clock / speeds[i]) - 1);
|
||||
|
||||
for (uint8_t i = 0; (i < servo_cfg->num_channels) && (set < banks); i++) {
|
||||
bool new = true;
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
|
||||
/* See if any previous channels use that same timer */
|
||||
for (uint8_t j = 0; (j < i) && new; j++) {
|
||||
new &= chan->timer != servo_cfg->channels[j].timer;
|
||||
}
|
||||
|
||||
if (new) {
|
||||
TIM_TimeBaseStructure.TIM_Period = ((1000000 / speeds[set]) - 1);
|
||||
TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure);
|
||||
set++;
|
||||
TIM_TimeBaseInit((TIM_TypeDef *)timer, &TIM_TimeBaseStructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,4 +184,27 @@ void PIOS_Servo_Set(uint8_t servo, uint16_t position)
|
||||
}
|
||||
}
|
||||
|
||||
void PIOS_Servo_Update()
|
||||
{
|
||||
/*
|
||||
for (uint8_t i = 0; (i < PIOS_SERVO_BANKS); i++) {
|
||||
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
|
||||
if (timer) {
|
||||
TIM_Cmd((TIM_TypeDef *)timer, ENABLE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void PIOS_Servo_SetBankMode(__attribute__((unused)) uint8_t bank, __attribute__((unused)) uint8_t mode) {}
|
||||
|
||||
uint8_t PIOS_Servo_GetPinBank(uint8_t pin)
|
||||
{
|
||||
if (pin < servo_cfg->num_channels) {
|
||||
return pios_servo_pin_bank[pin];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_SERVO */
|
||||
|
@ -159,6 +159,16 @@ out_fail:
|
||||
|
||||
static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer)
|
||||
{
|
||||
/* Check for an overflow event on this timer */
|
||||
bool overflow_event = 0;
|
||||
uint16_t overflow_count = false;
|
||||
|
||||
if (TIM_GetITStatus(timer, TIM_IT_Update) == SET) {
|
||||
TIM_ClearITPendingBit(timer, TIM_IT_Update);
|
||||
overflow_count = timer->ARR;
|
||||
overflow_event = true;
|
||||
}
|
||||
|
||||
/* Iterate over all registered clients of the TIM layer to find channels on this timer */
|
||||
for (uint8_t i = 0; i < pios_tim_num_devs; i++) {
|
||||
const struct pios_tim_dev *tim_dev = &pios_tim_devs[i];
|
||||
@ -168,18 +178,6 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for an overflow event on this timer */
|
||||
bool overflow_event;
|
||||
uint16_t overflow_count;
|
||||
if (TIM_GetITStatus(timer, TIM_IT_Update) == SET) {
|
||||
TIM_ClearITPendingBit(timer, TIM_IT_Update);
|
||||
overflow_count = timer->ARR;
|
||||
overflow_event = true;
|
||||
} else {
|
||||
overflow_count = 0;
|
||||
overflow_event = false;
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < tim_dev->num_channels; j++) {
|
||||
const struct pios_tim_channel *chan = &tim_dev->channels[j];
|
||||
|
||||
@ -251,11 +249,11 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer)
|
||||
* get the order wrong, our pulse width calculations could be off by up
|
||||
* to ARR ticks. That could be bad.
|
||||
*
|
||||
* Heuristic: If the edge_count is < 16 ticks above zero then we assume the
|
||||
* Heuristic: If the edge_count is < 32 ticks above zero then we assume the
|
||||
* edge happened just after the overflow.
|
||||
*/
|
||||
|
||||
if (edge_count < 16) {
|
||||
if (edge_count < 32) {
|
||||
/* Call the overflow callback first */
|
||||
if (tim_dev->callbacks->overflow) {
|
||||
(*tim_dev->callbacks->overflow)((uint32_t)tim_dev,
|
||||
@ -300,67 +298,6 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
uint16_t val = 0;
|
||||
for (uint8_t i = 0; i < pios_pwm_cfg.num_channels; i++) {
|
||||
struct pios_pwm_channel channel = pios_pwm_cfg.channels[i];
|
||||
if ((channel.timer == timer) && (TIM_GetITStatus(channel.timer, channel.ccr) == SET)) {
|
||||
TIM_ClearITPendingBit(channel.timer, channel.ccr);
|
||||
|
||||
switch (channel.channel) {
|
||||
case TIM_Channel_1:
|
||||
val = TIM_GetCapture1(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
val = TIM_GetCapture2(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
val = TIM_GetCapture3(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
val = TIM_GetCapture4(channel.timer);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CaptureState[i] == 0) {
|
||||
RiseValue[i] = val;
|
||||
} else {
|
||||
FallValue[i] = val;
|
||||
}
|
||||
|
||||
// flip state machine and capture value here
|
||||
/* Simple rise or fall state machine */
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure = pios_pwm_cfg.tim_ic_init;
|
||||
if (CaptureState[i] == 0) {
|
||||
/* Switch states */
|
||||
CaptureState[i] = 1;
|
||||
|
||||
/* Switch polarity of input capture */
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
|
||||
TIM_ICInitStructure.TIM_Channel = channel.channel;
|
||||
TIM_ICInit(channel.timer, &TIM_ICInitStructure);
|
||||
} else {
|
||||
/* Capture computation */
|
||||
if (FallValue[i] > RiseValue[i]) {
|
||||
CaptureValue[i] = (FallValue[i] - RiseValue[i]);
|
||||
} else {
|
||||
CaptureValue[i] = ((channel.timer->ARR - RiseValue[i]) + FallValue[i]);
|
||||
}
|
||||
|
||||
/* Switch states */
|
||||
CaptureState[i] = 0;
|
||||
|
||||
/* Increase supervisor counter */
|
||||
CapCounter[i]++;
|
||||
|
||||
/* Switch polarity of input capture */
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_Channel = channel.channel;
|
||||
TIM_ICInit(channel.timer, &TIM_ICInitStructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* if 0 */
|
||||
|
||||
/* Bind Interrupt Handlers
|
||||
*
|
||||
|
@ -39,6 +39,19 @@
|
||||
|
||||
static const struct pios_servo_cfg *servo_cfg;
|
||||
|
||||
// determine if the related timer will work in synchronous (or OneShot/OneShot125) One Pulse mode.
|
||||
static uint8_t pios_servo_bank_mode[PIOS_SERVO_BANKS] = { 0 };
|
||||
// used to skip updates when pulse length is higher than update cycle
|
||||
static uint16_t pios_servo_bank_next_update[PIOS_SERVO_BANKS] = { 0 };
|
||||
static uint16_t pios_servo_bank_max_pulse[PIOS_SERVO_BANKS] = { 0 };
|
||||
// timer associated to each bank
|
||||
static TIM_TypeDef *pios_servo_bank_timer[PIOS_SERVO_BANKS] = { 0 };
|
||||
|
||||
// index of bank used for each pin
|
||||
static uint8_t *pios_servo_pin_bank;
|
||||
|
||||
#define PIOS_SERVO_TIMER_CLOCK 1000000
|
||||
#define PIOS_SERVO_SAFE_MARGIN 50
|
||||
/**
|
||||
* Initialise Servos
|
||||
*/
|
||||
@ -52,46 +65,141 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
|
||||
|
||||
/* Store away the requested configuration */
|
||||
servo_cfg = cfg;
|
||||
pios_servo_pin_bank = pios_malloc(sizeof(uint8_t) * cfg->num_channels);
|
||||
|
||||
/* Configure the channels to be in output compare mode */
|
||||
for (uint8_t i = 0; i < cfg->num_channels; i++) {
|
||||
const struct pios_tim_channel *chan = &cfg->channels[i];
|
||||
uint8_t bank = 0;
|
||||
for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
bool new = true;
|
||||
/* See if any previous channels use that same timer */
|
||||
for (uint8_t j = 0; (j < i) && new; j++) {
|
||||
new &= chan->timer != servo_cfg->channels[j].timer;
|
||||
}
|
||||
|
||||
if (new) {
|
||||
PIOS_Assert(bank < PIOS_SERVO_BANKS);
|
||||
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
|
||||
if (servo_cfg->channels[j].timer == chan->timer) {
|
||||
pios_servo_pin_bank[j] = bank;
|
||||
}
|
||||
}
|
||||
pios_servo_bank_timer[bank] = chan->timer;
|
||||
|
||||
TIM_ARRPreloadConfig(chan->timer, ENABLE);
|
||||
TIM_CtrlPWMOutputs(chan->timer, ENABLE);
|
||||
TIM_Cmd(chan->timer, DISABLE);
|
||||
|
||||
bank++;
|
||||
}
|
||||
|
||||
/* Set up for output compare function */
|
||||
switch (chan->timer_chan) {
|
||||
case TIM_Channel_1:
|
||||
TIM_OC1Init(chan->timer, &cfg->tim_oc_init);
|
||||
TIM_OC1Init(chan->timer, &servo_cfg->tim_oc_init);
|
||||
TIM_OC1PreloadConfig(chan->timer, TIM_OCPreload_Enable);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
TIM_OC2Init(chan->timer, &cfg->tim_oc_init);
|
||||
TIM_OC2Init(chan->timer, &servo_cfg->tim_oc_init);
|
||||
TIM_OC2PreloadConfig(chan->timer, TIM_OCPreload_Enable);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
TIM_OC3Init(chan->timer, &cfg->tim_oc_init);
|
||||
TIM_OC3Init(chan->timer, &servo_cfg->tim_oc_init);
|
||||
TIM_OC3PreloadConfig(chan->timer, TIM_OCPreload_Enable);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
TIM_OC4Init(chan->timer, &cfg->tim_oc_init);
|
||||
TIM_OC4Init(chan->timer, &servo_cfg->tim_oc_init);
|
||||
TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable);
|
||||
break;
|
||||
}
|
||||
|
||||
TIM_ARRPreloadConfig(chan->timer, ENABLE);
|
||||
TIM_CtrlPWMOutputs(chan->timer, ENABLE);
|
||||
TIM_Cmd(chan->timer, ENABLE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PIOS_Servo_SetBankMode(uint8_t bank, uint8_t mode)
|
||||
{
|
||||
PIOS_Assert(bank < PIOS_SERVO_BANKS);
|
||||
pios_servo_bank_mode[bank] = mode;
|
||||
|
||||
if (pios_servo_bank_timer[bank]) {
|
||||
for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
|
||||
if (pios_servo_pin_bank[i] == bank) {
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
/* Set up for output compare function */
|
||||
switch (chan->timer_chan) {
|
||||
case TIM_Channel_1:
|
||||
TIM_OC1PolarityConfig(chan->timer, TIM_OCPolarity_High);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
TIM_OC2PolarityConfig(chan->timer, TIM_OCPolarity_High);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
TIM_OC3PolarityConfig(chan->timer, TIM_OCPolarity_High);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
TIM_OC4PolarityConfig(chan->timer, TIM_OCPolarity_High);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mode != PIOS_SERVO_BANK_MODE_PWM) {
|
||||
// TIM_UpdateDisableConfig(pios_servo_bank_timer[bank], ENABLE);
|
||||
} else {
|
||||
// TIM_UpdateDisableConfig(pios_servo_bank_timer[bank], DISABLE);
|
||||
}
|
||||
// Setup the timer accordingly
|
||||
TIM_SelectOnePulseMode(pios_servo_bank_timer[bank], TIM_OPMode_Repetitive);
|
||||
TIM_Cmd(pios_servo_bank_timer[bank], ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIOS_Servo_Update()
|
||||
{
|
||||
for (uint8_t i = 0; (i < PIOS_SERVO_BANKS); i++) {
|
||||
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
|
||||
if (timer && pios_servo_bank_mode[i] == PIOS_SERVO_BANK_MODE_SINGLE_PULSE) {
|
||||
// a pulse to be generated is longer than cycle period. skip this update.
|
||||
if (TIM_GetCounter((TIM_TypeDef *)timer) > (uint32_t)(pios_servo_bank_next_update[i] + PIOS_SERVO_SAFE_MARGIN)) {
|
||||
TIM_GenerateEvent((TIM_TypeDef *)timer, TIM_EventSource_Update);
|
||||
pios_servo_bank_next_update[i] = pios_servo_bank_max_pulse[i];
|
||||
}
|
||||
}
|
||||
pios_servo_bank_max_pulse[i] = 0;
|
||||
}
|
||||
for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
|
||||
uint8_t bank = pios_servo_pin_bank[i];
|
||||
uint8_t mode = pios_servo_bank_mode[bank];
|
||||
if (mode == PIOS_SERVO_BANK_MODE_SINGLE_PULSE) {
|
||||
/* Update the position */
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
|
||||
switch (chan->timer_chan) {
|
||||
case TIM_Channel_1:
|
||||
TIM_SetCompare1(chan->timer, 0);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
TIM_SetCompare2(chan->timer, 0);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
TIM_SetCompare3(chan->timer, 0);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
TIM_SetCompare4(chan->timer, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the servo update rate (Max 500Hz)
|
||||
* \param[in] array of rates in Hz
|
||||
* \param[in] array of timer clocks in Hz
|
||||
* \param[in] maximum number of banks
|
||||
*/
|
||||
void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
|
||||
{
|
||||
PIOS_Assert(banks <= PIOS_SERVO_BANKS);
|
||||
if (!servo_cfg) {
|
||||
return;
|
||||
}
|
||||
@ -99,30 +207,22 @@ void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init;
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
//
|
||||
|
||||
uint8_t set = 0;
|
||||
|
||||
for (uint8_t i = 0; (i < servo_cfg->num_channels) && (set < banks); i++) {
|
||||
bool new = true;
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
|
||||
|
||||
/* See if any previous channels use that same timer */
|
||||
for (uint8_t j = 0; (j < i) && new; j++) {
|
||||
new &= chan->timer != servo_cfg->channels[j].timer;
|
||||
}
|
||||
|
||||
if (new) {
|
||||
// Choose the correct prescaler value for the APB the timer is attached
|
||||
if (chan->timer == TIM1 || chan->timer == TIM8 || chan->timer == TIM9 || chan->timer == TIM10 || chan->timer == TIM11) {
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / 1000000) - 1;
|
||||
} else {
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / 1000000) - 1;
|
||||
for (uint8_t i = 0; i < banks && i < PIOS_SERVO_BANKS; i++) {
|
||||
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
|
||||
if (timer) {
|
||||
uint32_t new_clock = PIOS_SERVO_TIMER_CLOCK;
|
||||
if (clock[i]) {
|
||||
new_clock = clock[i];
|
||||
}
|
||||
|
||||
TIM_TimeBaseStructure.TIM_Period = ((1000000 / speeds[set]) - 1);
|
||||
TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure);
|
||||
set++;
|
||||
// Choose the correct prescaler value for the APB the timer is attached
|
||||
if (timer == TIM1 || timer == TIM8 || timer == TIM9 || timer == TIM10 || timer == TIM11) {
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / new_clock) - 1;
|
||||
} else {
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / new_clock) - 1;
|
||||
}
|
||||
TIM_TimeBaseStructure.TIM_Period = ((new_clock / speeds[i]) - 1);
|
||||
TIM_TimeBaseInit((TIM_TypeDef *)timer, &TIM_TimeBaseStructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,22 +239,42 @@ void PIOS_Servo_Set(uint8_t servo, uint16_t position)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Update the position */
|
||||
const struct pios_tim_channel *chan = &servo_cfg->channels[servo];
|
||||
uint16_t val = position;
|
||||
uint16_t margin = chan->timer->ARR / 50; // Leave 2% of period as margin to prevent overlaps
|
||||
if (val > (chan->timer->ARR - margin)) {
|
||||
val = chan->timer->ARR - margin;
|
||||
}
|
||||
|
||||
uint8_t bank = pios_servo_pin_bank[servo];
|
||||
if (pios_servo_bank_max_pulse[bank] < val) {
|
||||
pios_servo_bank_max_pulse[bank] = val;
|
||||
}
|
||||
switch (chan->timer_chan) {
|
||||
case TIM_Channel_1:
|
||||
TIM_SetCompare1(chan->timer, position);
|
||||
TIM_SetCompare1(chan->timer, val);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
TIM_SetCompare2(chan->timer, position);
|
||||
TIM_SetCompare2(chan->timer, val);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
TIM_SetCompare3(chan->timer, position);
|
||||
TIM_SetCompare3(chan->timer, val);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
TIM_SetCompare4(chan->timer, position);
|
||||
TIM_SetCompare4(chan->timer, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PIOS_Servo_GetPinBank(uint8_t pin)
|
||||
{
|
||||
if (pin < servo_cfg->num_channels) {
|
||||
return pios_servo_pin_bank[pin];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_SERVO */
|
||||
|
@ -251,6 +251,7 @@ extern uint32_t pios_com_hkosd_id;
|
||||
// -------------------------
|
||||
#define PIOS_SERVO_UPDATE_HZ 50
|
||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
|
||||
// --------------------------
|
||||
// Timer controller settings
|
||||
|
@ -747,11 +747,11 @@ void PIOS_Board_Init(void)
|
||||
}
|
||||
|
||||
/* Set the radio configuration parameters. */
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, oplinkSettings.ChannelSet, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID);
|
||||
|
||||
/* Set the PPM callback if we should be receiving PPM. */
|
||||
if (ppm_mode) {
|
||||
if (ppm_mode || (ppm_only && !is_coordinator)) {
|
||||
PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback);
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,7 @@ extern uint32_t pios_packet_handler;
|
||||
// -------------------------
|
||||
#define PIOS_SERVO_UPDATE_HZ 50
|
||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
|
||||
// --------------------------
|
||||
// Timer controller settings
|
||||
|
@ -48,6 +48,9 @@ ifndef TESTAPP
|
||||
SRC += $(OPUAVOBJ)/uavobjectpersistence.c
|
||||
SRC += $(OPUAVOBJ)/eventdispatcher.c
|
||||
|
||||
## Misc library functions
|
||||
SRC += $(FLIGHTLIB)/sha1.c
|
||||
|
||||
## UAVObjects
|
||||
SRC += $(OPUAVSYNTHDIR)/oplinkstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/oplinksettings.c
|
||||
|
@ -438,11 +438,11 @@ void PIOS_Board_Init(void)
|
||||
}
|
||||
|
||||
// Set the radio configuration parameters.
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, oplinkSettings.ChannelSet, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID);
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
|
||||
/* Set the PPM callback if we should be receiving PPM. */
|
||||
if (ppm_mode) {
|
||||
if (ppm_mode || (ppm_only && !is_coordinator)) {
|
||||
PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback);
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,7 @@ extern uint32_t pios_ppm_out_id;
|
||||
// -------------------------
|
||||
#define PIOS_SERVO_UPDATE_HZ 50
|
||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
|
||||
// --------------------------
|
||||
// Timer controller settings
|
||||
|
@ -247,6 +247,8 @@ extern uint32_t pios_com_telem_usb_id;
|
||||
// --------------------------
|
||||
#define PIOS_TIM_MAX_DEVS 6
|
||||
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
|
||||
// -------------------------
|
||||
// USB
|
||||
// -------------------------
|
||||
|
@ -91,6 +91,7 @@ ifndef TESTAPP
|
||||
SRC += $(FLIGHTLIB)/insgps13state.c
|
||||
SRC += $(FLIGHTLIB)/auxmagsupport.c
|
||||
SRC += $(FLIGHTLIB)/lednotification.c
|
||||
SRC += $(FLIGHTLIB)/sha1.c
|
||||
|
||||
## UAVObjects
|
||||
include ./UAVObjects.inc
|
||||
|
@ -770,11 +770,11 @@ void PIOS_Board_Init(void)
|
||||
}
|
||||
|
||||
/* Set the radio configuration parameters. */
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, oplinkSettings.ChannelSet, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID);
|
||||
PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, is_oneway, ppm_mode, ppm_only);
|
||||
|
||||
/* Set the PPM callback if we should be receiving PPM. */
|
||||
if (ppm_mode) {
|
||||
if (ppm_mode || (ppm_only && !is_coordinator)) {
|
||||
PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback);
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ extern uint32_t pios_packet_handler;
|
||||
// -------------------------
|
||||
#define PIOS_SERVO_UPDATE_HZ 50
|
||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
// --------------------------
|
||||
// Timer controller settings
|
||||
// --------------------------
|
||||
|
@ -225,6 +225,7 @@ extern uint32_t pios_com_hkosd_id;
|
||||
// -------------------------
|
||||
#define PIOS_SERVO_UPDATE_HZ 50
|
||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||
#define PIOS_SERVO_BANKS 6
|
||||
|
||||
// --------------------------
|
||||
// Timer controller settings
|
||||
|
@ -1551,6 +1551,17 @@
|
||||
<enableVbo>false</enableVbo>
|
||||
</data>
|
||||
</Revolution>
|
||||
<Blackout_MiniH>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
<version>0.0.0</version>
|
||||
</configInfo>
|
||||
<data>
|
||||
<acFilename>%%DATAPATH%%models/multi/blackout/BlackoutMiniHQuad.3DS</acFilename>
|
||||
<bgFilename>%%DATAPATH%%models/backgrounds/default_background.png</bgFilename>
|
||||
<enableVbo>false</enableVbo>
|
||||
</data>
|
||||
</Blackout_MiniH>
|
||||
<Zagi>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
@ -2530,7 +2541,7 @@
|
||||
<side0>
|
||||
<classId>ModelViewGadget</classId>
|
||||
<gadget>
|
||||
<activeConfiguration>Test Quad X</activeConfiguration>
|
||||
<activeConfiguration>Blackout_MiniH</activeConfiguration>
|
||||
</gadget>
|
||||
<type>uavGadget</type>
|
||||
</side0>
|
||||
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
ground/openpilotgcs/share/openpilotgcs/models/multi/blackout/TEXTURE.PNG
Executable file
BIN
ground/openpilotgcs/share/openpilotgcs/models/multi/blackout/TEXTURE.PNG
Executable file
Binary file not shown.
After Width: | Height: | Size: 949 KiB |
@ -100,40 +100,40 @@ void OPMapWidget::SetUavPic(QString UAVPic)
|
||||
}
|
||||
}
|
||||
|
||||
WayPointLine *OPMapWidget::WPLineCreate(WayPointItem *from, WayPointItem *to, QColor color)
|
||||
WayPointLine *OPMapWidget::WPLineCreate(WayPointItem *from, WayPointItem *to, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (!from | !to) {
|
||||
return NULL;
|
||||
}
|
||||
WayPointLine *ret = new WayPointLine(from, to, map, color);
|
||||
WayPointLine *ret = new WayPointLine(from, to, map, color, dashed, width);
|
||||
ret->setOpacity(overlayOpacity);
|
||||
return ret;
|
||||
}
|
||||
WayPointLine *OPMapWidget::WPLineCreate(HomeItem *from, WayPointItem *to, QColor color)
|
||||
WayPointLine *OPMapWidget::WPLineCreate(HomeItem *from, WayPointItem *to, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (!from | !to) {
|
||||
return NULL;
|
||||
}
|
||||
WayPointLine *ret = new WayPointLine(from, to, map, color);
|
||||
WayPointLine *ret = new WayPointLine(from, to, map, color, dashed, width);
|
||||
ret->setOpacity(overlayOpacity);
|
||||
return ret;
|
||||
}
|
||||
WayPointCircle *OPMapWidget::WPCircleCreate(WayPointItem *center, WayPointItem *radius, bool clockwise, QColor color)
|
||||
WayPointCircle *OPMapWidget::WPCircleCreate(WayPointItem *center, WayPointItem *radius, bool clockwise, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (!center | !radius) {
|
||||
return NULL;
|
||||
}
|
||||
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color);
|
||||
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color, dashed, width);
|
||||
ret->setOpacity(overlayOpacity);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WayPointCircle *OPMapWidget::WPCircleCreate(HomeItem *center, WayPointItem *radius, bool clockwise, QColor color)
|
||||
WayPointCircle *OPMapWidget::WPCircleCreate(HomeItem *center, WayPointItem *radius, bool clockwise, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (!center | !radius) {
|
||||
return NULL;
|
||||
}
|
||||
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color);
|
||||
WayPointCircle *ret = new WayPointCircle(center, radius, clockwise, map, color, dashed, width);
|
||||
ret->setOpacity(overlayOpacity);
|
||||
return ret;
|
||||
}
|
||||
|
@ -511,10 +511,10 @@ public:
|
||||
}
|
||||
void SetShowDiagnostics(bool const & value);
|
||||
void SetUavPic(QString UAVPic);
|
||||
WayPointLine *WPLineCreate(WayPointItem *from, WayPointItem *to, QColor color);
|
||||
WayPointLine *WPLineCreate(HomeItem *from, WayPointItem *to, QColor color);
|
||||
WayPointCircle *WPCircleCreate(WayPointItem *center, WayPointItem *radius, bool clockwise, QColor color);
|
||||
WayPointCircle *WPCircleCreate(HomeItem *center, WayPointItem *radius, bool clockwise, QColor color);
|
||||
WayPointLine *WPLineCreate(WayPointItem *from, WayPointItem *to, QColor color, bool dashed = false, int width = -1);
|
||||
WayPointLine *WPLineCreate(HomeItem *from, WayPointItem *to, QColor color, bool dashed = false, int width = -1);
|
||||
WayPointCircle *WPCircleCreate(WayPointItem *center, WayPointItem *radius, bool clockwise, QColor color, bool dashed = false, int width = -1);
|
||||
WayPointCircle *WPCircleCreate(HomeItem *center, WayPointItem *radius, bool clockwise, QColor color, bool dashed = false, int width = -1);
|
||||
void deleteAllOverlays();
|
||||
void WPSetVisibleAll(bool value);
|
||||
WayPointItem *magicWPCreate();
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include "homeitem.h"
|
||||
|
||||
namespace mapcontrol {
|
||||
WayPointCircle::WayPointCircle(WayPointItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color) : QGraphicsEllipseItem(map),
|
||||
my_center(center), my_radius(radius), my_map(map), myColor(color), myClockWise(clockwise)
|
||||
WayPointCircle::WayPointCircle(WayPointItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color, bool dashed, int width) : QGraphicsEllipseItem(map),
|
||||
my_center(center), my_radius(radius), my_map(map), myColor(color), myClockWise(clockwise), dashed(dashed), width(width)
|
||||
{
|
||||
connect(center, SIGNAL(localPositionChanged(QPointF, WayPointItem *)), this, SLOT(refreshLocations()));
|
||||
connect(radius, SIGNAL(localPositionChanged(QPointF, WayPointItem *)), this, SLOT(refreshLocations()));
|
||||
@ -40,8 +40,8 @@ WayPointCircle::WayPointCircle(WayPointItem *center, WayPointItem *radius, bool
|
||||
connect(map, SIGNAL(childSetOpacity(qreal)), this, SLOT(setOpacitySlot(qreal)));
|
||||
}
|
||||
|
||||
WayPointCircle::WayPointCircle(HomeItem *radius, WayPointItem *center, bool clockwise, MapGraphicItem *map, QColor color) : QGraphicsEllipseItem(map),
|
||||
my_center(center), my_radius(radius), my_map(map), myColor(color), myClockWise(clockwise)
|
||||
WayPointCircle::WayPointCircle(HomeItem *radius, WayPointItem *center, bool clockwise, MapGraphicItem *map, QColor color, bool dashed, int width) : QGraphicsEllipseItem(map),
|
||||
my_center(center), my_radius(radius), my_map(map), myColor(color), myClockWise(clockwise), dashed(dashed), width(width)
|
||||
{
|
||||
connect(radius, SIGNAL(homePositionChanged(internals::PointLatLng, float)), this, SLOT(refreshLocations()));
|
||||
connect(center, SIGNAL(localPositionChanged(QPointF)), this, SLOT(refreshLocations()));
|
||||
@ -67,6 +67,14 @@ void WayPointCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
|
||||
p2 = QPointF(line.p1().x(), line.p1().y() - line.length());
|
||||
QPen myPen = pen();
|
||||
myPen.setColor(myColor);
|
||||
if (width > 0) {
|
||||
myPen.setWidth(width);
|
||||
}
|
||||
if (dashed) {
|
||||
QVector<qreal> dashes;
|
||||
dashes << 4 << 8;
|
||||
myPen.setDashPattern(dashes);
|
||||
}
|
||||
qreal arrowSize = 10;
|
||||
painter->setPen(myPen);
|
||||
QBrush brush = painter->brush();
|
||||
|
@ -40,8 +40,8 @@ class WayPointCircle : public QObject, public QGraphicsEllipseItem {
|
||||
Q_OBJECT Q_INTERFACES(QGraphicsItem)
|
||||
public:
|
||||
enum { Type = UserType + 9 };
|
||||
WayPointCircle(WayPointItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color = Qt::green);
|
||||
WayPointCircle(HomeItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color = Qt::green);
|
||||
WayPointCircle(WayPointItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color = Qt::green, bool dashed = false, int width = -1);
|
||||
WayPointCircle(HomeItem *center, WayPointItem *radius, bool clockwise, MapGraphicItem *map, QColor color = Qt::green, bool dashed = false, int width = -1);
|
||||
int type() const;
|
||||
void setColor(const QColor &color)
|
||||
{
|
||||
@ -55,6 +55,8 @@ private:
|
||||
QColor myColor;
|
||||
bool myClockWise;
|
||||
QLineF line;
|
||||
bool dashed;
|
||||
int width;
|
||||
protected:
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
public slots:
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include "homeitem.h"
|
||||
|
||||
namespace mapcontrol {
|
||||
WayPointLine::WayPointLine(WayPointItem *from, WayPointItem *to, MapGraphicItem *map, QColor color) : QGraphicsLineItem(map),
|
||||
source(from), destination(to), my_map(map), myColor(color)
|
||||
WayPointLine::WayPointLine(WayPointItem *from, WayPointItem *to, MapGraphicItem *map, QColor color, bool dashed, int width) : QGraphicsLineItem(map),
|
||||
source(from), destination(to), my_map(map), myColor(color), dashed(dashed), lineWidth(width)
|
||||
{
|
||||
this->setLine(to->pos().x(), to->pos().y(), from->pos().x(), from->pos().y());
|
||||
connect(from, SIGNAL(localPositionChanged(QPointF, WayPointItem *)), this, SLOT(refreshLocations()));
|
||||
@ -47,8 +47,8 @@ WayPointLine::WayPointLine(WayPointItem *from, WayPointItem *to, MapGraphicItem
|
||||
connect(map, SIGNAL(childSetOpacity(qreal)), this, SLOT(setOpacitySlot(qreal)));
|
||||
}
|
||||
|
||||
WayPointLine::WayPointLine(HomeItem *from, WayPointItem *to, MapGraphicItem *map, QColor color) : QGraphicsLineItem(map),
|
||||
source(from), destination(to), my_map(map), myColor(color)
|
||||
WayPointLine::WayPointLine(HomeItem *from, WayPointItem *to, MapGraphicItem *map, QColor color, bool dashed, int width) : QGraphicsLineItem(map),
|
||||
source(from), destination(to), my_map(map), myColor(color), dashed(dashed), lineWidth(width)
|
||||
{
|
||||
this->setLine(to->pos().x(), to->pos().y(), from->pos().x(), from->pos().y());
|
||||
connect(from, SIGNAL(homePositionChanged(internals::PointLatLng, float)), this, SLOT(refreshLocations()));
|
||||
@ -98,12 +98,23 @@ void WayPointLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
arrowHead.clear();
|
||||
arrowHead << line().pointAt(0.5) << arrowP1 << arrowP2;
|
||||
painter->drawPolygon(arrowHead);
|
||||
if (myColor == Qt::red) {
|
||||
myPen.setWidth(3);
|
||||
} else if (myColor == Qt::yellow) {
|
||||
myPen.setWidth(2);
|
||||
} else if (myColor == Qt::green) {
|
||||
myPen.setWidth(1);
|
||||
|
||||
if (dashed) {
|
||||
QVector<qreal> dashes;
|
||||
dashes << 4 << 8;
|
||||
myPen.setDashPattern(dashes);
|
||||
}
|
||||
|
||||
if (lineWidth == -1) {
|
||||
if (myColor == Qt::red) {
|
||||
myPen.setWidth(3);
|
||||
} else if (myColor == Qt::yellow) {
|
||||
myPen.setWidth(2);
|
||||
} else if (myColor == Qt::green) {
|
||||
myPen.setWidth(1);
|
||||
}
|
||||
} else {
|
||||
myPen.setWidth(lineWidth);
|
||||
}
|
||||
painter->setPen(myPen);
|
||||
painter->drawLine(line());
|
||||
|
@ -40,8 +40,8 @@ class WayPointLine : public QObject, public QGraphicsLineItem {
|
||||
Q_OBJECT Q_INTERFACES(QGraphicsItem)
|
||||
public:
|
||||
enum { Type = UserType + 8 };
|
||||
WayPointLine(WayPointItem *from, WayPointItem *to, MapGraphicItem *map, QColor color = Qt::green);
|
||||
WayPointLine(HomeItem *from, WayPointItem *to, MapGraphicItem *map, QColor color = Qt::green);
|
||||
WayPointLine(WayPointItem *from, WayPointItem *to, MapGraphicItem *map, QColor color = Qt::green, bool dashed = false, int width = -1);
|
||||
WayPointLine(HomeItem *from, WayPointItem *to, MapGraphicItem *map, QColor color = Qt::green, bool dashed = false, int width = -1);
|
||||
int type() const;
|
||||
QPainterPath shape() const;
|
||||
void setColor(const QColor &color)
|
||||
@ -54,6 +54,8 @@ private:
|
||||
MapGraphicItem *my_map;
|
||||
QPolygonF arrowHead;
|
||||
QColor myColor;
|
||||
bool dashed;
|
||||
int lineWidth;
|
||||
protected:
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
public slots:
|
||||
|
@ -511,7 +511,7 @@ Typical value is 50% for + or X configuration on quads.</string>
|
||||
<property name="title">
|
||||
<string>Motor output channels</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7" columnstretch="1,1,0,0,1">
|
||||
<layout class="QGridLayout" name="gridLayout_7" columnstretch="1,1,0,0,1,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
@ -524,61 +524,41 @@ Typical value is 50% for + or X configuration on quads.</string>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="0" column="0" rowspan="5">
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="6" rowspan="5">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="MotorOutputLabel1_2">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox1">
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox2">
|
||||
<widget class="QComboBox" name="rcOutputChannelBox1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
<string>Select output channel for Accessory0 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
@ -587,19 +567,30 @@ font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
<string>Accessory1</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
<string>RcOutput channels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
@ -608,19 +599,204 @@ font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
<string>RC Output</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accessory0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RC Input</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox4">
|
||||
<widget class="QComboBox" name="rcOutputChannelBox3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
<string>Select output channel for Accessory2 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="rcOutputChannelBox2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Select output channel for Accessory1 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accessory2</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="toolTip">
|
||||
<string>RcOutput curve</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Curve</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="rcOutputCurveBox1">
|
||||
<property name="toolTip">
|
||||
<string>Select output curve for Accessory0 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="rcOutputCurveBox2">
|
||||
<property name="toolTip">
|
||||
<string>Select output curve for Accessory1 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QComboBox" name="rcOutputCurveBox3">
|
||||
<property name="toolTip">
|
||||
<string>Select output curve for Accessory2 RcInput</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tricopter Yaw Servo channel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="5">
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
<property name="sizeConstraint">
|
||||
@ -749,7 +925,143 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<item row="1" column="4">
|
||||
<widget class="QComboBox" name="triYawChannelBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="5">
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="MotorOutputLabel1_2">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox1">
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox2">
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox3">
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="multiMotorChannelBox4">
|
||||
<property name="toolTip">
|
||||
<string>Assign your motor output channels using the drawing above as a reference. Respect propeller rotation.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="5">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QCheckBox" name="MultirotorRevMixerCheckBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse all motors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -778,61 +1090,6 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QComboBox" name="triYawChannelBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tricopter Yaw Servo channel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QCheckBox" name="MultirotorRevMixerCheckBox">
|
||||
<property name="text">
|
||||
<string>Reverse all motors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -110,6 +110,17 @@ QStringList ConfigMultiRotorWidget::getChannelDescriptions()
|
||||
if (multi.TRIYaw > 0 && multi.TRIYaw <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) {
|
||||
channelDesc[multi.TRIYaw - 1] = QString("Tri-Yaw");
|
||||
}
|
||||
|
||||
if (multi.Accessory0 > 0 && multi.Accessory0 <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) {
|
||||
channelDesc[multi.Accessory0 - 1] = QString("Accessory0");
|
||||
}
|
||||
if (multi.Accessory1 > 0 && multi.Accessory1 <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) {
|
||||
channelDesc[multi.Accessory1 - 1] = QString("Accessory1");
|
||||
}
|
||||
if (multi.Accessory2 > 0 && multi.Accessory2 <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) {
|
||||
channelDesc[multi.Accessory2 - 1] = QString("Accessory2");
|
||||
}
|
||||
|
||||
return channelDesc;
|
||||
}
|
||||
|
||||
@ -120,6 +131,12 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
|
||||
|
||||
populateChannelComboBoxes();
|
||||
|
||||
QStringList mixerCurveList;
|
||||
mixerCurveList << "Curve1" << "Curve2";
|
||||
m_aircraft->rcOutputCurveBox1->addItems(mixerCurveList);
|
||||
m_aircraft->rcOutputCurveBox2->addItems(mixerCurveList);
|
||||
m_aircraft->rcOutputCurveBox3->addItems(mixerCurveList);
|
||||
|
||||
// Setup the Multirotor picture in the Quad settings interface
|
||||
m_aircraft->quadShape->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_aircraft->quadShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@ -151,6 +168,7 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
|
||||
|
||||
m_aircraft->multiThrottleCurve->setXAxisLabel(tr("Input"));
|
||||
m_aircraft->multiThrottleCurve->setYAxisLabel(tr("Output"));
|
||||
|
||||
updateEnableControls();
|
||||
}
|
||||
|
||||
@ -319,6 +337,12 @@ void ConfigMultiRotorWidget::registerWidgets(ConfigTaskWidget &parent)
|
||||
parent.addWidget(m_aircraft->mrYawMixLevel);
|
||||
parent.addWidget(m_aircraft->triYawChannelBox);
|
||||
parent.addWidget(m_aircraft->MultirotorRevMixerCheckBox);
|
||||
parent.addWidget(m_aircraft->rcOutputChannelBox1);
|
||||
parent.addWidget(m_aircraft->rcOutputChannelBox2);
|
||||
parent.addWidget(m_aircraft->rcOutputChannelBox3);
|
||||
parent.addWidget(m_aircraft->rcOutputCurveBox1);
|
||||
parent.addWidget(m_aircraft->rcOutputCurveBox2);
|
||||
parent.addWidget(m_aircraft->rcOutputCurveBox3);
|
||||
}
|
||||
|
||||
void ConfigMultiRotorWidget::resetActuators(GUIConfigDataUnion *configData)
|
||||
@ -342,6 +366,46 @@ void ConfigMultiRotorWidget::resetActuators(GUIConfigDataUnion *configData)
|
||||
configData->multi.VTOLMotorNNW = 0;
|
||||
}
|
||||
|
||||
void ConfigMultiRotorWidget::resetRcOutputs(GUIConfigDataUnion *configData)
|
||||
{
|
||||
configData->multi.Accessory0 = 0;
|
||||
configData->multi.Accessory1 = 0;
|
||||
configData->multi.Accessory2 = 0;
|
||||
}
|
||||
|
||||
void ConfigMultiRotorWidget::resetMixers()
|
||||
{
|
||||
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
for (int channel = 0; channel < (int)ConfigMultiRotorWidget::CHANNEL_NUMELEM; channel++) {
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigMultiRotorWidget::updateRcCurvesUsed()
|
||||
{
|
||||
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox1, VehicleConfig::MIXER_THROTTLECURVE1);
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox2, VehicleConfig::MIXER_THROTTLECURVE1);
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox3, VehicleConfig::MIXER_THROTTLECURVE1);
|
||||
|
||||
for (int channel = 0; channel < (int)ConfigMultiRotorWidget::CHANNEL_NUMELEM; channel++) {
|
||||
QString mixerType = getMixerType(mixer, channel);
|
||||
if (mixerType == "Accessory0" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) {
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox1, VehicleConfig::MIXER_THROTTLECURVE2);
|
||||
} else if (mixerType == "Accessory1" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) {
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox2, VehicleConfig::MIXER_THROTTLECURVE2);
|
||||
} else if (mixerType == "Accessory2" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) {
|
||||
setComboCurrentIndex(m_aircraft->rcOutputCurveBox3, VehicleConfig::MIXER_THROTTLECURVE2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to refresh the UI widget values
|
||||
*/
|
||||
@ -457,6 +521,12 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
|
||||
setComboCurrentIndex(m_aircraft->triYawChannelBox, multi.TRIYaw);
|
||||
}
|
||||
|
||||
setComboCurrentIndex(m_aircraft->rcOutputChannelBox1, multi.Accessory0);
|
||||
setComboCurrentIndex(m_aircraft->rcOutputChannelBox2, multi.Accessory1);
|
||||
setComboCurrentIndex(m_aircraft->rcOutputChannelBox3, multi.Accessory2);
|
||||
|
||||
updateRcCurvesUsed();
|
||||
|
||||
// Now, read mixing values stored on board and applies values on sliders.
|
||||
m_aircraft->mrPitchMixLevel->setValue(getMixerValue(mixer, "MixerValuePitch"));
|
||||
m_aircraft->mrRollMixLevel->setValue(getMixerValue(mixer, "MixerValueRoll"));
|
||||
@ -476,6 +546,13 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
// Reset all Mixers
|
||||
resetMixers();
|
||||
|
||||
QList<QString> rcOutputList;
|
||||
rcOutputList << "Accessory0" << "Accessory1" << "Accessory2";
|
||||
setupRcOutputs(rcOutputList);
|
||||
|
||||
// Curve is also common to all quads:
|
||||
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve());
|
||||
|
||||
@ -731,7 +808,6 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
|
||||
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
|
||||
}
|
||||
|
||||
return airframeType;
|
||||
}
|
||||
|
||||
@ -816,6 +892,62 @@ void ConfigMultiRotorWidget::setupQuadMotor(int channel, double pitch, double ro
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, yaw * 127);
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function: setup rc outputs. Takes a list of channel names in input.
|
||||
*/
|
||||
void ConfigMultiRotorWidget::setupRcOutputs(QList<QString> rcOutputList)
|
||||
{
|
||||
QList<QComboBox *> rcList;
|
||||
rcList << m_aircraft->rcOutputChannelBox1 << m_aircraft->rcOutputChannelBox2 << m_aircraft->rcOutputChannelBox3;
|
||||
|
||||
GUIConfigDataUnion configData = getConfigData();
|
||||
resetRcOutputs(&configData);
|
||||
|
||||
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
int curveAccessory0 = m_aircraft->rcOutputCurveBox1->currentIndex();
|
||||
int curveAccessory1 = m_aircraft->rcOutputCurveBox2->currentIndex();
|
||||
int curveAccessory2 = m_aircraft->rcOutputCurveBox3->currentIndex();
|
||||
|
||||
foreach(QString rc_output, rcOutputList) {
|
||||
int index = rcList.takeFirst()->currentIndex();
|
||||
|
||||
if (rc_output == QString("Accessory0")) {
|
||||
configData.multi.Accessory0 = index;
|
||||
if (index) {
|
||||
setMixerType(mixer, index - 1, VehicleConfig::MIXERTYPE_ACCESSORY0);
|
||||
if (curveAccessory0) {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
|
||||
} else {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
}
|
||||
}
|
||||
} else if (rc_output == QString("Accessory1")) {
|
||||
configData.multi.Accessory1 = index;
|
||||
if (index) {
|
||||
setMixerType(mixer, index - 1, VehicleConfig::MIXERTYPE_ACCESSORY1);
|
||||
if (curveAccessory1) {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
|
||||
} else {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
}
|
||||
}
|
||||
} else if (rc_output == QString("Accessory2")) {
|
||||
configData.multi.Accessory2 = index;
|
||||
if (index) {
|
||||
setMixerType(mixer, index - 1, VehicleConfig::MIXERTYPE_ACCESSORY2);
|
||||
if (curveAccessory2) {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
|
||||
} else {
|
||||
setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setConfigData(configData);
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function: setup motors. Takes a list of channel names in input.
|
||||
*/
|
||||
@ -1052,10 +1184,11 @@ bool ConfigMultiRotorWidget::throwConfigError(int numMotors)
|
||||
{
|
||||
// Initialize configuration error flag
|
||||
bool error = false;
|
||||
QString channelNames = "";
|
||||
|
||||
// Iterate through all instances of multiMotorChannelBox
|
||||
for (int i = 0; i < numMotors; i++) {
|
||||
// Fine widgets with text "multiMotorChannelBox.x", where x is an integer
|
||||
// Find widgets with his name "multiMotorChannelBox.x", where x is an integer
|
||||
QComboBox *combobox = this->findChild<QComboBox *>("multiMotorChannelBox" + QString::number(i + 1));
|
||||
if (combobox) {
|
||||
if (combobox->currentText() == "None") {
|
||||
@ -1064,9 +1197,40 @@ bool ConfigMultiRotorWidget::throwConfigError(int numMotors)
|
||||
pixmap.fill(QColor("red"));
|
||||
combobox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes
|
||||
error = true;
|
||||
} else if (channelNames.contains(combobox->currentText(), Qt::CaseInsensitive)) {
|
||||
int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize);
|
||||
QPixmap pixmap(size, size);
|
||||
pixmap.fill(QColor("orange"));
|
||||
combobox->setItemData(combobox->currentIndex(), pixmap, Qt::DecorationRole); // Set color palettes
|
||||
combobox->setToolTip(tr("Duplicate channel in motor outputs"));
|
||||
} else {
|
||||
combobox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes
|
||||
for (int index = 0; index < (int)ConfigMultiRotorWidget::CHANNEL_NUMELEM; index++) {
|
||||
combobox->setItemData(index, 0, Qt::DecorationRole); // Reset all color palettes
|
||||
combobox->setToolTip("");
|
||||
}
|
||||
}
|
||||
channelNames += (combobox->currentText() == "None") ? "" : combobox->currentText();
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through all instances of rcOutputChannelBox
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// Find widgets with his name "rcOutputChannelBox.x", where x is an integer
|
||||
QComboBox *combobox = this->findChild<QComboBox *>("rcOutputChannelBox" + QString::number(i + 1));
|
||||
if (combobox) {
|
||||
if (channelNames.contains(combobox->currentText(), Qt::CaseInsensitive)) {
|
||||
int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize);
|
||||
QPixmap pixmap(size, size);
|
||||
pixmap.fill(QColor("orange"));
|
||||
combobox->setItemData(combobox->currentIndex(), pixmap, Qt::DecorationRole); // Set color palettes
|
||||
combobox->setToolTip(tr("Channel already used"));
|
||||
} else {
|
||||
for (int index = 0; index < (int)ConfigMultiRotorWidget::CHANNEL_NUMELEM; index++) {
|
||||
combobox->setItemData(index, 0, Qt::DecorationRole); // Reset all color palettes
|
||||
combobox->setToolTip(tr("Select output channel for Accessory%1 RcInput").arg(i));
|
||||
}
|
||||
}
|
||||
channelNames += (combobox->currentText() == "None") ? "" : combobox->currentText();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,16 +65,19 @@ private:
|
||||
|
||||
virtual void registerWidgets(ConfigTaskWidget &parent);
|
||||
virtual void resetActuators(GUIConfigDataUnion *configData);
|
||||
virtual void resetRcOutputs(GUIConfigDataUnion *configData);
|
||||
|
||||
bool setupQuad(bool pLayout);
|
||||
bool setupHexa(bool pLayout);
|
||||
bool setupOcto();
|
||||
bool setupMultiRotorMixer(double mixerFactors[8][3]);
|
||||
void setupMotors(QList<QString> motorList);
|
||||
void setupRcOutputs(QList<QString> rcOutputList);
|
||||
void resetMixers();
|
||||
void setupQuadMotor(int channel, double roll, double pitch, double yaw);
|
||||
|
||||
void setYawMixLevel(int);
|
||||
|
||||
void updateRcCurvesUsed();
|
||||
void updateAirframe(QString multiRotorType);
|
||||
void setupEnabledControls(QString multiRotorType);
|
||||
|
||||
|
@ -52,7 +52,10 @@ typedef struct {
|
||||
uint VTOLMotorWNW : 4;
|
||||
uint VTOLMotorNNW : 4; // 64 bits
|
||||
uint TRIYaw : 4;
|
||||
quint32 padding : 28; // 96 bits
|
||||
uint Accessory0 : 4;
|
||||
uint Accessory1 : 4;
|
||||
uint Accessory2 : 4;
|
||||
quint32 padding : 16; // 96 bits
|
||||
quint32 padding1; // 128 bits
|
||||
} __attribute__((packed)) multiGUISettingsStruct;
|
||||
|
||||
|
@ -23,7 +23,6 @@ HEADERS += \
|
||||
configvehicletypewidget.h \
|
||||
config_cc_hw_widget.h \
|
||||
configccattitudewidget.h \
|
||||
configpipxtremewidget.h \
|
||||
configstabilizationwidget.h \
|
||||
assertions.h \
|
||||
defaultattitudewidget.h \
|
||||
@ -57,7 +56,8 @@ HEADERS += \
|
||||
calibration/sixpointcalibrationmodel.h \
|
||||
calibration/levelcalibrationmodel.h \
|
||||
calibration/gyrobiascalibrationmodel.h \
|
||||
calibration/calibrationuiutils.h
|
||||
calibration/calibrationuiutils.h \
|
||||
configoplinkwidget.h
|
||||
|
||||
SOURCES += \
|
||||
configplugin.cpp \
|
||||
@ -71,7 +71,6 @@ SOURCES += \
|
||||
config_cc_hw_widget.cpp \
|
||||
configccattitudewidget.cpp \
|
||||
configstabilizationwidget.cpp \
|
||||
configpipxtremewidget.cpp \
|
||||
defaultattitudewidget.cpp \
|
||||
defaulthwsettingswidget.cpp \
|
||||
channelform.cpp \
|
||||
@ -97,7 +96,8 @@ SOURCES += \
|
||||
calibration/thermal/thermalcalibrationmodel.cpp \
|
||||
calibration/sixpointcalibrationmodel.cpp \
|
||||
calibration/levelcalibrationmodel.cpp \
|
||||
calibration/gyrobiascalibrationmodel.cpp
|
||||
calibration/gyrobiascalibrationmodel.cpp \
|
||||
configoplinkwidget.cpp
|
||||
|
||||
FORMS += \
|
||||
airframe.ui \
|
||||
@ -118,8 +118,8 @@ FORMS += \
|
||||
outputchannelform.ui \
|
||||
revosensors.ui \
|
||||
txpid.ui \
|
||||
pipxtreme.ui \
|
||||
mixercurve.ui \
|
||||
configrevohwwidget.ui
|
||||
configrevohwwidget.ui \
|
||||
oplink.ui
|
||||
|
||||
RESOURCES += configgadget.qrc
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "configtxpidwidget.h"
|
||||
#include "configrevohwwidget.h"
|
||||
#include "config_cc_hw_widget.h"
|
||||
#include "configpipxtremewidget.h"
|
||||
#include "configoplinkwidget.h"
|
||||
#include "configrevowidget.h"
|
||||
#include "defaultattitudewidget.h"
|
||||
#include "defaulthwsettingswidget.h"
|
||||
@ -240,7 +240,7 @@ void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *)
|
||||
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
|
||||
QWidget *qwd = new ConfigPipXtremeWidget(this);
|
||||
QWidget *qwd = new ConfigOPLinkWidget(this);
|
||||
stackWidget->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
|
||||
oplinkConnected = true;
|
||||
}
|
||||
|
@ -544,22 +544,9 @@ void ConfigInputWidget::wzNext()
|
||||
// Load actuator settings back from beginning of wizard
|
||||
actuatorSettingsObj->setData(previousActuatorSettingsData);
|
||||
|
||||
// Leave setting the throttle neutral until the final Next press,
|
||||
// else the throttle scaling causes the graphical stick movement to not
|
||||
// match the tx stick
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE] =
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE] +
|
||||
((manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_THROTTLE] -
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE]) * 0.04);
|
||||
if ((abs(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE] -
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE]) < 100) ||
|
||||
(abs(manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE] -
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE]) < 100)) {
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE] =
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE] +
|
||||
(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE] -
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE]) / 2;
|
||||
}
|
||||
// Force flight mode neutral to middle and Throttle neutral at 4%
|
||||
adjustSpecialNeutrals();
|
||||
|
||||
manualSettingsObj->setData(manualSettingsData);
|
||||
// move to Arming Settings tab
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
@ -1595,7 +1582,7 @@ void ConfigInputWidget::updateCalibration()
|
||||
(reverse[i] && manualSettingsData.ChannelMax[i] > manualCommandData.Channel[i])) {
|
||||
manualSettingsData.ChannelMax[i] = manualCommandData.Channel[i];
|
||||
}
|
||||
if (i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE || i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) {
|
||||
if ((i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) || (i == ManualControlSettings::CHANNELNUMBER_THROTTLE)) {
|
||||
adjustSpecialNeutrals();
|
||||
} else {
|
||||
manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i];
|
||||
@ -1659,7 +1646,7 @@ void ConfigInputWidget::simpleCalibration(bool enable)
|
||||
restoreMdataSingle(manualCommandObj, &manualControlMdata);
|
||||
|
||||
for (unsigned int i = 0; i < ManualControlCommand::CHANNEL_NUMELEM; i++) {
|
||||
if (i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE || i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) {
|
||||
if ((i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) || (i == ManualControlSettings::CHANNELNUMBER_THROTTLE)) {
|
||||
adjustSpecialNeutrals();
|
||||
} else {
|
||||
manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i];
|
||||
@ -1680,9 +1667,9 @@ void ConfigInputWidget::adjustSpecialNeutrals()
|
||||
// FlightMode and Throttle need special neutral settings
|
||||
//
|
||||
// Force flight mode neutral to middle
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE] =
|
||||
(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE] +
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE]) / 2;
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE] =
|
||||
(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE] +
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE]) / 2;
|
||||
|
||||
// Force throttle to be near min, add 4% from total range to avoid arming issues
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE] =
|
||||
|
@ -25,7 +25,7 @@
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "configpipxtremewidget.h"
|
||||
#include "configoplinkwidget.h"
|
||||
|
||||
#include <coreplugin/generalsettings.h>
|
||||
#include <oplinksettings.h>
|
||||
@ -38,7 +38,7 @@ static const int MIN_CHANNEL_RANGE = 10;
|
||||
static const float FIRST_FREQUENCY = 430.000;
|
||||
static const float FREQUENCY_STEP = 0.040;
|
||||
|
||||
ConfigPipXtremeWidget::ConfigPipXtremeWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
{
|
||||
m_oplink = new Ui_OPLinkWidget();
|
||||
m_oplink->setupUi(this);
|
||||
@ -67,7 +67,6 @@ ConfigPipXtremeWidget::ConfigPipXtremeWidget(QWidget *parent) : ConfigTaskWidget
|
||||
addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
|
||||
addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel);
|
||||
addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel);
|
||||
addWidgetBinding("OPLinkSettings", "ChannelSet", m_oplink->ChannelSet);
|
||||
addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID);
|
||||
addWidgetBinding("OPLinkSettings", "Coordinator", m_oplink->Coordinator);
|
||||
addWidgetBinding("OPLinkSettings", "OneWay", m_oplink->OneWayLink);
|
||||
@ -83,7 +82,6 @@ ConfigPipXtremeWidget::ConfigPipXtremeWidget(QWidget *parent) : ConfigTaskWidget
|
||||
addWidgetBinding("OPLinkStatus", "RxFailure", m_oplink->RxFailure);
|
||||
addWidgetBinding("OPLinkStatus", "UAVTalkErrors", m_oplink->UAVTalkErrors);
|
||||
addWidgetBinding("OPLinkStatus", "TxDropped", m_oplink->Dropped);
|
||||
addWidgetBinding("OPLinkStatus", "TxResent", m_oplink->Resent);
|
||||
addWidgetBinding("OPLinkStatus", "TxFailure", m_oplink->TxFailure);
|
||||
addWidgetBinding("OPLinkStatus", "Resets", m_oplink->Resets);
|
||||
addWidgetBinding("OPLinkStatus", "Timeouts", m_oplink->Timeouts);
|
||||
@ -119,13 +117,13 @@ ConfigPipXtremeWidget::ConfigPipXtremeWidget(QWidget *parent) : ConfigTaskWidget
|
||||
updateEnableControls();
|
||||
}
|
||||
|
||||
ConfigPipXtremeWidget::~ConfigPipXtremeWidget()
|
||||
ConfigOPLinkWidget::~ConfigOPLinkWidget()
|
||||
{}
|
||||
|
||||
/*!
|
||||
\brief Called by updates to @OPLinkStatus
|
||||
*/
|
||||
void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
void ConfigOPLinkWidget::updateStatus(UAVObject *object)
|
||||
{
|
||||
// Request and update of the setting object if we haven't received it yet.
|
||||
if (!settingsUpdated) {
|
||||
@ -233,7 +231,7 @@ void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
/*!
|
||||
\brief Called by updates to @OPLinkSettings
|
||||
*/
|
||||
void ConfigPipXtremeWidget::updateSettings(UAVObject *object)
|
||||
void ConfigOPLinkWidget::updateSettings(UAVObject *object)
|
||||
{
|
||||
Q_UNUSED(object);
|
||||
|
||||
@ -284,20 +282,20 @@ void ConfigPipXtremeWidget::updateSettings(UAVObject *object)
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::updateEnableControls()
|
||||
void ConfigOPLinkWidget::updateEnableControls()
|
||||
{
|
||||
enableControls(true);
|
||||
ppmOnlyChanged();
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::disconnected()
|
||||
void ConfigOPLinkWidget::disconnected()
|
||||
{
|
||||
if (settingsUpdated) {
|
||||
settingsUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::bind()
|
||||
void ConfigOPLinkWidget::bind()
|
||||
{
|
||||
QPushButton *bindButton = qobject_cast<QPushButton *>(sender());
|
||||
|
||||
@ -323,7 +321,7 @@ void ConfigPipXtremeWidget::bind()
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::ppmOnlyChanged()
|
||||
void ConfigOPLinkWidget::ppmOnlyChanged()
|
||||
{
|
||||
bool is_ppm_only = m_oplink->PPMOnly->isChecked();
|
||||
|
||||
@ -332,17 +330,17 @@ void ConfigPipXtremeWidget::ppmOnlyChanged()
|
||||
m_oplink->ComSpeed->setEnabled(!is_ppm_only);
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::minChannelChanged()
|
||||
void ConfigOPLinkWidget::minChannelChanged()
|
||||
{
|
||||
channelChanged(false);
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::maxChannelChanged()
|
||||
void ConfigOPLinkWidget::maxChannelChanged()
|
||||
{
|
||||
channelChanged(true);
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::channelChanged(bool isMax)
|
||||
void ConfigOPLinkWidget::channelChanged(bool isMax)
|
||||
{
|
||||
int minChannel = m_oplink->MinimumChannel->value();
|
||||
int maxChannel = m_oplink->MaximumChannel->value();
|
@ -29,15 +29,15 @@
|
||||
|
||||
#include <oplinksettings.h>
|
||||
|
||||
#include "ui_pipxtreme.h"
|
||||
#include "ui_oplink.h"
|
||||
#include "configtaskwidget.h"
|
||||
|
||||
class ConfigPipXtremeWidget : public ConfigTaskWidget {
|
||||
class ConfigOPLinkWidget : public ConfigTaskWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ConfigPipXtremeWidget(QWidget *parent = 0);
|
||||
~ConfigPipXtremeWidget();
|
||||
ConfigOPLinkWidget(QWidget *parent = 0);
|
||||
~ConfigOPLinkWidget();
|
||||
|
||||
public slots:
|
||||
void updateStatus(UAVObject *object1);
|
@ -98,9 +98,18 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
|
||||
addWidget(ui->cb_outputRate1);
|
||||
addWidget(ui->spinningArmed);
|
||||
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode1, 0, 0, true);
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode2, 1, 0, true);
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode3, 2, 0, true);
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode4, 3, 0, true);
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode5, 4, 0, true);
|
||||
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode6, 5, 0, true);
|
||||
|
||||
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
|
||||
|
||||
populateWidgets();
|
||||
refreshWidgetsValues();
|
||||
|
||||
updateEnableControls();
|
||||
}
|
||||
|
||||
@ -240,6 +249,17 @@ void ConfigOutputWidget::sendChannelTest(int index, int value)
|
||||
actuatorCommand->setData(actuatorCommandFields);
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setColor(QWidget *widget, const QColor color)
|
||||
{
|
||||
QPalette p(palette());
|
||||
|
||||
p.setColor(QPalette::Background, color);
|
||||
p.setColor(QPalette::Base, color);
|
||||
p.setColor(QPalette::Active, QPalette::Button, color);
|
||||
p.setColor(QPalette::Inactive, QPalette::Button, color);
|
||||
widget->setAutoFillBackground(true);
|
||||
widget->setPalette(p);
|
||||
}
|
||||
|
||||
/********************************
|
||||
* Output settings
|
||||
@ -250,22 +270,33 @@ void ConfigOutputWidget::sendChannelTest(int index, int value)
|
||||
*/
|
||||
void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
{
|
||||
Q_UNUSED(obj);
|
||||
|
||||
bool dirty = isDirty();
|
||||
|
||||
ConfigTaskWidget::refreshWidgetsValues(obj);
|
||||
|
||||
// Get Actuator Settings
|
||||
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
|
||||
|
||||
Q_ASSERT(actuatorSettings);
|
||||
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
|
||||
|
||||
// Get channel descriptions
|
||||
QStringList ChannelDesc = ConfigVehicleTypeWidget::getChannelDescriptions();
|
||||
QStringList channelDesc = ConfigVehicleTypeWidget::getChannelDescriptions();
|
||||
|
||||
QList<int> channelBanks;
|
||||
QList<QColor> bankColors;
|
||||
bankColors
|
||||
<< QColor("#C6ECAE")
|
||||
<< QColor("#91E5D3")
|
||||
<< QColor("#FCEC52")
|
||||
<< QColor("#C3A8FF")
|
||||
<< QColor("#F7F7F2")
|
||||
<< QColor("#FF9F51");
|
||||
|
||||
// Initialize output forms
|
||||
QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>();
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
outputChannelForm->setName(ChannelDesc[outputChannelForm->index()]);
|
||||
outputChannelForm->setName(channelDesc[outputChannelForm->index()]);
|
||||
|
||||
// init min,max,neutral
|
||||
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
|
||||
@ -279,89 +310,78 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
// Get the SpinWhileArmed setting
|
||||
ui->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
|
||||
|
||||
// Setup output rates for all banks
|
||||
if (ui->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])) == -1) {
|
||||
ui->cb_outputRate1->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]));
|
||||
}
|
||||
if (ui->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])) == -1) {
|
||||
ui->cb_outputRate2->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]));
|
||||
}
|
||||
if (ui->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])) == -1) {
|
||||
ui->cb_outputRate3->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]));
|
||||
}
|
||||
if (ui->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])) == -1) {
|
||||
ui->cb_outputRate4->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]));
|
||||
}
|
||||
if (ui->cb_outputRate5->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[4])) == -1) {
|
||||
ui->cb_outputRate5->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[4]));
|
||||
}
|
||||
if (ui->cb_outputRate6->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[5])) == -1) {
|
||||
ui->cb_outputRate6->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[5]));
|
||||
}
|
||||
ui->cb_outputRate1->setCurrentIndex(ui->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])));
|
||||
ui->cb_outputRate2->setCurrentIndex(ui->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])));
|
||||
ui->cb_outputRate3->setCurrentIndex(ui->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])));
|
||||
ui->cb_outputRate4->setCurrentIndex(ui->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])));
|
||||
ui->cb_outputRate5->setCurrentIndex(ui->cb_outputRate5->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[4])));
|
||||
ui->cb_outputRate6->setCurrentIndex(ui->cb_outputRate6->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[5])));
|
||||
QList<QLabel *> bank;
|
||||
bank << ui->chBank1 << ui->chBank2 << ui->chBank3 << ui->chBank4 << ui->chBank5 << ui->chBank6;
|
||||
|
||||
// Reset to all disabled
|
||||
ui->chBank1->setText("-");
|
||||
ui->chBank2->setText("-");
|
||||
ui->chBank3->setText("-");
|
||||
ui->chBank4->setText("-");
|
||||
ui->chBank5->setText("-");
|
||||
ui->chBank6->setText("-");
|
||||
ui->cb_outputRate1->setEnabled(false);
|
||||
ui->cb_outputRate2->setEnabled(false);
|
||||
ui->cb_outputRate3->setEnabled(false);
|
||||
ui->cb_outputRate4->setEnabled(false);
|
||||
ui->cb_outputRate5->setEnabled(false);
|
||||
ui->cb_outputRate6->setEnabled(false);
|
||||
QList<QComboBox *> outputRateCombos;
|
||||
outputRateCombos << ui->cb_outputRate1 << ui->cb_outputRate2 << ui->cb_outputRate3 <<
|
||||
ui->cb_outputRate4 << ui->cb_outputRate5 << ui->cb_outputRate6;
|
||||
|
||||
QList<QComboBox *> outputModeCombos;
|
||||
outputModeCombos << ui->cb_outputMode1 << ui->cb_outputMode2 << ui->cb_outputMode3 <<
|
||||
ui->cb_outputMode4 << ui->cb_outputMode5 << ui->cb_outputMode6;
|
||||
|
||||
Q_ASSERT(outputModeCombos.count() == outputRateCombos.count());
|
||||
Q_ASSERT(outputRateCombos.count() == bank.count());
|
||||
|
||||
for (int i = 0; i < outputModeCombos.count(); i++) {
|
||||
// Setup output rates for all banks
|
||||
if (outputRateCombos.at(i)->findText(QString::number(actuatorSettingsData.BankUpdateFreq[i])) == -1) {
|
||||
outputRateCombos.at(i)->addItem(QString::number(actuatorSettingsData.BankUpdateFreq[i]));
|
||||
}
|
||||
outputRateCombos.at(i)->setCurrentIndex(outputRateCombos.at(i)->findText(QString::number(actuatorSettingsData.BankUpdateFreq[i])));
|
||||
|
||||
// Reset to all disabled
|
||||
bank.at(i)->setText("-");
|
||||
|
||||
outputRateCombos.at(i)->setEnabled(false);
|
||||
setColor(outputRateCombos.at(i), palette().color(QPalette::Background));
|
||||
|
||||
outputModeCombos.at(i)->setEnabled(false);
|
||||
setColor(outputModeCombos.at(i), palette().color(QPalette::Background));
|
||||
}
|
||||
|
||||
// Get connected board model
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
Q_ASSERT(pm);
|
||||
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
|
||||
Q_ASSERT(utilMngr);
|
||||
QStringList bankLabels;
|
||||
|
||||
if (utilMngr) {
|
||||
int board = utilMngr->getBoardModel();
|
||||
// Setup labels and combos for banks according to board type
|
||||
if ((board & 0xff00) == 0x0400) {
|
||||
// Coptercontrol family of boards 4 timer banks
|
||||
ui->chBank1->setText("1-3");
|
||||
ui->chBank2->setText("4");
|
||||
ui->chBank3->setText("5,7-8");
|
||||
ui->chBank4->setText("6,9-10");
|
||||
ui->cb_outputRate1->setEnabled(true);
|
||||
ui->cb_outputRate2->setEnabled(true);
|
||||
ui->cb_outputRate3->setEnabled(true);
|
||||
ui->cb_outputRate4->setEnabled(true);
|
||||
bankLabels << "1 (1-3)" << "2 (4)" << "3 (5,7-8)" << "4 (6,9-10)";
|
||||
channelBanks << 1 << 1 << 1 << 2 << 3 << 4 << 3 << 3 << 4 << 4;
|
||||
} else if ((board & 0xff00) == 0x0900) {
|
||||
// Revolution family of boards 6 timer banks
|
||||
ui->chBank1->setText("1-2");
|
||||
ui->chBank2->setText("3");
|
||||
ui->chBank3->setText("4");
|
||||
ui->chBank4->setText("5-6");
|
||||
ui->chBank5->setText("7-8");
|
||||
ui->chBank6->setText("9-10");
|
||||
ui->cb_outputRate1->setEnabled(true);
|
||||
ui->cb_outputRate2->setEnabled(true);
|
||||
ui->cb_outputRate3->setEnabled(true);
|
||||
ui->cb_outputRate4->setEnabled(true);
|
||||
ui->cb_outputRate5->setEnabled(true);
|
||||
ui->cb_outputRate6->setEnabled(true);
|
||||
bankLabels << "1 (1-2)" << "2 (3)" << "3 (4)" << "4 (5-6)" << "5 (7-8)" << "6 (9-10)";
|
||||
channelBanks << 1 << 1 << 2 << 3 << 4 << 4 << 5 << 5 << 6 << 6;
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
foreach(QString banklabel, bankLabels) {
|
||||
bank[i]->setText(banklabel);
|
||||
outputRateCombos[i]->setEnabled(true);
|
||||
setColor(outputRateCombos[i], bankColors[i]);
|
||||
outputModeCombos[i]->setEnabled(true);
|
||||
setColor(outputModeCombos[i], bankColors[i]);
|
||||
i++;
|
||||
}
|
||||
// Get Channel ranges:
|
||||
i = 0;
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
|
||||
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
|
||||
|
||||
outputChannelForm->setRange(minValue, maxValue);
|
||||
|
||||
if (channelBanks.count() > i) {
|
||||
outputChannelForm->setBank(QString("%1").arg(channelBanks.at(i)));
|
||||
outputChannelForm->setColor(bankColors[channelBanks.at(i++) - 1]);
|
||||
}
|
||||
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
|
||||
outputChannelForm->setNeutral(neutral);
|
||||
}
|
||||
@ -374,7 +394,7 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
*/
|
||||
void ConfigOutputWidget::updateObjectsFromWidgets()
|
||||
{
|
||||
emit updateObjectsFromWidgetsRequested();
|
||||
ConfigTaskWidget::updateObjectsFromWidgets();
|
||||
|
||||
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
|
||||
|
||||
@ -391,12 +411,12 @@ void ConfigOutputWidget::updateObjectsFromWidgets()
|
||||
}
|
||||
|
||||
// Set update rates
|
||||
actuatorSettingsData.ChannelUpdateFreq[0] = ui->cb_outputRate1->currentText().toUInt();
|
||||
actuatorSettingsData.ChannelUpdateFreq[1] = ui->cb_outputRate2->currentText().toUInt();
|
||||
actuatorSettingsData.ChannelUpdateFreq[2] = ui->cb_outputRate3->currentText().toUInt();
|
||||
actuatorSettingsData.ChannelUpdateFreq[3] = ui->cb_outputRate4->currentText().toUInt();
|
||||
actuatorSettingsData.ChannelUpdateFreq[4] = ui->cb_outputRate5->currentText().toUInt();
|
||||
actuatorSettingsData.ChannelUpdateFreq[5] = ui->cb_outputRate6->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[0] = ui->cb_outputRate1->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[1] = ui->cb_outputRate2->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[2] = ui->cb_outputRate3->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[3] = ui->cb_outputRate4->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[4] = ui->cb_outputRate5->currentText().toUInt();
|
||||
actuatorSettingsData.BankUpdateFreq[5] = ui->cb_outputRate6->currentText().toUInt();
|
||||
|
||||
actuatorSettingsData.MotorsSpinWhileArmed = ui->spinningArmed->isChecked() ?
|
||||
ActuatorSettings::MOTORSSPINWHILEARMED_TRUE :
|
||||
|
@ -59,6 +59,8 @@ private:
|
||||
|
||||
void assignOutputChannel(UAVDataObject *obj, QString &str);
|
||||
|
||||
void setColor(QWidget *widget, const QColor color);
|
||||
|
||||
OutputChannelForm *getOutputChannelForm(const int index) const;
|
||||
|
||||
void sendAllChannelTests();
|
||||
|
@ -94,6 +94,7 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
|
||||
case SystemSettings::AIRFRAMETYPE_HEXAX:
|
||||
case SystemSettings::AIRFRAMETYPE_HEXACOAX:
|
||||
case SystemSettings::AIRFRAMETYPE_HEXA:
|
||||
case SystemSettings::AIRFRAMETYPE_HEXAH:
|
||||
// multirotor
|
||||
channelDesc = ConfigMultiRotorWidget::getChannelDescriptions();
|
||||
break;
|
||||
|
@ -49,8 +49,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>949</width>
|
||||
<height>558</height>
|
||||
<width>812</width>
|
||||
<height>566</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
@ -312,44 +312,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="ChannelSetLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Channel Set</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QSpinBox" name="ChannelSet">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets the random sequence of channels to use for frequency hopping.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>250</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="Coordinator">
|
||||
<property name="font">
|
||||
@ -911,6 +873,374 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="CorrectedLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Corrected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QLabel" name="RXSeqLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Seq. No.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QLineEdit" name="TXRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6">
|
||||
<widget class="QLabel" name="RXRateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Rate (B/s)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<widget class="QLineEdit" name="RXSeq">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="7">
|
||||
<widget class="QLineEdit" name="RXRate">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="GoodLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Good</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="Good">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="ErrorsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Errors</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="Corrected">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="MissedPacketsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Missed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="6">
|
||||
<widget class="QLabel" name="UAVTalkErrorsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UAVTalk Errors</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="7">
|
||||
<widget class="QLineEdit" name="UAVTalkErrors">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="7">
|
||||
<widget class="QLineEdit" name="Resets">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="6">
|
||||
<widget class="QLabel" name="ResetsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Resets</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="5">
|
||||
<widget class="QLineEdit" name="Timeouts">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4">
|
||||
<widget class="QLabel" name="TimeoutsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Timeouts</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QLineEdit" name="RSSI">
|
||||
<property name="minimumSize">
|
||||
@ -1066,34 +1396,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLineEdit" name="Resent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLabel" name="TXRateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The number of packets that were unable to be transmitted</string>
|
||||
<property name="text">
|
||||
<string>TX Rate (B/s)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1141,254 +1456,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLabel" name="TXRateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TX Rate (B/s)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QLineEdit" name="TXRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QLabel" name="RXSeqLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Seq. No.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<widget class="QLineEdit" name="RXSeq">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6">
|
||||
<widget class="QLabel" name="RXRateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Rate (B/s)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="7">
|
||||
<widget class="QLineEdit" name="RXRate">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="GoodLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Good</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="Good">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="CorrectedLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Corrected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="Corrected">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="ErrorsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Errors</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="Errors">
|
||||
<property name="sizePolicy">
|
||||
@ -1420,22 +1487,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="MissedPacketsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Missed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="Missed">
|
||||
<property name="sizePolicy">
|
||||
@ -1473,107 +1524,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="DroppedLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TX Dropped</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="Dropped">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The number of packets that were unable to be transmitted</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="ResentLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TX Resent</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="TxFailureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tx Failure</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLineEdit" name="TxFailure">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4">
|
||||
<widget class="QLabel" name="FreeHeapLabel">
|
||||
<property name="font">
|
||||
@ -1609,24 +1559,8 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="6">
|
||||
<widget class="QLabel" name="UAVTalkErrorsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UAVTalk Errors</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="7">
|
||||
<widget class="QLineEdit" name="UAVTalkErrors">
|
||||
<item row="3" column="3">
|
||||
<widget class="QLineEdit" name="TxFailure">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
@ -1647,13 +1581,29 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="7">
|
||||
<widget class="QLineEdit" name="Resets">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="TxFailureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tx Failure</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="Dropped">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -1667,16 +1617,19 @@
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
<property name="toolTip">
|
||||
<string>The number of packets that were unable to be transmitted</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="6">
|
||||
<widget class="QLabel" name="ResetsLabel">
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="ResentLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
@ -1684,52 +1637,14 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Resets</string>
|
||||
<string>TX Dropped</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="5">
|
||||
<widget class="QLineEdit" name="Timeouts">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4">
|
||||
<widget class="QLabel" name="TimeoutsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Timeouts</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="RxFailureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
@ -1745,7 +1660,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="RxFailure">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
@ -122,8 +122,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>674</width>
|
||||
<height>677</height>
|
||||
<width>680</width>
|
||||
<height>672</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
@ -157,7 +157,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Output Update Speed</string>
|
||||
<string>Output configuration</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="6">
|
||||
@ -183,7 +183,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Channel:</string>
|
||||
<string>Bank(Channels):</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -282,9 +282,15 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value
|
||||
</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>50</string>
|
||||
@ -345,8 +351,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
</string>
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
@ -430,8 +438,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
</string>
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
@ -493,8 +503,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
</string>
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
@ -566,8 +578,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
</string>
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
@ -629,8 +643,10 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup "RapidESC" here: usual value is 490 Hz for multirotor airframes.
|
||||
</string>
|
||||
<string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
@ -674,6 +690,190 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mode:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="cb_outputMode1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.
|
||||
Several other ESCs like BLHeli 13+ can use the more advanced OneShot125.
|
||||
When using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QComboBox" name="cb_outputMode2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QComboBox" name="cb_outputMode3">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QComboBox" name="cb_outputMode4">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QComboBox" name="cb_outputMode5">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QComboBox" name="cb_outputMode6">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -33,8 +33,8 @@ OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) :
|
||||
ui.setupUi(this);
|
||||
|
||||
// The convention for OP is Channel 1 to Channel 10.
|
||||
ui.actuatorNumber->setText(QString("%1:").arg(index + 1));
|
||||
|
||||
ui.actuatorNumber->setText(QString("%1").arg(index + 1));
|
||||
setBank("-");
|
||||
// Register for ActuatorSettings changes:
|
||||
connect(ui.actuatorMin, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
|
||||
connect(ui.actuatorMax, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
|
||||
@ -58,6 +58,11 @@ QString OutputChannelForm::name()
|
||||
return ui.actuatorName->text();
|
||||
}
|
||||
|
||||
QString OutputChannelForm::bank()
|
||||
{
|
||||
return ui.actuatorBankNumber->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel assignment label.
|
||||
*/
|
||||
@ -66,6 +71,25 @@ void OutputChannelForm::setName(const QString &name)
|
||||
ui.actuatorName->setText(name);
|
||||
}
|
||||
|
||||
void OutputChannelForm::setColor(const QColor &color)
|
||||
{
|
||||
QString stylesheet = ui.actuatorNumberFrame->styleSheet();
|
||||
|
||||
stylesheet = stylesheet.split("background-color").first();
|
||||
stylesheet.append(
|
||||
QString("background-color: rgb(%1, %2, %3)")
|
||||
.arg(color.red()).arg(color.green()).arg(color.blue()));
|
||||
ui.actuatorNumberFrame->setStyleSheet(stylesheet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel bank label.
|
||||
*/
|
||||
void OutputChannelForm::setBank(const QString &bank)
|
||||
{
|
||||
ui.actuatorBankNumber->setText(bank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict UI to protect users from accidental misuse.
|
||||
*/
|
||||
|
@ -43,8 +43,12 @@ public:
|
||||
friend class ConfigOutputWidget;
|
||||
|
||||
virtual QString name();
|
||||
virtual void setName(const QString &name);
|
||||
virtual QString bank();
|
||||
|
||||
virtual void setName(const QString &name);
|
||||
virtual void setBank(const QString &bank);
|
||||
|
||||
virtual void setColor(const QColor &color);
|
||||
public slots:
|
||||
int min() const;
|
||||
void setMin(int minimum);
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>768</width>
|
||||
<height>51</height>
|
||||
<height>54</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -29,7 +29,7 @@
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="legend0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -72,7 +72,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="legend1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -115,7 +115,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="legend2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -152,7 +152,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<item row="0" column="6">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -168,7 +168,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="legend6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -207,7 +207,7 @@ font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
<string> # - Bank</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
@ -217,7 +217,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -233,7 +233,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<item row="1" column="6">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -249,7 +249,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -265,7 +265,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="actuatorMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@ -289,7 +289,8 @@ margin:1px;</string>
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Minimum PWM value, beware of not overdriving your servo.</string>
|
||||
<string>Minimum PWM value, beware of not overdriving your servo.
|
||||
Using OneShot125 a value of 1000(uS) here will produce a pulse of 125(uS).</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -302,38 +303,151 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="actuatorNumber">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QFrame" name="actuatorNumberFrame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
<width>100</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel Number</string>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-radius: 5; margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0:</string>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="actuatorNumber">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel Number</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-radius: 5;\nfont: bold 12px;\nmargin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-radius: 5;\nfont: 12px;\nmargin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="actuatorBankNumber">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Bank number</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-radius: 5;\nfont: 12px;\nmargin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> 0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="legend3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -376,7 +490,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="legend4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -419,7 +533,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<item row="0" column="9">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -462,7 +576,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="actuatorName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
@ -490,7 +604,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<item row="1" column="7">
|
||||
<widget class="QSpinBox" name="actuatorMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@ -514,7 +628,8 @@ margin:1px;</string>
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Maximum PWM value, beware of not overdriving your servo.</string>
|
||||
<string>Maximum value, beware of not overdriving your servo.
|
||||
Using OneShot125 a value of 2000(uS) here will produce a pulse of 250(uS).</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -524,8 +639,8 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QFrame" name="frame">
|
||||
<item row="1" column="5">
|
||||
<widget class="QFrame" name="barFrame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@ -607,7 +722,7 @@ margin:1px;</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<item row="1" column="8">
|
||||
<widget class="QFrame" name="frame_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
@ -665,7 +780,7 @@ margin:1px;</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<item row="1" column="9">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
|
@ -33,9 +33,6 @@
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#include "../hidapi/hidapi.h"
|
||||
#include "ophid_const.h"
|
||||
#include "ophid_global.h"
|
||||
|
@ -38,38 +38,20 @@ macx {
|
||||
-framework IOKit
|
||||
}
|
||||
|
||||
linux-g++ {
|
||||
linux {
|
||||
SOURCES += src/ophid_usbmon_linux.cpp
|
||||
LIBS += -lusb -ludev
|
||||
LIBS += -ludev -lrt -lpthread
|
||||
|
||||
# hidapi library
|
||||
## rawhid
|
||||
# SOURCES += hidapi/linux/hid.c
|
||||
## libusb
|
||||
SOURCES += hidapi/libusb/hid.c
|
||||
LIBS += `pkg-config libusb-1.0 --libs` -lrt -lpthread
|
||||
INCLUDEPATH += /usr/include/libusb-1.0
|
||||
# INCLUDEPATH += `pkg-config libusb-1.0 --cflags`
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += libusb-1.0
|
||||
|
||||
!exists(/usr/include/libusb-1.0) {
|
||||
error(Install libusb-1.0.0-dev using your package manager.)
|
||||
error(Install libusb-1.0-0-dev using your package manager.)
|
||||
}
|
||||
}
|
||||
|
||||
linux-g++-64 {
|
||||
SOURCES += src/ophid_usbmon_linux.cpp
|
||||
LIBS += -lusb -ludev
|
||||
|
||||
# hidapi library
|
||||
## rawhid
|
||||
# SOURCES += hidapi/linux/hid.c
|
||||
## libusb
|
||||
SOURCES += hidapi/libusb/hid.c
|
||||
LIBS += `pkg-config libusb-1.0 --libs` -lrt -lpthread
|
||||
INCLUDEPATH += /usr/include/libusb-1.0
|
||||
# INCLUDEPATH += `pkg-config libusb-1.0 --cflags`
|
||||
!exists(/usr/include/libusb-1.0) {
|
||||
error(Install libusb-1.0.0-dev using your package manager.)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,39 +103,39 @@ modelMapProxy::overlayType modelMapProxy::overlayTranslate(int type)
|
||||
}
|
||||
}
|
||||
|
||||
void modelMapProxy::createOverlay(WayPointItem *from, WayPointItem *to, modelMapProxy::overlayType type, QColor color)
|
||||
void modelMapProxy::createOverlay(WayPointItem *from, WayPointItem *to, modelMapProxy::overlayType type, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (from == NULL || to == NULL || from == to) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case OVERLAY_LINE:
|
||||
myMap->WPLineCreate(from, to, color);
|
||||
myMap->WPLineCreate(from, to, color, dashed, width);
|
||||
break;
|
||||
case OVERLAY_CIRCLE_RIGHT:
|
||||
myMap->WPCircleCreate(to, from, true, color);
|
||||
myMap->WPCircleCreate(to, from, true, color, dashed, width);
|
||||
break;
|
||||
case OVERLAY_CIRCLE_LEFT:
|
||||
myMap->WPCircleCreate(to, from, false, color);
|
||||
myMap->WPCircleCreate(to, from, false, color, dashed, width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void modelMapProxy::createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color)
|
||||
void modelMapProxy::createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color, bool dashed, int width)
|
||||
{
|
||||
if (from == NULL || to == NULL) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case OVERLAY_LINE:
|
||||
myMap->WPLineCreate(to, from, color);
|
||||
myMap->WPLineCreate(to, from, color, dashed, width);
|
||||
break;
|
||||
case OVERLAY_CIRCLE_RIGHT:
|
||||
myMap->WPCircleCreate(to, from, true, color);
|
||||
myMap->WPCircleCreate(to, from, true, color, dashed, width);
|
||||
break;
|
||||
case OVERLAY_CIRCLE_LEFT:
|
||||
myMap->WPCircleCreate(to, from, false, color);
|
||||
myMap->WPCircleCreate(to, from, false, color, dashed, width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -164,7 +164,7 @@ void modelMapProxy::refreshOverlays()
|
||||
wp_next_overlay = overlayTranslate(model->data(model->index(x + 1, flightDataModel::MODE)).toInt());
|
||||
wp_jump_overlay = overlayTranslate(model->data(model->index(wp_jump, flightDataModel::MODE)).toInt());
|
||||
wp_error_overlay = overlayTranslate(model->data(model->index(wp_error, flightDataModel::MODE)).toInt());
|
||||
createOverlay(wp_current, findWayPointNumber(wp_error), wp_error_overlay, Qt::red);
|
||||
createOverlay(wp_current, findWayPointNumber(wp_error), wp_error_overlay, Qt::red, true, 1);
|
||||
switch (model->data(model->index(x, flightDataModel::COMMAND)).toInt()) {
|
||||
case MapDataDelegate::COMMAND_ONCONDITIONNEXTWAYPOINT:
|
||||
wp_next = findWayPointNumber(x + 1);
|
||||
|
@ -56,8 +56,8 @@ private slots:
|
||||
void selectedWPChanged(QList<WayPointItem *>);
|
||||
private:
|
||||
overlayType overlayTranslate(int type);
|
||||
void createOverlay(WayPointItem *from, WayPointItem *to, overlayType type, QColor color);
|
||||
void createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color);
|
||||
void createOverlay(WayPointItem *from, WayPointItem *to, overlayType type, QColor color, bool dashed = false, int width = -1);
|
||||
void createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color, bool dashed = false, int width = -1);
|
||||
OPMapWidget *myMap;
|
||||
flightDataModel *model;
|
||||
void refreshOverlays();
|
||||
|
@ -404,32 +404,32 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
|
||||
|
||||
data.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
|
||||
|
||||
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) {
|
||||
data.ChannelUpdateFreq[i] = LEGACY_ESC_FREQUENCY;
|
||||
for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
|
||||
data.BankUpdateFreq[i] = LEGACY_ESC_FREQUENCY;
|
||||
}
|
||||
|
||||
switch (m_configSource->getVehicleSubType()) {
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y:
|
||||
// Servo always on channel 4
|
||||
data.ChannelUpdateFreq[0] = escFrequence;
|
||||
data.BankUpdateFreq[0] = escFrequence;
|
||||
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC ||
|
||||
m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC3D) {
|
||||
data.ChannelUpdateFreq[1] = servoFrequence;
|
||||
data.BankUpdateFreq[1] = servoFrequence;
|
||||
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
|
||||
data.ChannelUpdateFreq[1] = escFrequence;
|
||||
data.ChannelUpdateFreq[2] = servoFrequence;
|
||||
data.BankUpdateFreq[1] = escFrequence;
|
||||
data.BankUpdateFreq[2] = servoFrequence;
|
||||
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
|
||||
data.ChannelUpdateFreq[1] = escFrequence;
|
||||
data.ChannelUpdateFreq[2] = escFrequence;
|
||||
data.ChannelUpdateFreq[3] = servoFrequence;
|
||||
data.BankUpdateFreq[1] = escFrequence;
|
||||
data.BankUpdateFreq[2] = escFrequence;
|
||||
data.BankUpdateFreq[3] = servoFrequence;
|
||||
}
|
||||
break;
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
|
||||
data.ChannelUpdateFreq[0] = escFrequence;
|
||||
data.ChannelUpdateFreq[1] = escFrequence;
|
||||
data.BankUpdateFreq[0] = escFrequence;
|
||||
data.BankUpdateFreq[1] = escFrequence;
|
||||
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
|
||||
data.ChannelUpdateFreq[2] = escFrequence;
|
||||
data.BankUpdateFreq[2] = escFrequence;
|
||||
}
|
||||
break;
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
|
||||
@ -441,10 +441,10 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
|
||||
data.ChannelUpdateFreq[0] = escFrequence;
|
||||
data.ChannelUpdateFreq[1] = escFrequence;
|
||||
data.ChannelUpdateFreq[2] = escFrequence;
|
||||
data.ChannelUpdateFreq[3] = escFrequence;
|
||||
data.BankUpdateFreq[0] = escFrequence;
|
||||
data.BankUpdateFreq[1] = escFrequence;
|
||||
data.BankUpdateFreq[2] = escFrequence;
|
||||
data.BankUpdateFreq[3] = escFrequence;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -467,15 +467,15 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
|
||||
data.ChannelMax[i] = actuatorSettings[i].channelMax;
|
||||
}
|
||||
|
||||
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) {
|
||||
data.ChannelUpdateFreq[i] = servoFrequence;
|
||||
for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
|
||||
data.BankUpdateFreq[i] = servoFrequence;
|
||||
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
|
||||
if (i == 1) {
|
||||
data.ChannelUpdateFreq[i] = escFrequence;
|
||||
data.BankUpdateFreq[i] = escFrequence;
|
||||
}
|
||||
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
|
||||
if (i == 2) {
|
||||
data.ChannelUpdateFreq[i] = escFrequence;
|
||||
data.BankUpdateFreq[i] = escFrequence;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -503,15 +503,15 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
|
||||
data.ChannelMax[i] = actuatorSettings[i].channelMax;
|
||||
}
|
||||
|
||||
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) {
|
||||
data.ChannelUpdateFreq[i] = servoFrequence;
|
||||
for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
|
||||
data.BankUpdateFreq[i] = servoFrequence;
|
||||
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
|
||||
if (i == 1) {
|
||||
data.ChannelUpdateFreq[i] = escFrequence;
|
||||
data.BankUpdateFreq[i] = escFrequence;
|
||||
}
|
||||
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
|
||||
if (i == 2) {
|
||||
data.ChannelUpdateFreq[i] = escFrequence;
|
||||
data.BankUpdateFreq[i] = escFrequence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,41 @@ DEB_PACKAGE_NAME := openpilot_$(DEB_VER)_$(DEB_ARCH)
|
||||
package:
|
||||
$(V1) echo "Building Linux package, please wait..."
|
||||
$(V1) cp -rL $(DEB_DIR) $(DEB_BUILD_DIR)
|
||||
$(V1)sed -i -e "$(SED_SCRIPT)" $(DEB_BUILD_DIR)/changelog
|
||||
$(V1) cd .. && dpkg-buildpackage -b -us -uc
|
||||
$(V1) sed -i -e "$(SED_SCRIPT)" $(DEB_BUILD_DIR)/changelog
|
||||
$(V1) dpkg-buildpackage -b -us -uc
|
||||
$(V1) mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).deb $(BUILD_DIR)/$(DEB_PACKAGE_NAME).deb
|
||||
$(V1) mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).changes $(BUILD_DIR)/$(DEB_PACKAGE_NAME).changes
|
||||
$(V1) rm -rf $(DEB_BUILD_DIR)
|
||||
|
||||
##############################
|
||||
#
|
||||
# Install OpenPilot
|
||||
#
|
||||
##############################
|
||||
prefix := /usr/local
|
||||
bindir := $(prefix)/bin
|
||||
libdir := $(prefix)/lib
|
||||
datadir := $(prefix)/share
|
||||
|
||||
INSTALL = cp -a --no-preserve=ownership
|
||||
LN = ln
|
||||
LN_S = ln -s
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
@$(ECHO) " INSTALLING GCS TO $(DESTDIR)/)"
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(bindir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(libdir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/applications
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/pixmaps
|
||||
$(V1) $(MKDIR) -p $(DESTDIR)$(udevdir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/bin/openpilotgcs $(DESTDIR)$(bindir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/bin/udp_test $(DESTDIR)$(bindir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/lib/openpilotgcs $(DESTDIR)$(libdir)
|
||||
$(V1) $(INSTALL) $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/share/openpilotgcs $(DESTDIR)$(datadir)
|
||||
$(V1) $(INSTALL) $(ROOT_DIR)/package/linux/openpilot.desktop $(DESTDIR)$(datadir)/applications
|
||||
$(V1) $(INSTALL) $(ROOT_DIR)/package/linux/openpilot.png $(DESTDIR)$(datadir)/pixmaps
|
||||
$(V1) rm $(DESTDIR)/$(datadir)/openpilotgcs/translations/Makefile
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ export DH_OPTIONS
|
||||
|
||||
# Disabled because OpenPilot makefile cleans and builds.
|
||||
override_dh_auto_clean:
|
||||
#$(MAKE) all_clean
|
||||
#
|
||||
|
||||
override_dh_auto_build:
|
||||
#dh_auto_build -- all
|
||||
|
@ -1,7 +1,15 @@
|
||||
<xml>
|
||||
<object name="ActuatorSettings" singleinstance="true" settings="true" category="Control">
|
||||
<description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description>
|
||||
<field name="ChannelUpdateFreq" units="Hz" type="uint16" elements="6" defaultvalue="50"/>
|
||||
<field name="BankUpdateFreq" units="Hz" type="uint16" elements="6" defaultvalue="50"/>
|
||||
<field name="BankMode" type="enum" units="" elements="6" options="PWM,OneShot,OneShot125" defaultvalue="PWM"
|
||||
limits="%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
|
||||
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
|
||||
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
|
||||
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
|
||||
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
|
||||
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125;"
|
||||
/>
|
||||
<field name="ChannelMax" units="us" type="int16" elements="12" defaultvalue="1000"/>
|
||||
<field name="ChannelNeutral" units="us" type="int16" elements="12" defaultvalue="1000"/>
|
||||
<field name="ChannelMin" units="us" type="int16" elements="12" defaultvalue="1000"/>
|
||||
|
@ -3,8 +3,8 @@
|
||||
<description>A receiver channel group carried over the OPLink radio.</description>
|
||||
<field name="Channel" units="us" type="int16" elements="8"/>
|
||||
<access gcs="readonly" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -13,7 +13,6 @@
|
||||
<field name="MaxRFPower" units="mW" type="enum" elements="1" options="0,1.25,1.6,3.16,6.3,12.6,25,50,100" defaultvalue="0"/>
|
||||
<field name="MinChannel" units="" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="MaxChannel" units="" type="uint8" elements="1" defaultvalue="250"/>
|
||||
<field name="ChannelSet" units="" type="uint8" elements="1" defaultvalue="39"/>
|
||||
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
|
@ -13,7 +13,6 @@
|
||||
<field name="RxMissed" units="%" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="RxFailure" units="%" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="UAVTalkErrors" units="" type="uint16" elements="1" defaultvalue="0"/>
|
||||
<field name="TxResent" units="%" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="TxDropped" units="%" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="TxFailure" units="%" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="Resets" units="" type="uint8" elements="1" defaultvalue="0"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user